阻塞信号集/未决信号集
① 将某个信号放到阻塞信号集,这个信号将被忽略而不会被进程处理(该信号变成未决状态),换句话说,被阻塞的信号
由于不能被递达而变成未决状态
② 直到阻塞解除后,该信号由未决状态
变成递达状态
,信号被处理。
信号集函数
int sigemptyset
(sigset_t *set); // 将set集合置空
int sigfillset
(sigset_t *set); // 将所有信号加入set集合
int sigaddset
(sigset_t *set, int signum); // 将signum信号加入set集合
int sigdelset
(sigset_t *set, int signum); // 从set集合中移除signum信号
int sigprocmask
(int how, const sigset_t *set, sigset_t *oldset); // 屏蔽 or 解除
- 参数:
how取值,假设当前的信号屏蔽字为mask
- SIG_BLOCK:mask = mask|set 添加屏蔽字
- SIG_UNBLOCK:mask = mask|~set 解除屏蔽字
- SIG_SETMASK:mask = set 赋值操作
set:传入的新的set
oldset:保存之前的信号屏蔽字集合
int sigismember
(const sigset_t *set, int signum); //判断set集合中是否存在signum信号
int sigpending
(sigset_t *set); // 读取当前进程中处于未决状态
的信号,放在传出参数set中
int main(){
sigset_t myset;
//清空myset
sigemptyset(&myset);
//将下面三个信号添加到myset集合中
sigaddset(&myset,SIGINT); /* ctrl+C */
sigaddset(&myset,SIGQUIT);/* ctrl+\ */
sigaddset(&myset,SIGKILL);
//将myset集合中的信号设为[阻塞]
sigprocmask(SIG_BLOCK,&myset,NULL);
while(1){
sigset_t pendset;
sigpending(&pendset); //读取当前进程的未决信号集
//1-31
for(int i=1;i<=31;i++){
if(sigismember(&pendset,i)) //判断i信号是否在penset中
printf("1");
else
printf("0");
}
printf("\n");
sleep(1);
}
return 0;
}
[gjw@localhost 4-signal]$ ./signal_set
0000000000000000000000000000000
0000000000000000000000000000000
0000000000000000000000000000000
^C0100000000000000000000000000000 #点击ctrl+C
^\0110000000000000000000000000000 #点击ctrl+\
0110000000000000000000000000000
0110000000000000000000000000000
0110000000000000000000000000000
已杀死 #kill -9 signal_set的pid
程序解读:
1.将ctrl+C,ctrl+\,kill -9引发的信号,放入myset阻塞信号集中
2.调用ctrl+C,ctrl+\触发相应的信号,调用sigpending函数获取[当前进程的
未决信号集],存放在pendset集合中
3.for循环,使用sigismember函数判断i信号是否在pendset集合中
4.调用kill -9杀死当前进程
功能描述:请编写一个程序,设置SIGINT和SIGQUIT信号,并在该程序中实现从文件中读取信息的操作,并保证在读取文件且只有在读取文件的过程中不会被发送的SIGINT和SIGQUIT信号所打断提示:在文件读取前阻塞信号,在文件读取后解除阻塞。
int main(){
int fd=open("/etc/profile",O_RDONLY);
//读取文件之前,将SIGINT/SIGQUIT信号设为阻塞
sigset_t set;
sigemptyset(&set);
sigaddset(&set,SIGINT);
//sigaddset(&set,SIGQUIT);
sigprocmask(SIG_BLOCK,&set,NULL);
char buf[10];
//设为阻塞后,读取文件
while(read(fd,buf,sizeof(buf))!=0){
printf("%s",buf);
//sleep(2);
memset(buf,0,sizeof(buf));
}
/*
while(1){
pause();
}
*/
//读取文件结束后,将SIGINT/SIGQUIT信号解除阻塞
sigset_t uset;
sigemptyset(&uset);
sigaddset(&uset,SIGINT);
//sigaddset(&uset,SIGQUIT);
sigprocmask(SIG_UNBLOCK,&set,NULL);
return 0;
}