No actual signals are used here. Signals can only be sent to processes, not threads. From the documentation of $thread->kill :
CAVEAT: The flow signaling capabilities provided by this module do not actually send signals through the OS. It emulates signals at the Perl level so that signal handlers are called in the corresponding thread. For example, sending $thr->kill('STOP') does not actually pause the thread (or the whole process), but calls the calling handler $SIG{'STOP'} in that thread (as shown above).
Since no real signals are used here, you do not mix signals and streams. Good.
But this is too complicated design. Just type $sem->down_force() in pause and $sem->up() in resume . There is no need for this thread.
use strict; use warnings; use threads; use Thread::Semaphore qw( ); { package Worker; sub new { my $class = shift; return bless({ @_ }, $class); } sub thr { return $_[0]{thr} } sub tid { return $_[0]{thr}->tid() } sub join { $_[0]{thr}->join() } sub pause { $_[0]{sem}->down_force() } sub resume { $_[0]{sem}->up() } } sub createThread { my $sem = Thread::Semaphore->new(); my $thr = async { while (1) { $sem->down(); ... $sem->up(); } }; return Worker->new( thr => $thr, sem => $sem ); } sub pause { my ($worker) = @_; $worker->pause(); } sub resume { my ($worker) = @_; $worker->resume(); }
Of course, it is assumed that you want to pause the flow between work units. If you want to immediately suspend a stream, you do not need semaphores or βsignalsβ at all [1] .
use strict; use warnings; use threads; use Thread::Suspend; # Must call import! { package Worker; sub new { my $class = shift; return bless({ @_ }, $class); } sub thr { return $_[0]{thr} } sub tid { return $_[0]{thr}->tid() } sub join { $_[0]{thr}->join() } sub pause { $_[0]{suspended}++ || $_[0]{thr}->suspend() } sub resume { --$_[0]{suspended} || $_[0]{thr}->resume() } } sub createThread { my $thr = async { ... }; return Worker->new( thr => $thr ); } sub pause { my ($worker) = @_; $worker->pause(); } sub resume { my ($worker) = @_; $worker->resume(); }
Bonus: $worker->pause; $worker->pause; $worker->resume; $worker->resume; $worker->pause; $worker->pause; $worker->resume; $worker->resume; works great for both of these methods (unlike the version in question).
If you want to continue using tid instead of an object, just save the object in a hash entered with tid.
- At least not in addition to Thread :: Suspend, which uses a βsignalβ, as well as what makes up the semaphores inside.
ikegami
source share