I currently have a script that runs threads to perform various actions in multiple directories. A snippet of my script:
sub BuildInit {
my $actionStr = "";
my $compStr = "";
my @component_dirs;
my @compToBeBuilt;
foreach my $comp (@compList) {
@component_dirs = GetDirs($comp);
}
print "Printing Action List: @actionList\n";
for ( 1 .. NUM_WORKERS ) {
async {
while ( defined( my $job = $q->dequeue() ) ) {
worker($job);
}
};
}
for my $action (@actionList) {
my $sem = Thread::Semaphore->new(0);
$q->enqueue( [ $_, $action, $sem ] ) for @component_dirs;
$sem->down( scalar @component_dirs );
print "\n------>> Waiting for prior actions to finish up... <<------\n";
}
$q->end();
$_->join() for threads->list();
return 0;
}
sub worker {
my ($job) = @_;
my ( $component, $action, $sem ) = @$job;
Build( $component, $action );
$sem->up();
}
sub Build {
my ( $comp, $action ) = @_;
my $cmd = "$MAKE $MAKE_INVOCATION_PATH/$comp ";
my $retCode = -1;
given ($action) {
when ("depend") { $cmd .= "$action >nul 2>&1" }
when ("clean") { $cmd .= $action }
when ("build") { $cmd .= 'l1' }
when ("link") { $cmd .= '' }
default { die "Action: $action is unknown to me." }
}
print "\n\t\t*** Performing Action: \'$cmd\' on $comp ***" if $verbose;
if ( $action eq "link" ) {
my $tries = 1;
until ( $retCode == 0 or $tries == 0 ) {
last if ( $retCode = system($cmd) ) == 2;
$tries--;
}
}
else {
$retCode = system($cmd);
}
push( @retCodes, ( $retCode >> 8 ) );
if ( $retCode != 0 ) {
print "\n\t\t*** ERROR IN $comp: $@ !! ***\n";
print "\t\t*** Action: $cmd -->> Error Level: " . ( $retCode >> 8 ) . "\n";
}
return $retCode;
}
An operator printthat I would like to be thread safe: print "\n\t\t*** Performing Action: \'$cmd\' on $comp ***" if $verbose;Ideally, I would like to get this output, and then every component that has $actionone executed on it will output to related pieces. However, this obviously does not work right now - the output alternates for the most part, with each stream splashing out its own information.
eg,:.
ComponentAFile1.cpp
ComponentAFile2.cpp
ComponentAFile3.cpp
ComponentBFile1.cpp
ComponentCFile1.cpp
ComponentBFile2.cpp
ComponentCFile2.cpp
ComponentCFile3.cpp
... etc.
- , , . : (a) , () stderr.
- ?
:
:
ComponentAFile1.cpp
ComponentAFile2.cpp
ComponentAFile3.cpp
------------------- #some separator
ComponentBFile1.cpp
ComponentBFile2.cpp
------------------- #some separator
ComponentCFile1.cpp
ComponentCFile2.cpp
ComponentCFile3.cpp
... etc.