#! perl -slw use strict; use threads; use Thread::Queue; use Thread::Semaphore; my $Q = new Thread::Queue; my $boss = async { my %workers; my %sems; while( ) { ( local( $_ ), my $name ) = m[([a-zA-Z])\s*(\d+)?] or next; warn "Non-integer thread '$name'\n" and next if defined $name and $name =~m[\D]; if( m[^w]i ) { warn "You must give a name for the worker\n" and next unless defined $name; warn "Worker $name already exists\n" and next if exists $workers{ $name }; $sems{ $name } = new Thread::Semaphore; $workers{ $name } = threads->create( \&worker, $name, $Q, $sems{ $name } ); next; } warn "Worker $name does not exist\n" and next unless m[^q] or exists $workers{ $name }; m[^k] and $sems{ $name }->up, ## Ensure the worker can respond delete( $workers{ $name } )->kill( 'KILL' )->join and next; if( m[^p] ) { ${ $sems{ $name } } ? $sems{ $name }->down : $sems{ $name }->up; $workers{ $name }->kill( 'STOP' ); next; } m[^s] and $sems{ $name }->up, ## Ensure a paused thread is able to respond $workers{ $name }->kill( 'FPE' ), $sems{ $name }->down ## and set it back and next; m[^q] or next; for( keys %workers ) { $sems{ $_ }->up; $workers{ $_ }->kill( 'KILL' )->join; } $Q->enqueue( undef ); ## Terminate main loop last; } }; print ">$_" while defined( $_ = $Q->dequeue ); $boss->join; exit; sub worker { my( $name, $queue, $sem ) = @_; my $cooldown = 0; my $state = 0; $SIG{KILL} = sub { warn "Worker $name dying\n"; threads->exit(); }; $SIG{STOP} = sub { printf STDERR "Worker $name is %s\n", ( $state ^= 1 ) ? 'paused' : 'resumed'; $sem->down(); $sem->up(); }; $SIG{FPE } = sub { $queue->enqueue("Worker $name has cooldown $cooldown."); }; $queue->enqueue("Worker $name starting"); my %nodes = (); while (1) { $queue->enqueue("$name step $cooldown"); sleep 1; $cooldown++; } } __END__ C:\test>743398.pl w1 >Worker 1 starting >1 step 0 >1 step 1 p1>1 step 2 Worker 1 is paused s1 >Worker 1 has cooldown 2. w2 >Worker 2 starting >2 step 0 >2 step 1 >2 step 2 p>2 step 3 2 Worker 2 is paused s2 >Worker 2 has cooldown 3. k1 >1 step 3 Worker 1 dying q >2 step 4 Worker 2 dying