Checking thread status

P

programmacist

Hello,

I'm trying to accomplish something that seems, IMHO, like it should be
relatively straightforward, but I can't seem to figure it out. I create
a worker thread that goes off and processes for an extended period of
time. Meanwhile, I would like to continue processing in the main
thread, and periodically check whether the worker thread is finished.
The example below illustrates this:

use threads;

sub work {
print "Worker has started\n";
sleep (3);
die "Worker is finished\n";
}

my $worker = threads->create('work');

while (** worker is not done **) {
print "Main is performing a task\n";
sleep (1);
}

$worker->join();

print "Moving on...\n";

What I can't seem to figure out is how to accomplish the ** worker is
not done ** part.

I have tried using threads->list to see the number of running threads,
but this continues to show the worker, even after it has supposedly
ended.

I have also tried the deprecated Thread module, so I could look at
$worker->done. However, it too, continues to say that the worker is not
done.

I thought about using a shared variable as a flag, but this doesn't
allow for the case of an abnormally terminated worker thread.

One clue I may have is that the output includes the following:

thread failed to start: Worker is finished

when the worker thread dies. I'm wondering why it thinks that the
thread didn't start?

I am using ActiveState perl 5.8.6 on a WindowsXP machine, though I've
also tried it on Windows 2000.

Any help provided would be greatly appreciated!

Cheers,
Ralph
 
T

Tassilo v. Parseval

Also sprach (e-mail address removed):
I'm trying to accomplish something that seems, IMHO, like it should be
relatively straightforward, but I can't seem to figure it out. I create
a worker thread that goes off and processes for an extended period of
time. Meanwhile, I would like to continue processing in the main
thread, and periodically check whether the worker thread is finished.
The example below illustrates this:

use threads;

sub work {
print "Worker has started\n";
sleep (3);
die "Worker is finished\n";
}

my $worker = threads->create('work');

while (** worker is not done **) {
print "Main is performing a task\n";
sleep (1);
}

$worker->join();

print "Moving on...\n";

What I can't seem to figure out is how to accomplish the ** worker is
not done ** part.

I have tried using threads->list to see the number of running threads,
but this continues to show the worker, even after it has supposedly
ended.

I have also tried the deprecated Thread module, so I could look at
$worker->done. However, it too, continues to say that the worker is not
done.

Note what the documention of 'Thread' says on 'done':

done The "done" method returns true if the thread you're
checking has finished, and false otherwise. (Not avail-
able with ithreads.)

Since 'use threads' is using the ithreads-model, you're out of luck.
I thought about using a shared variable as a flag, but this doesn't
allow for the case of an abnormally terminated worker thread.

You can still cover that case by installing a handler for the
pseudosignal __DIE__ in your worker thread:

use threads;
use threads::shared;

my $working : shared;

sub work {
local $SIG{__DIE__} = sub {
print "Abnormal termination: ", shift;
$working = 0;
};
print "Worker has started\n";
sleep (3);
die "died\n" if rand > 0;
$working = 0;
}

$working = 1;
my $worker = threads->create('work');

while ($working) {
print "Main is performing a task\n";
sleep (1);
}

$worker->join();

print "Moving on...\n";

So now your worker thread will set $working to zero even under some
abnormal condition that would have normally caused an imediate death.
One clue I may have is that the output includes the following:

thread failed to start: Worker is finished

when the worker thread dies. I'm wondering why it thinks that the
thread didn't start?

This warning is a little misleading. perldiag says:

thread failed to start: %s
(F) The entry point function of threads->create() failed for
some reason.

'work' is your entry point function and having it die satisfies the
condition for "failed for some reason", I reckon.

Contrary to what perldiag thinks (the (F) indicates it's a fatal
trappable error), this is merely a warning and it can be shut up by
installing a handler for __WARN__.

Tassilo
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top