sigemptyset、sigaddset、sigprocmask的用法

本文介绍了一个C语言程序示例,该程序演示了如何使用信号处理函数sigprocmask来阻塞和取消阻塞SIGINT信号。通过设置信号集并在循环中进行sin函数计算,展示了信号阻塞的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

程序可以实现!!!!!!!
http://hi.baidu.com/mylife1898/blog/item/09439ef9491f7c51252df2ee.html/cmtid/a5b6e851d8d265868c543006

源程序:

#include <signal.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(int argc,char **argv)
{
double y;
sigset_t intmask;
int i,repeat_factor;
if(argc!=2)
{
fprintf(stderr,"Usage:%s repeat_factor\n\a",argv[0]);
exit(1);
}
if((repeat_factor=atoi(argv[1]))<1)repeat_factor=10;
sigemptyset(&intmask); /* 将信号集合设置为空 */
sigaddset(&intmask,SIGINT); /* 加入中断 Ctrl+C 信号*/
while(1)
{
/*阻塞信号,我们不希望保存原来的集合所以参数为NULL*/
sigprocmask(SIG_BLOCK,&intmask,NULL);
fprintf(stderr,"SIGINT signal blocked\n");
for(i=0;i<repeat_factor;i++)y=sin((double)i);
fprintf(stderr,"Blocked calculation is finished\n");
/* 取消阻塞 */
sigprocmask(SIG_UNBLOCK,&intmask,NULL);
fprintf(stderr,"SIGINT signal unblocked\n");
for(i=0;i<repeat_factor;i++)y=sin((double)i);
fprintf(stderr,"Unblocked calculation is finished\n");
}
exit(0);
}

解释如下:

sigemptyset 函数初始化信号集合set,将set 设置为空.

sigfillset 也初始化信号集合,只是将信号集合设置为所有信号的集合.

sigaddset 将信号signo 加入到信号集合之中,sigdelset 将信号从信号集合中删除.

sigismember 查询信号是否在信号集合之中.s

igprocmask 是最为关键的一个函数.在使用之前要先设置好信号集合set.这个函数的作用是将指定的信号集合set 加入到进程的信号阻塞集合之中去,如果提供了oset 那么当前的进程信号阻塞集合将会保存在oset 里面.参数how 决定函数的操作方式:
SIG_BLOCK:增加一个信号集合到当前进程的阻塞集合之中.
SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合.
SIG_SETMASK:将当前的信号集合设置为信号阻塞集合.

上述源程序,在不带参数执行时,输出是个错误的结果是:Usage:./sigset repeat_factor

带参数执行后的结果将是不断重复如下语言:

SIGINT signal blocked
Blocked calculation is finished
SIGINT signal unblocked
Unblocked calculation is finished
SIGINT signal blocked
Blocked calculation is finished
SIGINT signal unblocked
Unblocked calculation is finished
SIGINT signal blocked
Blocked calculation is finished
SIGINT signal unblocked
Unblocked calculation is finished
SIGINT signal blocked
Blocked calculation is finished
SIGINT signal unblocked
Unblocked calculation is finished
SIGINT signal blocked
Blocked calculation is finished
SIGINT signal unblocked
Unblocked calculation is finished

在输入Ctrl+c后将会停止。

### 使用 `sigprocmask` 函数管理信号掩码 在多线程或多进程编程中,有时需要临时阻塞某些信号以防止它们打断当前操作。这可以通过调用 `sigprocmask` 来实现。此函数允许修改或查询当前进程的信号掩码。 #### 函数原型 ```c #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oldset); ``` 参数说明: - `how`: 控制如何调整信号掩码的行为,取值有三种可能:`SIG_BLOCK`, `SIG_UNBLOCK`, 和 `SIG_SETMASK`. - `set`: 指向要应用的新信号指针。 - `oldset`: 如果不为空,则用于存储旧的信号掩码副本[^4]。 当成功执行时返回0;失败则返回-1,并设置相应的错误代码到全局变量errno中。 下面是一个简单的例子来展示怎样使用 `sigprocmask`: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> void show_signal_set(sigset_t *set){ int i; printf("Signal set:"); for(i=1;i<NSIG;++i){ // NSIG 定义了系统支持的最大信号数加一 if(sigismember(set,i)){ printf(" %d",i); } } putchar('\n'); } int main(){ sigset_t newmask, oldmask; // 初始化一个新的空sigemptyset(&newmask); // 添加 SIGINT 到新的信号sigaddset(&newmask,SIGINT); // 获取当前信号掩码并保存至 oldmask 中 if (sigprocmask(SIG_SETMASK,&newmask,&oldmask)<0) { perror("Failed to get current signal mask"); exit(EXIT_FAILURE); } puts("Blocking SIGINT..."); // 显示新旧两个信号的内容 printf("Old Signal Mask:\t");show_signal_set(&oldmask); printf("New Signal Mask:\t");show_signal_set(&newmask); sleep(5); // 阻塞一段时间让测试更明显 // 还原原来的信号掩码 if (sigprocmask(SIG_SETMASK,&oldmask,NULL)<0) { perror("Failed to restore original signal mask"); exit(EXIT_FAILURE); } puts("\nUnblocking all signals..."); return EXIT_SUCCESS; } ``` 这段代码展示了如何创建一个包含特定信号(这里是 `SIGINT`)的信号,并通过 `sigprocmask` 修改当前进程的信号掩码来阻止这些信号被传递给进程。之后又恢复了原始的状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值