信号处理功能正确清洁

时间:2017-04-27 20:05:06

标签: c signals signal-handling

我制作了一个使用fork()函数的程序来制作子进程。它的子进程做了一些工作,但我希望它们在从父进程收到SIGTERM信号时终止。在退出之前,我还希望他们清理我已经分配的数组并通过FIFO将一些东西发送到父进程。所以我有2个场景。

  1. 我的数组的全局变量以及FIFO的文件描述符,然后通过信号处理函数退出,例如:

    /*global variables*/
    struct whatever ** test;
    int test_size;
    int fd_in, fd_out;
    
    /*handler*/
    void shutdown(int signo)
    {
          /*free memory for the arrays malloc'd through the program*/
          /*send message with the help of fd_out*/
          /*close fd_in and fd_out*/
          _exit(0);
    }
    
  2. 声明一个全局int标志,当子进程感知到标志已更改时,它们会清理数组,发送消息并退出。

    /*global variables*/
    int exit_flag=0;
    
    /*handler*/
    void shutdown(int signo)
    {
          exit_flag=1;
    }
    
    /*child process*/
    int main()
    {
          /*declare fds and arrays*/
          /*use sigaction and set up handler*/
    
          while(!exit_flag)
          {
                 /*do stuff*/
          }
    
          /*free memory*/
          /*send message with the help of fd_out*/
          /*close fds*/
    }
    
  3. 我的问题是哪种情况会带来良好的编码/编程?它们是相同的还是有更好,更正确的方法来做到这一点?

1 个答案:

答案 0 :(得分:1)

您的第二次实施比第一次实施的错误要少得多。如果要释放/关闭资源,则必须确保活动进程未使用这些资源。由于您正在接收异步信号,因此无法确定您的进程处于合适的状态以在没有竞争条件的情况下释放这些资源。

此外,您很可能还需要在其他条件下执行这些清理例程(错误,完成等),因此如果在处理程序中实现这些例程可能会是多余的。

另外,最好养成将全局标志声明为volatile的习惯,以确保编译器不会将标志优化为常量并使您陷入无限循环。< / p>

volatile int exit_flag=0;