pause()信号处理程序

时间:2017-06-11 13:49:04

标签: c signals posix pause

#!/usr/bin/env fish function foo __parse_args $argv[1] echo foo end function __parse_args --argument option if test -z $option return # No option to parse, return early end switch $option case -h --help echo "Shows this help and exits" return 0 # How can we exit 0 instead of return? case -\* echo "Error: '$option' not a valid option" return 1 # How can we exit 1 instead of return? end end foo $argv 功能阻塞,直到信号到达。 假设进程得到一个信号并且返回了pause(),那么信号处理程序是否会在<{>} 调用pause()之后的代码之前执行,或者结果是意外的?

示例:

pause()

void sigusr1_handler() { // .. handler code } void main() { // .. bind handler to SIGUSR1 pause(); // wait for SIGUSR1 // some more code } 完成后是否会执行“更多代码”,或者是否存在竞争条件?如果是这样,解决方案是什么?  除了忙碌的等待之外我什么都想不到,但是根本不需要停顿......

2 个答案:

答案 0 :(得分:8)

引自the man page for pause(2)

  

pause()仅在捕获到信号并返回信号捕获函数时返回。在这种情况下, pause()返回-1, errno 设置为 EINTR

您可以确定信号处理程序在some more code之前运行。

答案 1 :(得分:3)

信号处理程序不会同时运行;它们会中断处理它们的线程,并且只有在信号处理程序返回时,中断的流才会继续。

但是,您的示例可能存在其他竞争条件;只是稀疏的伪代码而不是对你的使用案例的完整解释,很难说。例如,一个不同的信号可能会到达并在您的信号发生之前中断pause,然后您的处理程序可能会比您预期的更晚运行。

有几种“正确的方法”可以做到这一点:

  • write单个字节到信号处理程序中的pipe,并且在主要执行流程中来自read
  • sem_post来自信号处理程序的信号量,以及主要执行流程中的sem_wait
  • 使用sigwaitinfosigtimedwait代替信号处理程序。
  • 仍在使用pause,但是在循环中:

    while(!signal_handler_finished) pause();
    

    其中signal_handler_finished的类型为volatile sig_atomic_t,并且在信号处理程序中设置为非零值。