sigaction的sa_flags

来源:互联网 发布:空天地一体化网络 编辑:程序博客网 时间:2024/06/07 09:40

    sa_flags实际上是一个位掩码,可以根据需要需要设置某一个flag或者若干个flags的or组合。

    每一个信号都有一组flags与其对应。在GNU C库中,当建立信号和handler之间的关系时,默认除了SA_RESTART flag外,其余flags都是默认设为0的。SA_RESTART flag设置为1或者0是由siginterrupt(int sig, int flag)函数决定的。

        1、如果siginterrupt函数的flag参数设置为0时,如果系统调用被sig信号打断,则在处理完sig信号后,就会重新调用被打断的系统调用,这也是linux默认的行为。(如果如果使用signal函数给sig信号指定了一个新的signal handler,系统调用被打断后,是重新调度还是直接返回error值由linux的默认行为决定)

        2、如果flag参数指定为1,并且没有进行数据传输,则被sig信号打断的系统调用会返回-1,并且errno会被设置为EINTR。

        3、 如果flag参数指定为1,并且被打断的系统调用正在进行数据传输,则系统调用会返回实际传输的数据数量。

    几个重要的flags:

        SA_NOCLDSTOP

        这个flag只对SIGCHLD信号有效,当这个flag设置的时候,系统会给终止的子进程发送一个信号,但是不会给已经停止的子进程发送信号。默认情况下,系统会向终止的子进程和停止的子进程都发送SIGCHLD信号。

        SA_ONSTACK

        略

        SA_RESTART

        使用这个flag会让被信号打断的一些原语(如open,read和write)“正常返回”。为什么会是正常返回呢?由于在进行open或者read等操作时,信号量达到后,系统会先处理信号量的,但是这里就有一个问题,信号量处理完后,被打断的系统调用怎么处理呢?POSIX规定对于这种情况的处理是直接返回,并且要把errno设置为EINTR。但是这样是很不方便的,因为使用信号量的函数必须在每一次系统调用后就都要确认是否是信号量打断,程序员很容易忘记确认,这就很容易导致程序的bug。

        GNU C库提供了一个宏TEMP_FAILURE_RETRY (expression),如果expression出错,并且设置了errno是EINTR,则这个宏会一次又一次的检测expression的值,直到expression的结果不是temporary failure,则返回expression的值。

        BSD则直接restart被中断的系统调用,而不是返回错误值。

        可以使用两种方式指定行为,sigaction.sa_flags或者siginterrupt函数。默认行为是由在调用singal之前是否定义_BSD_SOURCE或者_GNU_SOURCE决定,如果定义了,默认采用restart系统调用的操作,否则,采用直接返回错误的策略。有一种特殊情况除外,在进行read和write操作时,信号可能会导致只传输一部分数据,这种情况下,系统调用会返回实际传输的数据数量。

http://www.gnu.org/software/libc/manual/html_node/Flags-for-Sigaction.html


      

原创粉丝点击