linux中信号的处理,linux中关于信号处理笔记(二)

2 等待一个全局变量被设置

这种情况是等待一个信号处理程序设置一个全局变量。下面的例子用于捕捉中断信号和退出信号,但是希望仅当退出信号处理程序时,才唤醒主进程。

#include

#include

#include

volatile sig_atomic_t quitflag;

/*

当把声明为该类型会保证该变量在使用或赋值时, 无论是在32位还是64位的机器上都能保证操作是原子的, 它会根据机器的类型自动适应。这个类型是定义在signal.h文件中。*/

static void sig_int(int signo)

{

if(signo == SIGINT)

printf("\ninterrupt\n");

else if(signo == SIGQUIT)

quitflag = 1;//等待这个全局变量

}

int main(void)

{

sigset_t newmask, oldmask, zeromask;

if(signal(SIGINT, sig_int) == SIG_ERR)

{

printf("signal(SIGINT) error");

exit(1);

}

if(signal(SIGQUIT, sig_int) == SIG_ERR)

{

printf("signal(SIGQUIT) error");

exit(1);

}

sigemptyset(&zeromask);

sigemptyset(&newmask);

sigaddset(&newmask, SIGQUIT);

if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)//屏蔽SIGQUIT信号

{

printf("SIG_BLOCK error");

exit(1);

}

while(quitflag == 0)

{

sigsuspend(&zeromask);//sigsuspend解开所有屏蔽信号,然后等待quitflag变成1,然后才往下执行,否则在这里循环

printf("quitflag = %d\n", quitflag);

}

quitflag = 0;

if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)

{

printf("SIG_SETMASK error");

exit(1);

}

exit(0);

}

78719c97b7eecc56b8b70aae20fd5560.png

由显示结果可以看出,sigsuspend放开屏蔽信号,按下“ctrl+C”,进入中断,但是不设置quitflag,直到按下“ctrl+\”,quitflag置1,才往下执行。

在单进程程序当中,主进程和中断共享变量,这不失为一种好办法。

3 父子进程通信,关于这个只有几个函数。在此不做记录。

另外重点说下sigaction函数:

int sigaction(int signo, const struct sigaction *restrict act, struct *restrictoact);

这个函数用来修改或者检查与指定信号相关联的处理动作,其中,参数signo是要检测或者修改其具体动作的信号编号,若act指针非空,

则要修改其动作,若oact非空,则系统由oact指针返回该信号的上一个动作。其中的结构体如下:

struct sigaction{

void (*sa_handler)(int);

sigset_t sa_mask;

int sa_flag;

void (*sa_sigaction)(int, siginfo_t *, void *);

};

关于这个函数可以这样理解:如果sa_handler字段有效,即这个字段是一个有效信号捕捉地址,则sa_mask字段信号集是这样的

在调用该捕捉函数前,这一信号集要加到进程的信号屏蔽字中,仅当从信号捕捉函数返回时再将进程的信号屏蔽字恢复到原来状态

这样,在信号处理函数调用时,就能阻塞某些信号,即在执行信号处理程序时,系统新建立的信号能被屏蔽,保证了在信号处理过程当中,

如果同一种信号再次发生,那么它会被阻塞到前一个新红处理完毕。例如:

int main(void)

{

int i = 0;

structsigactionact, oldact;

act.sa_handler = show_handler;

...

sigaddset(&act.sa_mask, SIGQUIT);

....

sigaction(SIGINT, &act, &oldact);

while(1) {

sleep(1);

printf("sleeping %d\n", i);

i++;

}}

上面函数设置SIGINT捕捉函数,在从SIGINT信号处理函数返回以前,把SIGQUIT信号屏蔽,从信号处理函数返回以后,恢复原来的信号屏蔽字。

这样即使在信号处理过程当中产生SIGQUIT信号,在接触屏蔽以后,信号SIGQUIT也能递达而不丢失。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值