POSIX Threads / Signale: Portable Möglichkeit zu bestimmen, zu welchem ​​Thread ein Signal gesendet wurde?

8

Ich habe einen Multithread-Server (mit POSIX-Threads) mit einem Thread für jede persistente Verbindung. In einem der Threads schließt sich das andere Ende der Verbindung, wodurch ein SIGPIPE geliefert wird. Gibt es eine (vorzugsweise portable) zu bestimmen, welcher Thread (und damit welche Verbindung) dies passiert, so kann ich meine Signal-Handler entweder tun die Thread / Connection Cleanup Arbeit selbst oder setzen Sie ein Flag, so dass die Haupt-und Worker-Thread jeweils sehen Sie müssen es später tun?

EDIT: Ich frage mich, ob ich vielleicht & amp; errno verwenden könnte, speichern Sie es in einem globalen Array und verknüpfen Sie es mit der Server-ID für den Thread, und suchen Sie dann im Signal-Handler nach & amp; errno. Wäre das spezifische errno des Threads für den Signal-Handler sichtbar? Ist mein Verständnis davon, wie das fadensichere errno auch im Stadion funktioniert?

    
Steely Dan 27.12.2011, 21:55
quelle

4 Antworten

12

Ich denke nicht, nein. Eine bessere Lösung für Multithread-Server ist es, das SIGPIPE -Signal zu unterdrücken (indem signal(SIGPIPE, SIG_IGN) als Teil der Startroutine des Programms aufgerufen wird) und dann den Thread-Deal mit dem Fehlerwert (-1 / EPIPE), der von send() zurückgegeben wird .

Signale und Multithreading vermischen sich nicht gut.

    
Jeremy Friesner 27.12.2011, 21:58
quelle
1

Sie können pthread_self sicher in einem Signal-Handler verwenden. Es ist async-signalsicher .

Diese Antwort ist für die Nachwelt. Ich empfehle diesen Ansatz nicht technisch. Die anderen Antworten und Kommentare, die einen anderen Ansatz vorschlagen, wären besser umzusetzen.

Als diese Frage gestellt wurde, war die Sicherheit von pthread_self nicht unbedingt offensichtlich. Das POSIX: 2008 Technical Corrigendum 1 von 2013 (zwei Jahre nachdem diese Frage gestellt wurde) stellt klar, dass pthread_self explizit async-signal-sicher ist, wie in der Linux signal (7) man-seite .

Entsprechend haben Sie in Kommentaren erwähnt, dass Sie nicht sicher sind, ob der "Kernel [einen SIGPIPE] an einen Thread sendet, der ihn nicht blockiert hat" . Das ist ein gutes Anliegen - ist es ein prozessgesteuertes Signal oder ein fadengesteuertes Signal? - Und zum Glück, fehl am Platz. Ein kernelerzeugter SIGPIPE ist ein "synchron erzeugtes" Signal als Reaktion auf einen I / O-Aufruf und wird an den aufrufenden Thread gesendet. Dies wurde in Corrigendum 2 (2004) zu POSIX: 2001 explizit klargestellt, dass ein SIGPIPE als Antwort auf ein write " an thread " gesendet (Hervorhebung hinzugefügt).

    
pilcrow 18.12.2015 14:38
quelle
0

Mein Ansatz wäre, den Signal-Handler für SIGPIPE einfach seine Thread-ID in eine globale Variable schreiben zu lassen und einen anderen Mechanismus zu verwenden, um dies dem Thread zu signalisieren, der damit umgehen sollte.

    
Eugen Rieck 27.12.2011 22:01
quelle
0

Was ist mit der Verwendung einer globalen Variable (deklariert thread-local) zum Speichern der Thread-ID, initialisieren Sie sie bei der Erstellung von Threads und verweisen Sie darauf im Signal-Handler des Threads.

Für Details zu GCC siehe hier: Ссылка oder allgemeiner hier: Ссылка

    
alk 28.12.2011 16:59
quelle

Tags und Links