GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Welcher Thread verarbeitet das Signal?

Lesen Sie sorgfältig signal(7) &pthread(7) &pthread_kill(3) &sigprocmask(2) &pthread_sigmask(3) - die Sie verwenden könnten (um SIGINT zu blockieren in unerwünschten Threads). Lesen Sie auch ein pthread-Tutorial.

Vermeiden Sie die Verwendung von Signalen zur Kommunikation oder Synchronisierung zwischen Threads. Betrachten Sie z. Mutexe (pthread_mutex_lock etc...) und Bedingungsvariablen (pthread_cond_wait etc...).

Wenn einer der Threads eine Ereignisschleife ausführt (z. B. um poll(2)...), erwägen Sie die Verwendung von signalfd(2).


Wenn Sie ein Signal an einen Prozess senden, ist nicht festgelegt, welcher Thread im Prozess dieses Signal verarbeiten wird.

Gemäß pthread(7) :

POSIX.1 erfordert auch, dass Threads eine Reihe anderer Attribute gemeinsam nutzen (d. h. diese Attribute sind prozessweit und nicht pro Thread):
...
- Signaldispositionen
...

POSIX.1 unterscheidet die Begriffe Signale, die an den Prozess als Ganzes gerichtet sind, und Signale, die an einzelne Threads gerichtet sind. Gemäß POSIX.1 ist ein prozessgerichtetes Signal (gesendet mit kill(2) , zum Beispiel) sollte von einem einzigen, willkürlich gehandhabt werden ausgewählten Thread innerhalb des Prozesses.

Wenn Sie möchten, dass ein dedizierter Thread in Ihrem Prozess einige Signale verarbeitet, finden Sie hier ein Beispiel aus pthread_sigmask(3) zeigt Ihnen, wie es geht:

Das folgende Programm blockiert einige Signale im Haupt-Thread und erstellt dann einen dedizierten Thread, um diese Signale über sigwait(3) abzurufen. Die folgende Shell-Session demonstriert ihre Verwendung:

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

Programmquelle

#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. Welchen Linux-Terminalbefehl verwenden Sie am häufigsten?

  2. Alternative zu „dd“, die die Datei nicht abschneidet?

  3. Linux – Wie kann man feststellen, welches Modul den Kernel verschmutzt?

  4. Wie signalisiert man das Ende der Stdin-Eingabe?

  5. Der Unterschied zwischen lokalisieren/wo ist/was?

Wie der Linux-Kernel mit Interrupts umgeht

Welche Linux-Distribution ist die beste für den Datenschutz?

So verwenden Sie den which-Befehl in Linux

Welche Echtzeitpriorität hat in Linux die höchste Priorität?

Welche Signalnummern funktionieren mit dem Kill-Befehl?

Warum ist es möglich, den Bildschirm umzudrehen?