信号与Linux的多线程处理(Signal handling with multiple threa

2019-06-17 13:18发布

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

哪个线程拦截信号? 多线程可以得到相同的信号? 有没有完全用于处理信号的特殊螺纹? 如果没有,什么线程是处理信号里面发生了什么? 如何执行信号处理程序结束后恢复?

Answer 1:

这是稍微细致入微,在此基础上正在使用版本的Linux内核。

假定2.6 POSIX线程,如果你正在谈论的OS发送SIGTERM或SIGHUP,该信号被发送到处理,其通过接收到的并且通过根线程处理。 使用POSIX线程,你也可以发送SIGTERM到各个线程为好,但我怀疑你是问什么时候该OS将信号发送到进程会发生什么。

在2.6,SIGTERM会导致子线程退出“干净”,其中2.4,子线程都处于不确定状态离开。



Answer 2:

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

  • 信号规定

POSIX.1也需要一些属性是不同的每个线程,包括:

  • 信号掩码( pthread_sigmask(3)

  • 备用信号栈( sigaltstack(2)

Linux内核的complete_signal程序具有下面的代码块-的评论是非常有用:

/*
 * 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_IGNSIG_DFL ,则信号被忽略(或默认-杀,核心,或忽略)的所有线程。

如果你的过程中树立了信号的配置到一个特定的处理程序,那么你就可以控制哪个线程会通过操纵利用特定线程的信号掩码接收信号pthread_sigmask(3) 您可以提名一个线程来管理他们所有,或创建每个信号一个线程,或这些选项的特定信号的任何混合物,或者你依赖的信号传递到主线程的Linux内核的当前默认行为。

一些信号,然而,根据特殊signal(7)手册页:

的信号可以产生(并且因此待处理),用于处理作为一个整体(例如,当使用发出杀灭(2) ),或为一个特定的线程(例如,某些信号,如SIGSEGV和SIGFPE,作为执行的结果所产生一个特定的机器语言指令是线程定向,因为是使用针对一个特定的线程的信号pthread_kill(3) )。 的方法,定向信号可被传递到当前不具有阻塞的信号中的线程中的任何一个。 如果线程的多于一个具有信号畅通,那么内核选择哪个交付信号的任意线程。



文章来源: Signal handling with multiple threads in Linux