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 nbsp nbsp nbsp nbsp nbsp nbsp nbsp sigemptyset amp act sa mask nbsp nbsp nbsp nbsp nbsp nbsp nbsp act sa flags 0 nbsp nbsp nbsp nbsp nbsp nbsp nbsp act sa h

#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/212440.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午8:02
下一篇 2026年3月18日 下午8:03


相关推荐

  • Android运行时异常“Binary XML file line : Error inflating class”

    Android运行时异常“Binary XML file line : Error inflating class”在原生 Android 下编译 APK 编译没有问题 但是在运行的时候经常出现如标题所描述的异常 然后整个程序 Crash 掉 nbsp nbsp nbsp 我遇到该问题常常都是因为修改了资源文件所引起 大致有以下几种方式来解决 nbsp nbsp nbsp 1 引用类名问题 自定义了一个 View 将他用于布局文件中 假设他的包名叫 MyPackage 类名叫 MyTestView 这个时候你在 XML 作为布局元素来布局的话 必须使用完

    2026年3月19日
    1
  • 建立本地数据库[通俗易懂]

    建立本地数据库[通俗易懂]首先下载安装MySQL,参考:http://www.runoob.com/mysql/mysql-install.html,安装完成后直接打开(安装过程中要求设置用户名和密码,此时输入的密码要记住,后面要使用)然后下载NavicatforMySQL,本人觉得这个比较简单,很适合初学者,安装完成之后点击File(文件)–新建文件,连接名可不填,主机名:localhost,用户名是安装MySQL…

    2022年6月1日
    36
  • VUE组件封装_vue组件内部双向绑定

    VUE组件封装_vue组件内部双向绑定官方:一个组件上的v-model默认会利用名为value的prop和名为input的事件。v-model实际上只是一个语法糖:<inputv-model=”password”>作用与以下相似:<inputtype=”text”:value=”password”@input=”password=$event.target.value”>也就是通过v-model传递的值,最终是传递给了子组件props中value属性,子组件修改valu

    2026年2月21日
    5
  • 柱状图 直方图 条形图 的区别

    柱状图 直方图 条形图 的区别在 Matplotlib 中和在 pyecharts 绘图时我们经常用到的 Bar 那 Bar 这到底是柱状图 条形图还是直方图呢 目录 1 柱状图 2 条形图 3 直方图 4 柱状图 直方图的选择

    2026年3月17日
    2
  • mysql BLOB数据类型分类

    mysql BLOB数据类型分类mysqlBLOB 是是一个二进制大对象 可以容纳可变数量的数据 下面分别说说 mysqlBLOB 数据类型分类 可以分为 nbsp 有 4 种 BLOB 类型 TINYBLOB BLOB MEDIUMBLOB 和 LONGBLOB 来自 www oceanoemchin com 分别讲述其取值范围 可以更好理解二进制存储 1 TINYBLOB 数据类型 nbsp nbsp nbsp 0 255 字节 nbsp nbsp nbsp 不超过 255

    2026年3月19日
    2
  • 最详细完整的flex弹性布局

    最详细完整的flex弹性布局初了解在学习弹性布局之前首先就要明白其概念 flex 就是 flexiblebox 的缩写 意为弹性布局 用来为盒装模型提供最大的灵活性任何一个容器都可以指定为 flex 布局 box display flex 行内元素当然也可以使用 flex 布局 box display inline flex Webkit 内核的浏览器 必须加上 webkit 前缀 box display webkit flex Safari display flex

    2026年3月17日
    2

发表回复

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

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