jackal
jackal

Reputation: 53

perl main program waiting forever

I am relatively new to perl and I have written a program to process same operations on set of OS images. Since the operations were same , I used threads. A scaled down version of the program is attached. The problem is , the main program never comes out and wait for ever . On tracing, I see that the main program is waiting on "tee" command. Anything I have goofed up here ?

I am on CentOS 6.7 with Perl version 5.1 and I cant move forward because of many other dependencies :(

#!/usr/bin/perl -w
use threads;


my $tee_pid= open my $tee, "|-", "tee mylog";
my @images = ( "image1" , "image2");

foreach my $image (@images){
$_ = async { do_ops_on_image() };
sleep ( 60 );
}

while( threads->list ) {
    for my $joinable ( threads->list( threads::joinable ) ) {
        $joinable->join;
    }
}
print "All thread completed \n";
close $tee;

sub do_ops_on_image
{
  my $time = `date`;
  my $id = threads->tid();
  sleep (120) if ( $id ==2 );
  print $tee "my $id started at $time \n";
}

Upvotes: 3

Views: 177

Answers (2)

user149341
user149341

Reputation:

I am relatively new to perl […] I used threads.

This is your problem.

Perl threads are weird. They have a number of unexpected and undesirable behaviors; in particular, most variables cannot safely be shared between threads, and some modules do not support use in a threaded environment at all. To quote the threads documentation:

The "interpreter-based threads" provided by Perl are not the fast, lightweight system for multitasking that one might expect or hope for. Threads are implemented in a way that make them easy to misuse. Few people know how to use them correctly or will be able to provide help.

The use of interpreter-based threads in perl is officially discouraged.

For many common applications, the Parallel::ForkManager module may be a more appropriate choice.

Upvotes: 3

Dave Mitchell
Dave Mitchell

Reputation: 2403

This seems to be a bug in perl that was fixed in version 5.14.0. If you really can't install a newer perl (in addition to the system perl), then try to avoid the $tee shared filehandle, which is what is causing the main thread to hang.

Also, your code to wait for the child threads to finish uses an active CPU loop which will burn lots of CPU. If you just want to wait until all child threads are finished, do something like

my @threads;
...
for ... {
     push @threads, async { ... }
}
...
$_->join for @threads;

Upvotes: 7

Related Questions