2017-02-28 4 views
0

Ich glaube nicht, dass dies ein Duplikat ist. Ich habe eine sehr spezifische Frage darüber, was mit anderen Threads passiert, wenn ein Signalhandler aufgerufen wird.Linux: Effekt des Signals auf mehrere Threads

Ich habe ein Multithread-Programm, das mit Hardware spielt. Beim Abrufen von SIGTERM (von einem Elternprozess) möchte ich, dass der Signalhandler den Zustand der Hardware auf einen bestimmten Zustand setzt und exit (1). Ich verstehe, dass, da ich nicht mit Signalmasken spielte, der Haupt-Thread das Signal verarbeiten wird. Aber es ist ein Multiprozessorsystem (raspberry pi) und die anderen Threads laufen alle mit hoher Priorität relativ zu main. Sie schlafen wahrscheinlich, aber sie könnten auch Hardware berühren.

Wenn alle anderen Threads bei der Ankunft eines Signals einfrieren, geht es mir gut - ich rufe exit() direkt vom Signalhandler auf und die anderen Threads werden nie wieder laufen. Aber wenn sie unabhängig voneinander laufen können, könnten sie sich mit der Hardware herumärgern, nachdem ich den gewünschten Zustand im Handler eingestellt habe, aber bevor ich mich beende. Und ich kann keine Dokumentation finden, die den Effekt beschreibt. Wenn "alles außer dem Signalhandler" nicht standardmäßig eingestellt ist, gibt es eine Möglichkeit, dieses Verhalten zu erhalten?

Ich kann den Code neu entwerfen, um die ganze Hardware-Handhabung in einen Thread zu bringen, und diesen Thread die Interrupts behandeln lassen, aber es ist unbequem - das Thread-Layout habe ich jetzt eine gute Arbeitsteilung und jeder Thread weiß, welche Hardware es kann berühren und wann. Ich würde lieber nicht neu gestalten.

Antwort

1

Die anderen Threads werden weiterhin ausgeführt, während der Signalverarbeitungs-Thread ausgeführt wird. Ich kenne keinen Freeze-Everything-Mechanismus.

Wenn Sie jedoch mehrere Threads haben, die die Hardware manipulieren, scheint es, als ob Sie irgendeine Art von gegenseitigem Ausschlussmechanismus haben sollten. In der Tat:

pthread_mutex_lock(&hardware_lock); 
fiddle_with_hardware(); 
pthread_mutex_unlock(&hardware_lock); 

Dann können Sie müssen nur Ihre Signal-Handling-Thread die Sperre erwerben, die Hardware-Zustand zurückgesetzt und exitohne Lösen der Verriegelung nennen. Der exit Aufruf beendet alle Threads, und da die Sperre gehalten wird, könnte kein anderer Thread mit der Hardware vor dem Beenden in Konflikt kommen.

Wenn Sie über mehrere Threads verfügen, die alle diskreten Teile des Hardware-Gesamtstatus bearbeiten, können Sie für jeden Statusbereich eine separate Sperre erstellen. Lassen Sie dann Ihren Signalverarbeitungs-Thread alle der Sperren erfassen, bevor Sie den endgültigen Hardware-Status festlegen und aufrufen. Da es im normalen Betrieb nur einen Thread geben wird, der versucht, auf jeden diskreten Abschnitt des Zustands zuzugreifen, sollte es keinen messbaren Leistungseinfluss von der zusätzlichen Verriegelung geben.

Eine andere Sache. Ich denke nicht, dass es richtig ist, dass "der Hauptfaden das Signal verarbeitet, da ich nicht mit Signalmasken gespielt habe." Von pthreads(7):

Nach POSIX.1 ein Verfahren gerichtete Signal (gesendet Abtötung unter Verwendung von (2), zum Beispiel), sollte durch einen einzigen, willkürlich ausgewählten Thread innerhalb des Prozesses behandelt werden.

Das heißt, Sie sollten mit pthread_sigmask sein, um sicherzustellen, dass die SIGTERM auf den Hauptthread gerichtet ist.

+0

Nehmen Sie einfach nicht, dass "haben Ihre Signal-Handling-Thread die Sperre erwerben" kann nicht im Signal-Handler getan werden, obwohl ein Mutex ist nicht sicher in einem Signal-Handler zu verwenden. – nos

+0

@nos Guter Punkt.Es wäre besser, wenn der Signal-Handler ein Flag gesetzt und der Rest nach der Rückkehr vom Signal-Handler ausgeführt wird. –

+0

Das war, wovor ich Angst hatte. Ich wusste, dass ich die Mutex-Lösung nicht machen konnte (und eine meiner Ängste ist, dass wiringPi einen Mutex unter den Abdeckungen verwendet, was jede Lösung, die den Hardware-Zugriff nicht unmöglich macht, unmöglich macht.) Ich werde es wahrscheinlich tun müssen Redesign. Vielen Dank. – user15001

Verwandte Themen