SylixOS的信号屏蔽浅析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SylixOS的信号屏蔽浅析相关的知识,希望对你有一定的参考价值。

1.信号介绍

   信号是一种软中断,用于通过异步的方式对进程进行事件通知。信号分为实时信号和非实时信号,各个进程对于信号的处理方式不一,处理方式分为三类:忽略,捕捉,执行系统默认动作。进程可以选择屏蔽某个或某些信号。

2.信号屏蔽

   SylixOS可以通过sigprocmask函数对某个信号集内的信号进行屏蔽。在信号被屏蔽的期间,进程对所屏蔽的大部分信号不会进行响应,只有解除屏蔽后才会响应。

2.1 sigprocmask函数

   sigprocmask函数原型如程序清单 2-1所示。

程序清单 2-1  sigprocmask函数原型

#include<signal.h>

int sigprocmask (intiCmd,constsigset_t *psigset,sigset_t *psigsetOld);

   函数sigprocmask原型分析:

   1、此函数成功时返回0,失败时返回-1并设置错误号;

   2、参数 iCmd是信号集命令;

   3、参数 psigset是新的信号集;

   4、输出参数 psigsetOld保存先前的信号集。

   sigprocmask设置信号屏蔽字时iCmd对应3个命令:

   1、SIG_BLOCK:新的信号集以或的形式添加到当前的信号屏蔽字中

   2、SIG_UNBLOCK:从当前的信号屏蔽字中删除新的信号集中包含的信号

   3、SIG_SETMASK:将新的信号集赋值给当前信号屏蔽字

2.1 sigprocmask函数

   SylixOS可以通过四个函数对信号集进行操作,具体函数如程序清单 2-2所示。

程序清单 2-2  信号集操作函数

#include<signal.h>

int sigemptyset (sigset_t *psigset);

int sigfillset (sigset_t *psigset);

int sigaddset (sigset_t *psigset,intiSigNo);

int sigdelset (sigset_t *psigset,intiSigNo);

   1、sigemptyset函数用于初始化一个信号集,使其不包含任何信号;

   2、sigfillset用于初始化一个信号集,使其包含所有信号;

   3、sigaddset用于向一个信号集中添加某个信号;

   4、sigdelset用于从一个信号集中删除某个信号。

   SylixOS可以设置进程屏蔽任意的信号,但是某些信号即使被设置屏蔽也无法生效,无法被屏蔽的信号如表 2-1所示。

表 2-1  无法屏蔽的信号

信号名

信号描述

SIGKILL

强迫进程结束

SIGABRT

异常结束

SIGSTOP

停止进程执行

SIGFPE

协处理器出错

SIGILL

非法指令

SIGBUS

bus error

SIGSEGV

无效内存引用

2.1 信号屏蔽测试

   设置进程屏蔽所有的信号后,向进程发送任意的信号,可以查看到信号是否被屏蔽,具体的信号屏蔽测试代码如程序清单 2-3所示。

程序清单 2-3  信号屏蔽测试代码

#include<stdio.h>

#include<signal.h>

 

int  main (int argc,char  **argv)

{

    int      iSigNo;              /*  信号ID                      */

    sigset_t  newMask;           /*  新的信号集                  */

    sigset_t  oldMask;            /*  旧的信号集                  */

    sigset_t  pendMask;          /*  阻塞的信号集                */

 

    sigfillset(&newMask);          /* 信号集包含所有信号          */

   

/*

     *  设置新的信号掩码,并保存旧的信号掩码

     */

    if (sigprocmask(SIG_SETMASK, &newMask, &oldMask) < 0) {

        fprintf(stderr,"Sigprocmask error.\n");

        return  (PX_ERROR);

    }

 

    sleep(5);                    /* 休眠等待信号                */

 

    sigpending(&pendMask);       /* 获取未决的信号集            */

    /*

     *  打印出未决信号集中的信号

     */

    for (iSigNo =SIGHUP;iSigNo <=SIGRTMAX;iSigNo++)

    {

        if (sigismember(&pendMask,iSigNo) ==TRUE) {

            fprintf(stdout,"Signal %d pending.\n",iSigNo);

        }

    }

 

    /*

     *  恢复旧的信号掩码

     */

    if (sigprocmask(SIG_SETMASK, &oldMask,NULL) < 0) {

      fprintf(stderr,"resume mask error.\n");

      return  (PX_ERROR);

    }

 

    return  (ERROR_NONE);

}

   运行代码后,可以通过kill命令向进程发送除表 2-1以外的任意的信号后,信号无法被响应,运行结果具体如图 2-1所示。

技术分享

图 2-1  测试代码的运行结果

   若发送无法被屏蔽的信号,则会执行与信号相关联的处理动作。

3.参考资料

   《SylixOS应用开发手册》


本文出自 “12823745” 博客,请务必保留此出处http://12833745.blog.51cto.com/12823745/1926130

以上是关于SylixOS的信号屏蔽浅析的主要内容,如果未能解决你的问题,请参考以下文章

SylixOS线程堆栈大小浅析

SylixOS钩子函数浅析

SylixOS线程私有数据浅析

SylixOS 用户进程加载浅析

基于SylixOS的中断浅析

SylixOS的RMS浅析