距离学习信号过了挺久,有点忘了,这个函数的功能,就打算搜一搜,没想到现在网络上的文章都是抄的,而且抄的还不全哎。。。。。。。。。
ok,我来解释一下。
文章参考李慧芹老师的视频,倘若没看懂,请直接去看李慧芹老师的视频。
解释这个函数,首先参考一个函数,pause() 函数。
pause()函数:man手册解释 wait for signal。
sigsuspend()函数:man手册解释 wait for a signal。
功能是不是一样的。
接下来看不一样的。
pause函数。会挂起当前的进程,使当前进程休眠。直到一个信号(这个信号是任意的信号)的来临。解除休眠。倘若该信号设置了处理函数,就执行信号处理函数。
假设一段代码情况(该假设,SIGINT 信号设置处理函数,不再是结束当前进程。)
将SIGINT 信号处理函数设置为 打印 "0/n"
(假设 橙色的代码将循环5次)
将SIGINT 设置为阻塞
系统调用,write(1, " * ", 1),向标准输出打印 *
将SIGINT 设置为非阻塞
pause();
系统调用,write(1, " * ", 1),向标准输出打印 *
倘若在SIGINT 被阻塞时,发送一个SIGINT 信号。 那个该信号什么时候执行?
在解除阻塞和pause() 之间执行。即
*** (发送一个SIGINT 信号)** 0
(换行) 程序挂起(pause() 使程序休眠)
为什么 SIGINT 在解除阻塞和pause() 之间执行 ,因为,这两步操作不原子。
解释了半天,说一下该代码段的期望结果是什么,即,阻塞解除后,执行pause()函数,然后SIGINT 信号刚好能够唤醒被pause 的进程。即 sigsuspend函数的功能。
这个功能很重要,函数就是因为实现的功能不一样,才不一样嘛。
看下面代码段和上边的代码段的区别
将SIGINT 信号处理函数设置为 打印 "0/n"
(假设 橙色的代码将循环5次)
将SIGINT 设置为阻塞
系统调用,write(1, " * ", 1),向标准输出打印 *
sigsuspend(信号集(解除SIGINT阻塞));
假设执行结果
***(SIGINT)**(pause)(信号来临,解除休眠)0
这个执行过程是看不出来 pause 的。
看函数原型
int sigsuspend(const sigset_t *mask);
将当前的信号集设置为mask,然后挂起休眠,等待一个信号的到来。当信号到来时,解除休眠。倘若该信号设置了处理函数,就执行信号处理函数。
该mask 的设置是临时的,当信号唤醒当前进程或线程后,则自动恢复之前的信号集。