Is there a way to stop the first thread from exiting until all the other threads are finsished?
In the main thread, do something like:
$_->join for threads->list;
although that could interfere with the threads being created in runSeries (I don't understand why you create a new thread there), in which case do this instead:
my @threads;
foreach $host (@syshost)
{
push @threads, threads->new(\&runSeries, $host);
}
$_->join for @threads;
Dave. | [reply] [d/l] [select] |
Thanks Dave.
I'm still very noobish to Perl, so I have a question on your response.
the $_->join for threads->list, what does this do.
The problem we are having, is that are services have a delay in their response time, being that our farthest host is between 200-400 miles from our distribution. Is this command going to keep the threads alive until a response if found?
The reason for the multi threads is that the main thread, launches a method that is launching other threads to search for all of the servies on each host.
So,
foreach $host(@syshosts)
{
@sysThread = threads->new( \&findHostNodes, $host );
}
sub findHostNodes
{
my $host = @_;
#print some stuff about the node
#now find the services on the host
foreach $service (@r21services)
{
@serviceThread = threads->new(\@shutdonwServices,
$service);
}
}
sub shutdownServices
{
shut down the windows services we are looking for
}
From you response, in your opinion, what is the better method?
Thanks,
Jeff
| [reply] [d/l] |
$_->join for threads->list, what does this do.
It simply waits for, and then joins, any remaining threads.
Your problem is simply to ensure that the main process doesn't exit until all threads have been joined. My example is just a simple way to ensure that all remaining threads have been joined.
Please bear in mind that threads in perl are extremely expensive to create and consume a lot of memory, so I suspect that creating new threads in findHostNodes is a bad idea.
Dave.
| [reply] |
This example might show you a way. One thing you might be missing is that the thread must reach the end of it's code block, or return, before it can be joined. So I usually use a shared var 'die' to signal a thread to return immediately. That way, if you want to exit without all those warnings, you set the 'die' = 1 for each thread, then join them after they have returned.In the following example, I join them as they finish, but you can easily hold them in an unjoined condition, until all threads are done. I don't know why you would want that, but it would be easy to do.
#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;
$| = 1;
my %threads;
foreach (1..10){
share $threads{$_}{'die'};
share $threads{$_}{'data'};
$threads{$_}{'die'} = 0;
$threads{$_}{'data'} = 0;
}
foreach (1..10) {
$threads{$_}{'thread'} = threads->new('StartTest');
}
my @threads = (1..10);
while(1){
foreach my $t (@threads){
if($threads{$t}{'data'} > 5){
$threads{$t}{'die'} = 1;
$threads{$t}{'thread'}->join;
@threads = grep { $_ != $t } @threads;
}
}
if(scalar @threads == 0){last}
}
print "\n", "All threads done\n";
##########################################################
sub StartTest {
my $self = threads->self;
print "Thread ", $self->tid, " started\n";
while(1){
if( $threads{$_}{'die'} == 1){return}
else{
print "From thread $self->",$threads{$_}{'data'}++,"\n";
sleep 1;
};
}
print "Thread ", $self->tid, " ending\n";
}
I'm not really a human, but I play one on earth.
flash japh
| [reply] [d/l] |