9 Stimmen

Segmentierungsfehler verursacht durch pthread_kill

GDB sagt mir, dass pthread_kill verursacht einen Segmentierungsfehler in meinem Programm. Im Grunde genommen verwende ich pthread_kill um zu prüfen, ob ein Thread aufgrund seiner ID aktiv ist oder nicht.

Ich habe im Internet recherchiert und festgestellt, dass es daran liegen könnte pthread_kill verursacht einen Segmentierungsfehler, wenn die TID ungültig ist. Ja, ich habe mein Programm mit "ungültigen" (von mir erfundenen) TIDs des Typs int . Könnte das die wahre Ursache sein?

0 Stimmen

Welche "ungültigen" Werte verwenden Sie?

0 Stimmen

Da pthread_t ein undurchsichtiger Typ ist, könnte die Verwendung einer Ganzzahl (wie 1001) theoretisch zu Problemen und einem nachfolgenden Absturz führen. Erhalten Sie beim Kompilieren mit -Wall irgendwelche Warnungen?

0 Stimmen

Haben Sie das Programm unter valgrind laufen lassen?

16voto

bdonlan Punkte 213545

pthread_t ist weder eine Thread-ID noch ein numerischer Index. Es ist ein undurchsichtiger Typ. Das Erfinden von Werten kann zu einem Absturz führen.

Unter Linux NPTL wird pthread_t als Zeiger verwendet:

int
__pthread_kill (threadid, signo)
     pthread_t threadid;
     int signo;
{
  struct pthread *pd = (struct pthread *) threadid;

Es sollte schon ziemlich klar sein, wo die Dinge schief laufen :) Die ältere Linuxthreads-Implementierung verwendete numerische Indizes in einer Tabelle, und dort konnte man tatsächlich TIDs erfinden, ohne einen Absturz zu erwarten.

Sie müssen das Thema Leben und Tod selbst verfolgen. A pthread_t ist gültig, bis Sie die pthread_join erfolgreich zu verwenden. Wenn Sie testen möchten, ob ein gültig pthread_t lebendig ist, rufen Sie pthread_tryjoin_np auf ihn; wenn er EBUSY ist der Thread aktiv. Wenn die Funktion erfolgreich ist, _die pthread_t ist nicht mehr gültig_ Sie müssen also irgendwo vermerken, dass dieser Thread jetzt tot ist und nicht mehr überprüft zu werden braucht!

Sie könnten natürlich auch Ihr eigenes Verfolgungssystem implementieren - erstellen Sie irgendwo eine Tabelle für das Vorhandensein von TIDs, ein System für die Vergabe von TIDs und die Weitergabe an neu erstellte Threads. Jeder Thread sollte sich selbst als tot markieren, bevor er beendet wird (vielleicht mit pthread_cleanup_push damit Sie den Threadabbruch und die pthread_exit ), und lösen Sie den Faden ab, damit Sie ihn nicht verbinden müssen (mit pthread_detach ). Jetzt haben Sie die explizite Kontrolle über Ihre Thread-Death-Meldungen.

1 Stimmen

Die Manpage für pthread_kill sagt, dass Sie Folgendes verwenden können pthread_kill(t, 0) auf das Vorhandensein von t zu prüfen, was bedeutet, dass der Aufruf mit ungültigen pthread_t-Werten erfolgen kann. Ist die Manpage falsch?

1 Stimmen

@Brandon sehen sourceware.org/bugzilla/show_bug.cgi?id=4509 y udrepper.livejournal.com/16844.html . dreppers Argument scheint ziemlich intellektuell faul zu sein, aber es scheint, dass es keine Absicht gibt, pthread_kill bei ungültigen TIDs in der Glibc zu unterstützen, so dass der Ansatz, pthread_kill zu verwenden, um auf die Existenz des Threads zu testen, nicht funktioniert

0 Stimmen

POSIX ist sehr eindeutig, dass die Verwendung einer pthread_t nach seiner Lebensdauer UB ist, und POSIX 2008 (entweder das Original oder das erste TC, ich habe es vergessen) hat dies weiter verdeutlicht, indem es die falschen "may fail"-Fehler entfernt hat. Außerdem beabsichtigen zukünftige Ausgaben von POSIX, Folgendes zu verbieten ESRCH als Fehler für Threads, die zwar beendet, aber noch nicht verbunden wurden.

2voto

Joshua Clayton Punkte 1597

Um diese Einschränkung in meinem Code zu umgehen, setze ich die TID auf Null, wenn der Code nicht ausgeführt wird

memset(&thread, '\0', sizeof(pthread_t)); 

... und vor dem Aufruf von pthread_kill auf Null prüfen

//this code will run if thread is not valid
if (!thread || ESRCH == pthread_kill(thread, 0)) {
    //do stuff and create the thread
}

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