Linux系统中的信号编程

信号集

定义:信号集表示一组信号的来(1)或者没有来(0)。

数据类型:sigset_t

//sigset_t结构大概长这个样子
typedef struct{
    unsigned long sig[2];
}sigset_t;

信号相关函数

(1)sigemptyset 把信号集中的所有信号都清零

(2) sigfillset 把信号集中的所有信号都设置为1

(3)信号集中支持60多个信号,可以向信号集中增加(信号标志设置为1)或删除(信号标志设置为0)特定的信号,用 sigaddset 和 sigdelset 就可以做到。sigaddset 用于将某个信号位设置为1,sigdelset用于将某个信号位设置为 0。

(4)sigprocmask、sigismember

sigprocmask 用于设置进程所对应的信号集(进程有默认的信号集)。

sigismember 函数用于检测信号集的特定信号是否被置位。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

//信号处理函数
void sig_quit(int signo)
{
	printf("收到了SIGQUIT信号!\n");

    if (signal(SIGQUIT, SIG_DFL) == SIG_ERR) {
        printf("无法为SIGQUIT信号设置默认处理!\n");
        exit(1);
    }
}


int main(int argc,char* const *argv)
{
    //定义新的信号集和原有的信号集
    sigset_t newmask, oldmask, pendmask;

    //注册信号对应的信号处理函数
    if (signal(SIGQUIT, sig_quit) == SIG_ERR)
    {
        printf("无法捕捉 SIGUSR1 信号!\n");

        //退出程序,参数是错误代码,0表示正常退出,非0表示错误,但具体什么错误,没有特定规定
        exit(1);
    }

    //newmask 信号集中所有信号都清零(表示这些信号都没有来)
    sigemptyset(&newmask);

    //设置newmask信号集中的SIGQUIT信号为1,再来SIGQUIT信号时进程就收不到
    sigaddset(&newmask, SIGQUIT);

    //设置该进程所对应的信号集
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)     
        ///第一个参数用了SIG_BLOCK, 表明设置进程新的信号屏蔽字为当前信号屏蔽字和第2个参数指向的信号集的并集。一个“进程”的当前信号屏蔽字,
        ///开始全部为0,相当于把当前“进程”的信号屏蔽字设置成newmask(屏蔽了SIGQUIT)。第3个参数不为空,则进程老的信号集会保存到第3个参数里,
        ///以备后续恢复用
    {
        printf("sigprocmask(SIG_BLOCK)失败!\n");
        exit(1);
    }
	
    printf("我要开始休息10s了--------begin-----此时我无法接收SIGOUT信号!\n");
    sleep(10);
    printf("我已经休息10s了----------end---!\n");
    if (sigismember(&newmask, SIGQUIT)) {
        printf("SIGQUIT信号被屏蔽了!\n");
    }
    else {
        printf("SIGQUIT信号没有被屏蔽!\n");
    }
    //
    if (sigismember(&newmask, SIGHUP)) {
        printf("SIGHUP信号被屏蔽了!\n");
    }
    else {
        printf("SIGHUP信号没有被屏蔽!\n");
    }
  
    //现在取消对SIGQUIT信号的屏蔽----把信号集还原回去
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0){
        printf("sigprocmask(SIG_SETMASK)失败!\n");
        exit(1);
    }
    printf("sigprocmask(SIG_SETMASK)成功!\n");

    if (sigismember(&oldmask, SIGQUIT)) {
        printf("SIGQUIT信号被屏蔽了!\n");
    }
    else {
        printf("SIGQUIT信号没有被屏蔽, 您可以发送SIGQUIT信号了,我要sleep10s!\n");
        int mysl = sleep(10);
        if (mysl > 0) {
            printf("sleep()还没有睡够,剩余%d\n", mysl);
        }
    }

    printf("再见了!\n");
  
    return 0;
}

重要结论:

信号有等待机制,但无法允许多个相同的信号排队等待(只留1个,其余的相同信号被忽略)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值