signal学习代码实例(sigaction/signalfd)
//参考了一些blog:
//1、http://cpp.ezbty.org/import_doc/linux_manpage/signalfd4.2.html
//2、http://www.cnblogs.com/wblyuyang/archive/2012/11/13/2768923.html
//3、http://www.cnblogs.com/hoys/archive/2012/08/19/2646377.html
</pre><pre name="code" class="cpp">#include <sys/signalfd.h>//signalfd;
#include <signal.h>//sigemptyset
#include <unistd.h>//exit;read;
#include <stdlib.h>//
#include <stdio.h>
inline void handle_error(const char *msg)
{
perror(msg);
exit(EXIT_FAILURE);
}
void test_singal_pause();
void test_signalfd();
void test_signal_block();
void test_signalfd()
{
sigset_t mask;
int sfd;
struct signalfd_siginfo fdsi;
ssize_t s;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
/* 阻塞信号以使得它们不被默认的处理试方式处理 */
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1)
handle_error("sigprocmask");
//signalfd应该会取消block;否则的话,信号是无法捕获的.
sfd = signalfd(-1, &mask, 0);
if (sfd == -1)
handle_error("signalfd");
//这里是位了测试,如果延迟了,任然会记录下来,不会丢失.但是,同一个信号,最多保存一次.
sleep(3);
printf("Sleep over\n");
for (;;) {
s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo));
if (s != sizeof(struct signalfd_siginfo))
handle_error("read");
if (fdsi.ssi_signo == SIGINT) {
printf("Got SIGINT\n");
} else if (fdsi.ssi_signo == SIGQUIT) {
printf("Got SIGQUIT\n");
exit(EXIT_SUCCESS);
} else {
printf("Read unexpected signal\n");
}
}
}
//------------------------------------------------------------------------------------
void singal_process(int sig)
{
switch(sig)
{
case SIGINT:
{
printf("sig=SIGINT\n");
break;
}
case SIGQUIT:
{
printf("sig=SIGQUIT\n");
break;
}
case SIGTSTP:
{
printf("sig=SIGTSTP\n");
break;
}
default :
{
printf("Unknow signal:%d!\n",sig);
}
}
}
void test_signal_block()
{
//1-set signal;
sigset_t mask;
sigset_t oldmask;
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
sigaddset(&mask, SIGQUIT);
sigaddset(&mask, SIGTSTP);
//2-block the signal;
if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1)
{
handle_error("sigprocmask");
}
//
struct sigaction act, oldact;
act.sa_handler = singal_process;
//这里是mask set似乎没什么用;act顾名思义,是用来设置动作的(即指针函数).
//sigaddset(&act.sa_mask, SIGQUIT);
//sigaddset(&act.sa_mask, SIGINT);
//sigaddset(&act.sa_mask, SIGTSTP);
//act.sa_flags = SA_RESETHAND | SA_NODEFER;
act.sa_flags = 0;
//这里才是真正的信号注册;
sigaction(SIGINT, &act, &oldact);
sigaction(SIGQUIT, &act, &oldact);
sigaction(SIGTSTP, &act, &oldact);
printf("1-sleep\n");
sleep(3);
if (sigprocmask(SIG_SETMASK, &oldmask,NULL) == -1)
{
handle_error("sigprocmask");
}
//sigsuspend这个函数,主要替换pause+信号的效果.
printf("2-sleep\n");
sleep(3);
}
//------------------------------------------------------------------------------------
void test_singal_pause()
{
sigset_t newset;
sigset_t old;
struct sigaction act;
act.sa_handler = singal_process; //信号处理函数handler
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0); //准备捕捉SIGINT信号
sigemptyset(&newset);
sigaddset(&newset, SIGINT);
sigprocmask(SIG_BLOCK, &newset, &old); //将SIGINT信号阻塞,同时保存当前信号集
printf("Blocked");
sigprocmask(SIG_SETMASK, &old, NULL); //取消阻塞:注意,一定要取消block,否则会捕获不到信号.
pause();
}
int main()
{
//test_singal_pause();
test_signalfd();
//test_signal_block();
return 0;
}
————————————————
原文链接:https://blog.csdn.net/cainiaohhf/article/details/47341677