GNU/Linux >> Znalost Linux >  >> Linux

Které vlákno zpracovává signál?

Pozorně si přečtěte signál(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) - které můžete použít (k zablokování SIGINT v nechtěných vláknech). Přečtěte si také tutoriál pthread.

Nepoužívejte signály ke komunikaci nebo synchronizaci mezi vlákny. Zvažte např. mutexy (pthread_mutex_lock atd...) a podmínkové proměnné (pthread_cond_wait atd...).

Pokud jedno z vláken spustí smyčku událostí (např. kolem poll(2)...), zvažte použití signalfd(2).


Pokud odešlete signál procesu, které vlákno v procesu tento signál zpracuje, není určeno.

Podle pthread(7) :

POSIX.1 také vyžaduje, aby vlákna sdílela řadu dalších atributů (tj. tyto atributy se týkají celého procesu, nikoli jednotlivých vláken):
...
- signalizační dispozice
...

POSIX.1 rozlišuje pojmy signály, které směřují k procesu jako celku, a signály, které směřují do jednotlivých vláken. Podle POSIX.1 signál řízený procesem (zaslaný pomocí kill(2) , například) by měl zpracovávat jeden, libovolně vybrané vlákno v procesu.

Pokud chcete, aby některé signály zpracovávalo vyhrazené vlákno ve vašem procesu, zde je příklad z pthread_sigmask(3) vám ukáže, jak to udělat:

Níže uvedený program zablokuje některé signály v hlavním vlákně a poté vytvoří vyhrazené vlákno pro načtení těchto signálů pomocí sigwait(3). Následující shellová relace demonstruje její použití:

$ ./a.out &
[1] 5423
$ kill -QUIT %1
Signal handling thread got signal 3
$ kill -USR1 %1
Signal handling thread got signal 10
$ kill -TERM %1
[1]+  Terminated              ./a.out

Zdroj programu

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

/* Simple error handling functions */

#define handle_error_en(en, msg) \
        do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)

static void *
sig_thread(void *arg)
{
    sigset_t *set = arg;
    int s, sig;

   for (;;) {
        s = sigwait(set, &sig);
        if (s != 0)
            handle_error_en(s, "sigwait");
        printf("Signal handling thread got signal %d\n", sig);
    }
}

int
main(int argc, char *argv[])
{
    pthread_t thread;
    sigset_t set;
    int s;

   /* Block SIGQUIT and SIGUSR1; other threads created by main()
       will inherit a copy of the signal mask. */

   sigemptyset(&set);
    sigaddset(&set, SIGQUIT);
    sigaddset(&set, SIGUSR1);
    s = pthread_sigmask(SIG_BLOCK, &set, NULL);
    if (s != 0)
        handle_error_en(s, "pthread_sigmask");

   s = pthread_create(&thread, NULL, &sig_thread, (void *) &set);
    if (s != 0)
        handle_error_en(s, "pthread_create");

   /* Main thread carries on to create other threads and/or do
       other work */

   pause();            /* Dummy pause so we can test program */
}

Linux
  1. Alternativa k „dd“, která soubor nezkrátí?

  2. Linux – Jak zjistit, který modul poškozuje jádro?

  3. Jaký souborový systém je nejlepší zálohovat?

  1. Který příkaz terminálu Linuxu používáte nejčastěji?

  2. Jak se připojit k vláknu, které visí na blokování IO?

  3. Sledování původu signálu UNIX?

  1. Jak změním velikost písma v Dwarf-fortress?

  2. Jak zjistit zdroj signálu POSIX

  3. Jaký je účel koncového '-' v aplikaci Kubernetes -f -