【问题标题】:I want to know which a signal is arrived when system call() is interrupted我想知道系统调用()中断时到达了哪个信号
【发布时间】:2013-08-28 14:36:14
【问题描述】:

我的应用程序有两个线程。每个线程通过每个套接字从服务器接收一些数据。线程等待返回 epoll_wait()。有时 epoll_wait() 返回 -1 而 errno 是 EINTR。 EINTR 表示系统 call() 被信号中断。我添加到处理 EINTR。 但是我不知道什么信号到达以及为什么信号到达。我想知道。

方法一。

我创建了一个线程。

sigset_t sMaskOfSignal;                                               
sigset_t sOldMaskOfSignal;                                            
sigfillset(&sMaskOfSignal);                                           
sigprocmask(SIG_UNBLOCK, &sMaskOfSignal, &sOldMaskOfSignal)

while(1)
{                                                                                        
    sigwait(&sMaskOfSignal, &sArrivedSignal);                                            

    fprintf(stdout, "%d(%s) signal caught\n", sArrivedSignal, strsignal(sArrivedSignal));
}                                                                                        

当 epoll_wait() 被中断时,我无法捕捉到信号。

方法二

当我在 strace 工具中执行我的应用程序时,epoll_wait() 永远不会被中断。

我的问题在 GDB 工具中得到了很好的重现。我需要帮助....

【问题讨论】:

    标签: c++ c multithreading signals eintr


    【解决方案1】:

    您可以尝试实现自己的信号处理程序。如果您的应用程序再次被信号中断,您自己的信号处理程序将被调用,您可以看到发出了什么样的信号。

    void
    signal_callback_handler(int signum)
    {
      printf("Caught signal %d\n",signum);
      exit(signum); // terminate application
    }
    
    int main()
    {
      // Register signal handler for all signals you want to handle
      signal(SIGINT, signal_callback_handler);
      signal(SIGABRT, signal_callback_handler);
      signal(SIGSEGV, signal_callback_handler);
      // .. and even more, if you want to
    }
    

    这不是一个非常方便的方法,但这应该(希望)能让您找出发出了什么信号。 Take a look here 查看可以处理的不同信号(注意:并非所有信号都可以在您自己的信号处理程序(!)中处理)。

    【讨论】:

    • 在报告之前,我尝试使用信号处理程序。但是我无法捕捉到信号。
    • 您可以将信号添加到 [1, 64] 的 for 循环中,以捕获所有信号进行测试。当信号在 sighandler 中打印出来时,您可以通过将 signum 与 kill -l 的输出进行比较来检查它是哪个信号。
    【解决方案2】:

    也许你应该尝试设置信号处理程序来捕获所有信号并将你的信号标志设置为 SA_SIGINFO

    类似的东西

    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_SIGINFO;
    act.sa_sigaction = <handler>;
    
    sigaction(SIGFPE, &act, 0);
    sigaction(SIGHUP, &act, 0);
    sigaction(SIGABRT, &act, 0);
    sigaction(SIGILL, &act, 0);
    sigaction(SIGALRM, &act, 0);
    sigaction(SIGALRM, &act, 0);
    .
    .
    .
    
    //and your handler looks like
    
    void handle_sig (int sig, siginfo_t *info, void *ptr)
    {
         printf ("Signal is %d\n",sig);
    }
    

    在主程序中注册处理程序,并在 epoll 中忽略 EINTR。

    【讨论】:

    • 我在 epoll_wait() 返回 -1 和 EINTR 时添加了一条日志消息。我看到了一条日志消息。但是信号处理程序没有捕获信号。 for (i = 1; i
    • /proc/PID/status SigQ: 0/126776 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 00000000000000000 SigIgn: 0000000> fffffffffffffffffff
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多