GNU/Linux >> Znalost Linux >  >> Linux

Zpracování signálu s více vlákny v Linuxu

pthreads(7) popisuje, že POSIX.1 vyžaduje všechna vlákna v atributech sdílení procesu, včetně:

  • dispozice signálu

POSIX.1 také vyžaduje, aby některé atributy byly odlišné pro každé vlákno, včetně:

  • maska ​​signálu (pthread_sigmask(3) )

  • alternativní zásobník signálů (sigaltstack(2) )

Linuxové jádro complete_signal rutina má následující blok kódu -- komentáře jsou docela užitečné:

/*
 * 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.
         */

Takže to vidíte vy mají na starosti, kam se signály doručují:

Pokud váš proces nastavil dispozice signálu na SIG_IGN nebo SIG_DFL , pak je signál ignorován (nebo výchozí -- zabít, jádro nebo ignorovat) pro všechna vlákna.

Pokud váš proces nastavil dispozice signálu pro konkrétní obslužnou rutinu, můžete ovládat, které vlákno bude přijímat signály, manipulací s maskami konkrétních signálů vláken pomocí pthread_sigmask(3) . Můžete jmenovat jedno vlákno, které je bude všechny spravovat, nebo vytvořit jedno vlákno pro každý signál, nebo jakoukoli kombinaci těchto možností pro konkrétní signály, nebo se můžete spolehnout na aktuální výchozí chování linuxového jádra při doručování signálu do hlavního vlákna.

Některé signály jsou však speciální podle signal(7) manuálová stránka:

Signál může být generován (a tedy čekající na zpracování) pro proces jako celek (např. když je odeslán pomocí kill(2)) nebo pro specifické vlákno (např. určité signály, jako je SIGSEGV a SIGFPE, generované jako důsledek provedení specifické instrukce strojového jazyka jsou směrovány do vlákna, stejně jako signály zacílené na konkrétní vlákno pomocí pthread_kill(3)). Procesně řízený signál může být doručen kterémukoli z vláken, které aktuálně nemají signál blokovaný. Pokud má signál odblokován více než jedno vlákno, jádro si vybere libovolné vlákno, do kterého má signál doručit.


Toto je mírně odlišné podle toho, jakou verzi linuxového jádra používáte.

Za předpokladu 2.6 posix vláken a pokud mluvíte o tom, že OS posílá SIGTERM nebo SIGHUP, signál je odeslán procesu, který je přijímán a zpracováván kořenovým vláknem. Pomocí vláken POSIX můžete také odeslat SIGTERM do jednotlivých vláken, ale mám podezření, že se ptáte na to, co se stane, když OS odešle signál procesu.

Ve verzi 2.6 SIGTERM způsobí, že podřízená vlákna „čistě“ opustí, zatímco ve verzi 2.4 byla podřízená vlákna ponechána v neurčitém stavu.


Linux
  1. Odesílejte příkazy do více relací SSH pomocí Terminátora

  2. Linux – Selhání nastavení afinity k běžícímu procesu se sadou úloh?

  3. Jak vytvářet vlákna v Linuxu (pomocí ukázkového programu C)

  1. JQ Command v Linuxu s příklady

  2. Jak pojmenovat vlákno v Linuxu?

  3. Jsou vlákna jádra Linuxu skutečně procesy jádra?

  1. Zpracování signálů UNIX/Linux:SIGEV_THREAD

  2. Je fopen() v Linuxu bezpečná funkce vláken?

  3. Ctrl + C přerušení zpracování událostí v Linuxu