当前位置: 首页 > 知识库问答 >
问题:

Linux中多线程的信号处理

华鹭洋
2023-03-14

在Linux中,当一个程序(可能有多个线程)收到信号(如SIGTERM或SIGHUP)时会发生什么?

哪个线程拦截信号?多个线程可以获得相同的信号吗?是否有专门处理信号的特殊线程?如果没有,那么处理信号的线程内部会发生什么?信号处理程序例程完成后,执行如何继续?

共有2个答案

夏侯枫
2023-03-14

根据您使用的Linux内核的版本,这有点细微差别。

假设有2.6个posix线程,如果您谈论的是发送SIGTERM或SIGHUP的操作系统,则信号被发送到进程,由根线程接收并处理。使用POSIX线程,您也可以将SIGTERM发送到各个线程,但我怀疑您是在询问当操作系统向进程发送信号时会发生什么。

在2.6中,SIGTERM将导致子线程“干净地”退出,在2.4中,子线程处于不确定状态。

薛博赡
2023-03-14

pthread(7)描述了POSIX.1要求进程中的所有线程共享属性,包括:

  • 信号处理

POSIX。1还要求每个线程具有不同的属性,包括:

>

交替信号堆栈(sigaltstack(2)

Linux内核的complete\u信号例程有以下代码块——注释非常有用:

/*
 * Now find a thread we can wake up to take the signal off the queue.
 *
 * If the main thread wants the signal, it gets first crack.
 * Probably the least surprising to the average bear.
 */
if (wants_signal(sig, p))
        t = p;
else if (!group || thread_group_empty(p))
        /*
         * There is just one thread and it does not need to be woken.
         * It will dequeue unblocked signals before it runs again.
         */
        return;
else {
        /*
         * Otherwise try to find a suitable thread.
         */
        t = signal->curr_target;
        while (!wants_signal(sig, t)) {
                t = next_thread(t);
                if (t == signal->curr_target)
                        /*
                         * No thread needs to be woken.
                         * Any eligible threads will see
                         * the signal in the queue soon.
                         */
                        return;
        }
        signal->curr_target = t;
}

/*
 * Found a killable thread.  If the signal will be fatal,
 * then start taking the whole group down immediately.
 */
if (sig_fatal(p, sig) &&
    !(signal->flags & SIGNAL_GROUP_EXIT) &&
    !sigismember(&t->real_blocked, sig) &&
    (sig == SIGKILL || !p->ptrace)) {
        /*
         * This signal will be fatal to the whole group.
         */

因此,您可以看到,您负责信号传输的位置:

如果进程已将信号的配置设置为SIG\u IGN或SIG\u DFL,则所有线程都会忽略该信号(或默认值——kill、core或ignore)。

如果进程已将信号的配置设置为特定的处理程序例程,则可以通过使用pthread\u sigmask(3)操作特定的线程信号掩码来控制哪个线程将接收信号。您可以指定一个线程来管理它们,或者为每个信号创建一个线程,或者为特定信号创建这些选项的任意组合,或者依赖Linux内核当前的默认行为将信号传递到主线程。

但是,根据信号(7)手册页,有些信号是特殊的:

可以为整个进程(例如,当使用kill(2)发送时)或特定线程(例如,由于执行特定机器语言指令而生成的某些信号,例如SIGSEGV和SIGFPE,是线程定向的,以及使用pthread_kill(3)针对特定线程的信号)生成(并因此挂起)。进程定向信号可以传递给当前没有阻塞信号的任何一个线程。如果多个线程解除了信号阻塞,则内核选择向其传递信号的任意线程。

 类似资料:
  • 问题内容: 在Linux中,当程序(可能具有多个线程)接收到诸如SIGTERM或SIGHUP之类的信号时会发生什么? 哪个线程拦截信号?多个线程可以得到相同的信号吗?有专门用于处理信号的特殊线程吗?如果不是,那么在处理信号的线程内部会发生什么?信号处理程序例程完成后,如何恢复执行? 问题答案: 根据您所使用的Linux内核版本,这会有些许细微差别。 假设有2.6个posix线程,并且如果您正在谈论

  • 问题内容: 这应该非常简单,并且令我感到惊讶的是,我还没找到关于stackoverflow的答案。 我有一个类似程序的守护程序,该程序需要响应SIGTERM和SIGINT信号才能与新贵一起正常工作。我读到最好的方法是在与主线程不同的线程中运行程序的主循环,并让主线程处理信号。然后,当接收到信号时,信号处理程序应通过设置通常在主循环中检查的哨兵标志来告诉主循环退出。 我已经尝试过这样做,但是它没有按

  • 问题内容: 我有2个线程(线程1和线程2)。而且我有信号处理。每当发生线程2时,都应处理该信号。为此,我写了下面的程序 我编译并运行该程序。每1秒打印一次“ thread1 active”,每3秒打印一次“ thread2 active”。 现在我生成了。但是它会像上面那样显示“ thread1 active”和“ thread2 active”消息。再次生成了,现在每3秒仅打印一次“ threa

  • 问题内容: 我有一个程序,该程序可以创建许多线程并运行,直到关闭嵌入式计算机的电源,或者用户使用或终止该过程为止。 这是一些代码以及main()的外观。 我想知道几件事: 是否需要信号处理? 我在这个线程中读到“ Linux C为正常终止捕获了终止信号” ,显然,操作系统将为我处理清理工作。因此,我可以仅用无限循环替换信号处理程序,然后让OS正常退出线程,取消分配内存等吗? 关于干净终止,还有其他

  • 本文向大家介绍详解Linux多线程使用信号量同步,包括了详解Linux多线程使用信号量同步的使用技巧和注意事项,需要的朋友参考一下 信号量、同步这些名词在进程间通信时就已经说过,在这里它们的意思是相同的,只不过是同步的对象不同而已。但是下面介绍的信号量的接口是用于线程的信号量,注意不要跟用于进程间通信的信号量混淆。 一、什么是信号量 线程的信号量与进程间通信中使用的信号量的概念是一样,它是一种特殊

  • 问题内容: 我需要在接收到任何终止命令(如SIGTERM和SIGKILL)时写入日志文件。 我可以注册SIGTERM,但是如何处理SIGKILL信号? 问题答案: 您不能,至少不是因为进程被杀死。 您 可以 做的是安排父进程监视子进程的死亡,并采取相应的措施。任何体面的过程监控系统(例如daemontools)都内置了这样的工具。