首页 文章

主/工作线程和信号处理

提问于
浏览
6

我正在编写一个程序,有一个主线程和一些工作线程,我想让信号处理正确 . 我的问题如下:

主线程启动并执行所有分配

主线程设置SIGINT信号处理程序

主线程启动工作线程 . 工作线程不需要特殊清理,但是它们可以在系统调用或信号量上休眠 .

收到SIGINT时,我的理解是只有一个线程接收它 . 因此,如果线程在系统调用或信号量上休眠,它们就不会被唤醒,我将无法pthread_join我的工作线程并在我的主线程中进行所有必要的清理 .

以下信号处理程序可以解决我的问题吗?

void term(int sig)
{
    g_do_cleanup = 1;
    pthread_kill(worker_1_id, some_other_signal);
    ...
    pthread_kill(worker_2_id, some_other_signal);
}

我期待的是,在接收到SIGINT后,所有线程都将用另一个信号发出信号,退出阻塞呼叫,看到 g_do_cleanup 标志并正常退出 .

欢迎任何关于如何正确执行此操作的评论或链接 .

编辑:我不是在寻找一种方法来唤醒多个线程等待特定条件,所以我不认为pthread_cond_signal方法是我正在寻找的 . 我想要的是:

  • 找到阻塞调用上阻塞的所有线程从这些调用返回的方法 .

  • 或者杀死除主要线程之外的所有线程 .

3 回答

  • 4

    这是我通常在主app线程中做的事情:

    /* before starting other threads */
    sigset_t sigs;
    sigemptyset( &sigs );
    sigaddset( &sigs, SIGTERM );
    sigaddset( &sigs, SIGINT );
    /* add other signals to handle */
    if ( pthread_sigmask( SIG_BLOCK, &sigs, 0 )) { /* handle error */ }
    /* can start threads now */
    ...
    /* in the main event loop */
    siginfo_t info;
    if ( sigwaitinfo( &sigs, &info ) == -1 ) { /* handle error */ }
    switch( info.si_signo )
    {
      case SIGTERM:
      case SIGINT: /* raise shutdown event */ break;
      default: /* other actions - log rotation, etc. */
    }
    ...
    

    这种方式信号成为常规应用程序事件 - 没有特殊的信号上下文限制等 . 等待也可以通过 sigtimedwait 超时完成,尽管BSD衍 生产环境 品不支持它 .

  • 2

    听起来像你想要的是一个pthread条件变量,这样你就可以通过从主线程中选择一个“事件”来唤醒任意数量的多个线程 .

    有关更多信息,请参见PTHREAD_COND_DESTROYPTHREAD_COND_BROADCAST的手册页 .

  • 1

    你的计划似乎很好 . 您正在强制一个线程处理系统信号 . 您需要使用pthread-sigmask()屏蔽工作线程中除某些其他信号之外的信号 .

    我想我会使用一个单独的线程来处理过程信号而不是主控 . 让它在等待运行信号处理程序时等待信号量或sigwait()等等 . 将pthread-kill代码移出信号处理程序 . 只需设置开关并让信号等待线程将other_signal发送到工作线程并退出 .

相关问题