sigsuspend的用法

sigsuspend的用法include include includevoidm op int main nbsp nbsp nbsp nbsp nbsp nbsp nbsp sigset tnew mask nbsp nbsp nbsp nbsp nbsp nbsp nbsp structsigact

—————————————————————————
#include


#include


#include



void my_op(int);







main()
{

        sigset_t new_mask;
        struct sigaction act;


        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        act.sa_handler=my_op;

        if(sigaction(SIGINT,&act,NULL))   //注册信号SIGINT处理函数为my_op
        {

                printf(“install signal SIGINT error\n”);
        }

        if(sigaction(SIGQUIT,&act,NULL)) //注册信号SIGQUIT处理函数为my_op
        {

                printf(“install signal SIGQUIT error\n”);
        }







        printf(“please send signal: kill -s %d %d\n”,SIGQUIT, getpid());

        sigemptyset(&new_mask);

        if(sigprocmask(0, NULL,&new_mask) < 0) //查询当前进程被挂起的信号存入new_mask中,
                                               //可用sigpending(&new_mask)代替
        {

                printf(“get pending mask error\n”);
        }

        sigaddset(&new_mask,SIGQUIT);     //将信号SIGQUIT,添加到信号集new_mask中,
                                           //也就是在原有的信号掩码中加入信号SIGQUIT。
         sigsuspend(&new_mask);            //将当前的信号掩码替换成new_mask,
                                           //也就是把信号SIGQUIT给阻塞后,当前进程挂起。
                                           //必须等待除了未阻塞的信号到来才恢复成原来的信号掩码
        exit(0);
}

void my_op(int signum)
{

        if ( signum == SIGINT )
        {

                printf(“SIGINT\n”);
        }
        else if ( signum == SIGQUIT )
        {

                printf(“SIGQUIT\n”);
        }
























        return;
}
———————————————————————-
编译该程序,并运行。在另一终端向该进程发送信号(运行kill -s SIGQUIT pid,SIGQUIT以及pid具体多少看程序的输出),一直未见到应该打印的信息”SIGQUIT\n”,这就说明SIGQUIT信号被阻塞了,当发送SIGINT信号时给该程序时,因为SIGINT信号并未阻塞,所以打印了”SIGINT\n”,紧接着sigsuspend恢复原来的信号掩码(原来的信号掩码并未阻塞SIGQUIT信号),最后才打印了刚开始接收到的SIGQUIT信号的信息息”SIGQUIT\n”。具体情况如下:

情况一:
1、程序运行后,执行到sigsuspend函数,用new_mask替换原来的信号掩码,即SIGQUIT信号被阻塞。
2、开启另一终端,执行 kill -s SIGQUIT pid 






程序结果如下:
please send signal: kill -s 3 4026

3、这就说明SIGQUIT信号被阻塞了,未见到应该打印的信息”SIGQUIT\n”,程序任在被挂起状态。

情况二:
1、程序运行后,执行到sigsuspend函数,用new_mask替换原来的信号掩码,即SIGQUIT信号被阻塞。
2、开启另一终端,执行 kill -s SIGQUIT pid 






程序结果如下:
please send signal: kill -s 3 4026

3、这就说明SIGQUIT信号被阻塞了,未见到应该打印的信息”SIGQUIT\n””,程序任在被挂起状态。
4、继续在另一终端上,执行 kill -s SIGINT pid 



程序结果如下:
please send signal: kill -s 3 4026
SIGINT
SIGQUIT

程序退出

5、这说明sigsuspend恢复原来的信号掩码(原来的信号掩码并未阻塞SIGQUIT信号),最后才打印了刚开始接收到的SIGQUIT信号的信息息”SIGQUIT\n”,打印结束程序退出。

================================================

#include


#include


#include















volatile quitflag;
void my_op(int);

main()
{

        sigset_t new_mask,old_mask,zero_mask;
        struct sigaction act;
        quitflag = 0;



        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        act.sa_handler=my_op;

        if(sigaction(SIGINT,&act,NULL))   //注册信号SIGINT处理函数为my_op
        {

                printf(“install signal SIGINT error\n”);
        }

        if(sigaction(SIGQUIT,&act,NULL)) //注册信号SIGQUIT处理函数为my_op
        {

                printf(“install signal SIGQUIT error\n”);
        }







        printf(“please send signal: kill -s %d %d\n”,SIGQUIT, getpid());

        sigemptyset(&new_mask);
        sigaddset(&new_mask,SIGQUIT);    //将信号SIGQUIT,添加到空信号集new_mask中

        if(sigprocmask(SIG_BLOCK, &new_mask,&old_mask)) //把信号SIGQUIT给阻塞
        {

                printf(“block signal SIGQUIT error\n”);
        }

        sigemptyset(&zero_mask);    //清空信号集zero_mask

        while(quitflag == 0)
        {

              sigsuspend(&zero_mask); //将当前的信号掩码替换成空信号掩码zero_mask,
                                        //也就是没有任何信号被阻塞,当前进程挂起。
                                       //等待任意信号到来就可恢复成原来的信号码,















但是这里有个循环
                                     //判断当quitflag == 0 时继续挂起当前进程,这里呢除了SIGQUIT信号


                                                  //外其它信号都不可以改变quitflag的值

        }

        if(sigprocmask(SIG_SETMASK,&old_mask,NULL)<0) //程序继续运行后恢复进程原来的信号掩码
        {

                printf(“unblock signal error\n”);
        }

        exit(0);
}

void my_op(int signum)
{

        if ( signum == SIGINT )
        {

                printf(“SIGINT\n”);
        }
        else if ( signum == SIGQUIT )
        {

                printf(“SIGQUIT\n”);
                quitflag = 1;
        }



















        return;
}
———————————————————————-

这里程序的情况分三种:
情况一:
1、程序运行后,执行到sigsuspend函数,用空信号掩码zero_mask替换原来的信号掩码,即不阻塞任何信号。

2、开启另一终端,执行 kill -s SIGINT pid 







程序结果如下:
please send signal: kill -s 3 4026
SIGINT

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号的处理函数不能更改quitflag的值,仍然不阻塞任何信号。

情况二:
1、程序运行后,执行到sigsuspend函数,用空信号掩码zero_mask替换原来的信号掩码,即不阻塞任何信号。

2、开启另一终端,执行 kill -s SIGINT pid 








程序结果如下:
please send signal: kill -s 3 4026
SIGINT

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号的处理函数不能更改quitflag的值,仍然不阻塞任何信号。

4、继续在另一终端上,执行 kill -s SIGQUIT pid 





程序结果如下:
please send signal: kill -s 3 4026
SIGINT
SIGQUIT

执行完后程序退出

5、为什么打印了“SIGQUIT\n”?不是被阻塞了么?原因是:sigsuspend不阻塞任何信号,所以呢,就执行了SIGQUIT的处理函数,改变了quitflag的值,quitflag = 1,打印”SIGQUIT\n”; 然后退出循环。紧接着sigsuspend恢复“原来的”信号掩码(这里的“原来的信号掩码”是包含阻塞SIGQUIT信号的),最后把信号掩码设置成最初的样子old_mask,程序退出。

情况三:
1、程序运行后,执行到sigsuspend函数,用空信号掩码zero_mask替换原来的信号掩码,即不阻塞任何信号。

2、开启另一终端,执行 kill -s SIGINT pid 











程序结果如下:
please send signal: kill -s 3 4026
SIGINT

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号的处理函数不能更改quitflag的值,仍然不阻塞任何信号。

4、继续在另一终端上,执行 kill -s 40 pid 





程序结果如下:
please send signal: kill -s 3 4026
SIGINT
Real-time signal 5

执行完后程序退出

5、为什么打印了“Real-time signal 5\n”?原因是:sigsuspend不阻塞任何信号,所以呢,就执行了40的默认处理函数。那为什么退出了循环了?应该没改变quitflag的值啊?实际上,40信号的默认处理函数是打印一行字符后就直接终止程序了,所以后面的代码都没执行了。想要改变就必须重新注册40的处理函数。
===============================================================================

#include


#include


#include














volatile quitflag;
void my_op(int);

main()
{

        sigset_t new_mask,old_mask,full_mask;
        struct sigaction act;
        quitflag = 0;



        sigemptyset(&act.sa_mask);
        act.sa_flags=0;
        act.sa_handler=my_op;

        if(sigaction(SIGINT,&act,NULL))   //注册信号SIGINT处理函数为my_op
        {

                printf(“install signal SIGINT error\n”);
        }

        if(sigaction(SIGQUIT,&act,NULL)) //注册信号SIGQUIT处理函数为my_op
        {

                printf(“install signal SIGQUIT error\n”);
        }







        printf(“please send signal: kill -s %d %d\n”,SIGQUIT, getpid());

        sigemptyset(&new_mask);
        sigaddset(&new_mask,SIGQUIT);    //将信号SIGQUIT,添加到空信号集new_mask中

        if(sigprocmask(SIG_BLOCK, &new_mask,&old_mask)) //把信号SIGQUIT给阻塞
        {

                printf(“block signal SIGQUIT error\n”);
        }

        sigfillset(&full_mask);          //将所有信号添加到信号集full_mask
        sigdelset(&full_mask,SIGQUIT); //将信号集full_mask中的SIGQUIT信号删除

        while(quitflag == 0)
        {

              sigsuspend(&full_mask); //将当前的信号掩码替换成信号掩码full_mask (不包含SIGQUIT信号),
                                          //也就是除了SIGQUIT信号其它信号都被阻塞,当前进程挂起。
                                          //只能等
















待SIGQUIT信号到来就可恢复成原来的信号掩码,
                                      //(这里“原来的信号掩码”是SIGQUIT信号被阻塞的信号集)


        }

        if(sigprocmask(SIG_SETMASK,&old_mask,NULL)<0) //程序继续运行后恢复进程最初始的信号掩码
        {

                printf(“unblock signal error\n”);
        }

        exit(0);
}

void my_op(int signum)
{

        if ( signum == SIGINT )
        {

                printf(“SIGINT\n”);
        }
        else if ( signum == SIGQUIT )
        {

                printf(“SIGQUIT\n”);
                quitflag = 1;
        }



















        return;
}
———————————————————————-
这里程序的情况分三种:
情况一:
1、程序运行后,执行到sigsuspend函数,用full_mask替换原来的信号掩码,除了SIGQUIT信号其它信号都被阻塞。

2、开启另一终端,执行 kill -s SIGINT pid 






程序结果如下:
please send signal: kill -s 3 4026

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号被阻塞。

情况二:
1、程序运行后,执行到sigsuspend函数,用full_mask替换原来的信号掩码,除了SIGQUIT信号其它信号都被阻塞。

2、开启另一终端,执行 kill -s SIGINT pid 







程序结果如下:
please send signal: kill -s 3 4026

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号被阻塞。

4、继续在另一终端上,执行 kill -s SIGQUIT pid 




程序结果如下:
please send signal: kill -s 3 4026
SIGQUIT
SIGINT

执行完后程序退出

5、为什么先打印了“SIGQUIT\n”?原因是:sigsuspend不阻塞SIGQUIT信号,所以呢,就执行了SIGQUIT的处理函数,改变了quitflag的值,quitflag = 1,打印”SIGQUIT\n”; 然后退出循环。紧接着sigsuspend恢复“原来的”信号掩码(这里的“原来的信号掩码”是阻塞SIGQUIT信号而不阻塞SIGINT的)所以接着打印“SIGINT\n”,最后把信号掩码设置成最初的样子old_mask,程序退出。

情况三:
1、程序运行后,执行到sigsuspend函数,用full_mask替换原来的信号掩码,除了SIGQUIT信号其它信号都被阻塞。

2、开启另一终端,执行 kill -s SIGINT pid 











程序结果如下:
please send signal: kill -s 3 4026

3、程序任在被挂起状态,这就说明还在循环中,因为SIGINT信号被阻塞。

4、继续在另一终端上,执行 kill -s 40 pid 




程序结果如下(40信号也是被阻塞的,所以还在循环中):
please send signal: kill -s 3 4026

5、继续在另一终端上,执行 kill -s SIGQUIT pid 


程序结果如下:
please send signal: kill -s 3 4026
SIGQUIT
Real-time signal 5

执行完后程序退出

6、为什么没打印了“SIGINT\n”?原因是:实际上,40信号的默认处理函数是打印一行字符后就直接终止程序了,所以后面的代码都没执行了。想要改变就必须重新注册40的处理函数。






版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/208356.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月19日 上午11:46
下一篇 2026年3月19日 上午11:46


相关推荐

  • 腾讯元宝怎么开启编程模式

    腾讯元宝怎么开启编程模式

    2026年3月13日
    3
  • gff文件_如何提取gff文件中的基因注释信息

    gff文件_如何提取gff文件中的基因注释信息原标题 如何提取 gff 文件中的基因注释信息 gff3 格式注释文件是最常见的基因注释 https archive broadinstitu org annotation argo help gff3 html 简单来说 gff3 是以 tab 分隔的文本文件 共有 9 列 对应信息如下 1 seqnameThena Typicallyach

    2025年9月24日
    7
  • [软件下载]Mysql、jdk、Tomcat、PyCharm等历史版本网址汇总

    [软件下载]Mysql、jdk、Tomcat、PyCharm等历史版本网址汇总Jdk 历史版本下载网址 https www oracle com java technologies downloads archive 下载需要账号自行注册解决很快 Tomcat 历史版本下载网址 https archive apache org dist tomcat Mysql 历史版本下载地址 https downloads mysql com archives community PyCharm 历史版本下载地址 https www jetbrains com pycha

    2026年3月18日
    2
  • SQL行转列、列转行

    SQL行转列、列转行这个主题还是比较常见的,行转列主要适用于对数据作聚合统计,如统计某类目的商品在某个时间区间的销售情况。列转行问题同样也很常见。一、整理测试数据createtablewyc_test( idint(32)notnullauto_increment, namevarchar(80)defaultnull, datedatedefaultn…

    2022年4月4日
    58
  • Numpy 中的矩阵求逆

    Numpy 中的矩阵求逆1 矩阵求逆 importnumpya np array 1 2 3 4 初始化一个非奇异矩阵 print a I print np linalg inv a 与上一步等同 对应于 MATLAB 中 inv 函数 2 矩阵求伪逆 importnumpya 定义一个奇异阵 AA np zeros 4

    2026年3月19日
    3
  • VBoxManage命令详解技术文章[通俗易懂]

    VBoxManage命令详解技术文章[通俗易懂]薸泊`お甡VBoxManage命令详解技术文章VBoxManage[-v|-version]        显示virtualbox的版本号VBoxManage-nologo              隐藏logoVBoxManage-convertSettings     允许自动转换设置文件VBoxManage-convertSettingsBackup 允许自动转换设置文件,…

    2022年6月14日
    29

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号