9 Stimmen

Lesen gemeinsamer Daten innerhalb eines Signalhandlers

Ich befinde mich in einer Situation, in der ich einen binären Suchbaum (BST) innerhalb eines Signalhandlers ( SIGSEGV Signalhandler, der meines Wissens nach pro Thread-Basis ist). Der BST kann von den anderen Threads in der Anwendung geändert werden.

Da ein Signalhandler keine Semaphoren, Mutexe usw. verwenden kann und daher nicht auf freigegebene Daten zugreifen kann, wie kann ich dieses Problem lösen? Beachten Sie, dass meine Anwendung multithreaded ist und auf einem Multicore-System läuft.

4voto

ILYA Khlopotov Punkte 697

Sie sollten nicht auf freigegebene Daten vom Signalhandler aus zugreifen. Weitere Informationen über Signale finden Sie in den folgenden Artikeln:

Linux-Signale für den Anwendungsprogrammierer

Das Modell zur Behandlung von Linux-Signalen

Alles über Linux-Signale

Der sicherste Weg, mit Signalen unter Linux umzugehen, ist bisher signalfd.

4voto

Daper Punkte 41

Ich kann mir zwei ganz klare Lösungen vorstellen:

  1. Linux-spezifisch: Erstellen Sie einen eigenen Thread, der Signale verarbeitet. Fangen Sie Signale mit signalfd() . Auf diese Weise werden Sie Signale in einem regulären Thread und nicht in einem begrenzten Handler behandeln.
  2. Tragbar: Verwenden Sie auch einen eigenen Thread, der schläft, bis ein Signal empfangen wird. Sie können eine Pipe verwenden, um ein Paar von Dateideskriptoren zu erstellen. Der Thread kann aus dem ersten Deskriptor lesen(2) und in einem Signalhandler können Sie in den zweiten Deskriptor schreiben(2). Die Verwendung von write() in einem Signalhandler ist legal gemäß POSIX . Wenn der Thread etwas aus der Pipe liest, weiß er, dass er eine Aktion durchführen muss.

3voto

Scott Hunter Punkte 47233

Angenommen, der SH kann nicht direkt auf die gemeinsam genutzten Daten zugreifen, dann könnten Sie es vielleicht indirekt tun:

  1. Haben Sie eine globale Variable, in die nur Signalhandler schreiben können, die aber von anderen gelesen werden kann (auch wenn nur innerhalb des gleichen Threads).
  2. SH setzt das Flag, wenn es aufgerufen wird
  3. Threads fragen dieses Flag ab, wenn sie nicht gerade dabei sind, das BST zu ändern; wenn sie es gesetzt finden, führen sie die für das ursprüngliche Signal erforderliche Verarbeitung durch (unter Verwendung aller erforderlichen Synchronisierungen) und lösen dann ein anderes Signal (wie SIGUSR1) aus, um anzuzeigen, dass die Verarbeitung abgeschlossen ist
  4. Das SH für DIESES Signal setzt die Flagge zurück

Wenn Sie sich Sorgen über sich überschneidende SIGSEGVs machen, fügen Sie einen Zähler hinzu, um den Überblick zu behalten. (Hey! Du hast gerade deinen eigenen Semaphor gebaut!)

Das schwache Glied ist natürlich die Umfrage, aber es ist ein Anfang.

1voto

Sie könnten Folgendes in Betracht ziehen mmap -ing ein Sicherung Dateisystem (im Benutzerbereich).

Eigentlich werden Sie glücklicher sein, wenn Sie Gnu Hurd die Unterstützung bietet für externe Pager

Und vielleicht könnte Ihr Hack, einen binären Suchbaum in Ihrem Signalhandler zu lesen, in der Praxis oft funktionieren, nicht portabel und auf eine kernelversionsabhängige Weise. Vielleicht ist die Serialisierung des Zugriffs mit nicht portablen Tricks auf niedriger Ebene (z.B. futexes y atomare gcc builtins ) könnte funktionieren. Das Lesen des (maschinenspezifischen) Quellcodes von NPTL, d.h. der aktuellen Linux pthread-Routinen, sollte helfen.

Es könnte der Fall sein, dass pthread_mutex_lock usw. sind tatsächlich aus einem Linux-Signal-Handler heraus verwendbar (weil er wahrscheinlich nur futex und atomare Befehle).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X