Perl setzt einen Thread fort

8

Ich versuche einen Thread zu starten, den ich jederzeit unterbrechen / fortsetzen könnte. Hier ist wie ich den Thread erstellen:

%Vor%

Nach dem Abrufen der Thread-ID (mit return $thr->tid(); ). Dann versuche ich es zu pausieren und die Nachricht sig stop wird gedruckt und später, wenn ich versuche, es fortzusetzen sig cont wird nicht gedruckt. Hier ist der Code, der den Thread aussetzt / wieder aufnimmt:

%Vor%

Nachdem ich einen unterbrochenen Thread fortgesetzt habe, ist die Nachricht Operation X was resumed aber sig cont nicht vorhanden und die Thread-Funktion wird ebenfalls nicht fortgesetzt.

    
bob_saginowski 27.07.2016, 11:22
quelle

2 Antworten

5

Es ist unklar, ob Sie Thread::Semaphore für einen separaten Zweck benötigen, aber es ist nicht für das Funktionieren von Thread::Suspend

Ich vermute, der Grund dafür, dass Ihr Suspend / Resume nicht funktioniert, ist, dass Sie den Signalhandler überschrieben haben, den Thread::Suspend für seine eigenen Zwecke eingerichtet hat

Wenn ich alle Signalhandler und den Thread::Semaphore Kram entferne, funktioniert dein Code gut:

%Vor%

Ausgabe

%Vor%


Aktualisieren

Es gibt auch keinen wirklichen Bedarf für Ihre Subroutinen. Hier ist eine nackte Implementierung

%Vor%

Ausgabe

%Vor%     
Borodin 27.07.2016, 15:28
quelle
4

Hier werden keine tatsächlichen Signale verwendet. Signale können nur an Prozesse gesendet werden, nicht an Threads. Aus der Dokumentation von $thread->kill :

  

CAVEAT: Die Thread-Signalisierungsfähigkeit, die von diesem Modul bereitgestellt wird, sendet tatsächlich keine Signale über das OS. Es emuliert Signale auf der Perl-Ebene, so dass Signalhandler im entsprechenden Thread aufgerufen werden. Wenn Sie beispielsweise $thr->kill('STOP') senden, wird ein Thread (oder der gesamte Prozess) tatsächlich nicht angehalten, aber in diesem Thread wird ein $SIG{'STOP'} -Handler aufgerufen (wie oben dargestellt).

Da hier keine echten Signale verwendet werden, mischen Sie keine Signale und Threads. Gut.

Aber es ist ein übermäßig kompliziertes Design. Rufen Sie einfach $sem->down_force() in pause und $sem->up() in resume auf. Das muss im Thread nicht passieren.

%Vor%

Das setzt natürlich voraus, dass Sie nur den Thread zwischen Arbeitseinheiten anhalten möchten. Wenn Sie den Thread sofort anhalten möchten, brauchen Sie überhaupt keine Semaphore oder "Signale".

%Vor%

Bonus: $worker->pause; $worker->pause; $worker->resume; $worker->resume; funktioniert für beide Methoden (im Gegensatz zur Version in der Frage).

Wenn Sie weiterhin mit einem tid anstelle eines Objekts arbeiten möchten, speichern Sie das Objekt einfach in einem Hash, der mit tid getastet wird.

  1. Zumindest nicht zusätzlich zu Thread :: Suspend, welches ein "Signal" verwendet und was intern zu Semaphoren führt.
ikegami 27.07.2016 15:32
quelle

Tags und Links