tid. magic
1 0 Worker 1 first job in while loop
1 1 Worker 1 first job in do_work
2 0 Worker 2 first job in while loop
2 1 Worker 2 first job in do_work
1 0 Worker 1 second job in while loop
1 1 Worker 1 second job in do_work
2 0 Worker 2 second job in while loop
2 1 Worker 2 second job in do_work
1 -1 Worker 1 after exiting while loop
2 -1 Worker 2 after exiting while loop
####
tid. magic
1 0 Worker 1 first job in while loop
1 1 Worker 1 first job in do_work
1 0 Worker 1 second job in while loop
1 1 Worker 1 second job in do_work
1 -1 Worker 1 after exiting while loop
2 0 Worker 2 first job in while loop
2 1 Worker 2 first job in do_work
2 0 Worker 2 second job in while loop
2 1 Worker 2 second job in do_work
2 -1 Worker 2 after exiting while loop
####
tid. magic
2 0 Worker 2 first job in while loop
2 1 Worker 2 first job in do_work
2 0 Worker 2 second job in while loop
2 1 Worker 2 second job in do_work
2 -1 Worker 2 after exiting while loop
1 0 Worker 1 first job in while loop
1 1 Worker 1 first job in do_work
1 0 Worker 1 second job in while loop
1 1 Worker 1 second job in do_work
1 -1 Worker 1 after exiting while loop
####
my $semSTDOUT : shared;
sub tprint{ lock $semSTDOUT; print @_; }
tprint "$tid: Some text";
####
sub run_external_command {
my ( $job, $tid ) = @_;
$q_PRINT->enqueue( "Thread $tid is running exteral job $job" );
local( *w_IN, *w_OUT, *w_ERR );
my $pid = open3( \*w_IN, \*w_OUT, \*w_ERR, '/bin/sleep', int( rand($DEFAULTS->{'random'} ) ) );
waitpid( $pid, 0 );
return $DEFAULTS->{'ret_success'};
}
####
#! perl -slw
use strict;
use threads;
use threads::shared;
use Thread::Queue;
use constant {
RANDOM => 4,
THREADS => 4,
JOBS => 20,
};
my $semSTD :shared;
sub tprint {
my $tid = threads->tid;
lock $semSTD;
print "[$tid] ", @_;
}
my $die_early :shared = 0;
$SIG{ INT } = sub {
tprint "Early termination requested";
$die_early = 1;
};
sub worker {
tprint "worker started";
my( $Q ) = @_;
while( !$die_early and defined( my $job = $Q->dequeue ) ) {
tprint "processing job:$job";
my $pid = open my $PIPE, '-|', "sleep " . int( rand RANDOM ) or die $!;
tprint "waiting for pid: $pid";
waitpid $pid, 0;
tprint "pid: $pid done";
}
tprint "Worker ending";
return 1;
}
my $Q = new Thread::Queue;
$Q->enqueue( map "JOB-$_", 1 .. JOBS );
$Q->enqueue( (undef) x THREADS );
tprint "Queue populated";
my @threads = map threads->new( \&worker, $Q ), 1 .. THREADS;
tprint "Workers started; waiting...";
$_->join for @threads;
print "Program complete";
__END__
C:\test>881217
[0] Queue populated
[1] worker started
[1] processing job:JOB-1
[1] waiting for pid: 1740
[2] worker started
[2] processing job:JOB-2
[1] waiting for pid: 1056
[2] pid: 2684 done
[2] processing job:JOB-4
[1] waiting for pid: 2116
[3] worker started
[3] processing job:JOB-6
[3] waiting for pid: 3244
[0] Workers started; waiting...
[4] worker started
[4] processing job:JOB-7
...
[3] pid: 1112 done
[3] processing job:JOB-20
[3] waiting for pid: 4048
[2] pid: 1728 done
[1] pid: 3432 done
[2] Worker ending
[1] Worker ending
[4] pid: 3924 done
[4] Worker ending
[3] pid: 4048 done
[3] Worker ending
Program complete