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:
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.
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:
Es gibt auch keinen wirklichen Bedarf für Ihre Subroutinen. Hier ist eine nackte Implementierung
%Vor% 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.
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.
Tags und Links multithreading perl