The following is a simple code example I'm working on. It just starts a thread, wait 5 seconds, and then terminate it.
#!/usr/bin/perl
use strict;
use warnings;
use threads;
sub thread_sub
{
threads->create(sub
{
sleep 5; # HERE A WHILE ROUTINEs EMULATED BY SLEEP
threads->detach();
});
}
thread_sub();
exit;
But the result is:
# ./multithread.pl
Perl exited with active threads:
1 running and unjoined
0 finished and unjoined
0 running and detached
This because it runs the thread but after that exit without waiting.
So, how can I wait for thread to finish before exit? I know there is is_running, but I don't known how to implement it in my code. Obliviously the reported code is just an example to understand how to implement is_running. Thank you.
To wait for a thread to finish, one typically uses the following:
$thread->join();
To wait for all threads, one would therefore use the following:
$_->join() for threads->list();
Don't detach the thread if this is what you are going to do.
About detach...
If you had fire-and-forget threads, you could use
use threads;
use threads::shared;
my $thread_count :shared = 0;
sub thread_sub {
{ lock $thread_count; ++$thread_count; cond_signal($thread_count); }
my $thread = async {
sleep 5;
{ lock $thread_count; --$thread_count; cond_signal($thread_count); }
};
$thread->detach(); # Free the small thread object as soon as it completes.
}
thread_sub();
# When it's time to exit:
{ lock($thread_count); cond_wait($thread_count) while $thread_count != 0; }
But that doesn't gain you much over just joining the threads, which is far simpler.
use threads;
sub thread_sub {
async {
sleep 5;
};
}
thread_sub();
# Periodically:
$_->join() for threads->list(threads::joinable);
# When it's time to exit:
$_->join() for threads->list();
Finally, it's more common in practice to create a pool of threads and reuse them rather then creating threads on the fly because thread creation is expensive in Perl. In this situation, detaching makes even less sense.
use threads;
use Thread::Queue qw( ); # 3.01+
use constant NUM_WORKERS => 3;
sub process_job { sleep 5 }
my $q = Thread::Queue->new();
for (1..NUM_WORKERS) {
async {
while (my $job = $q->dequeue()) {
process_job($job);
}
};
}
$q->enqueue('some_job');
# When it's time to exit:
$q->end();
$_->join() for threads->list();
I haven't used it, but look into Thread::Pool.
By the way, async { ... } is just a cleaner way of saying threads->create(sub { ... }).
Why are you doing this? Detaching a thread means that you don't care about its return or fate; it will finish and exit or be killed as the program is about to exit.
If you want to wait for it don't detach but join.
As for the question of how to use is_running, you need a thread object
use warnings;
use strict;
use feature 'say';
use threads;
$| = 1;
sub thread_sub
{
my $thr = threads->create(sub
{
## threads->detach();
sleep 2; say "\tprocessing ..";
sleep 2; say "\tdone";
});
return $thr;
}
my $thr = thread_sub();
while ($thr->is_running) { # or: while (threads->list)
sleep 1;
say "main";
}
$_->join for threads->list; # instead of detaching
say "done";
Btw, a detached thread is also covered by is_running (or list) and the above works for it as well. But doing that doesn't make sense; I am just discussing the method you ask about.
Related
Feeling stupid somehow as I'm now trying to get a simple interrupt for a thread working in groovy for some hours already.
Somehow following code won't set the 'interrupted' flag in the thread 'name'. Causing the loop to run 'til its end.
Found tons of other questions where usually the check for Thread.currentThread().isInterrupted() was missing. But this is not the case here:
def t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.currentThread().isInterrupted(); ++i) {
println "$i"
sleep 1000
}
} catch (InterruptedException e) {
println "Catched exception"
Thread.currentThread().interrupt();
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
sleep 2000
I get following output
Interrupting thread in 1...
0
Interrupting thread...
1
2
3
4
5
6
7
8
9
Wonder what I miss here / am doing wrong?
Tried also using ExecutorService and calling cancel(true) on the returned Future. Didn't work either.
If you interrupt the thread while sleeping, the sleeping interrupted thread catches the InterruptedException thrown by Thread.sleep and the interrupted status is cleared. So your Thread.currentThread().isInterrupted() always returns false.
You can make your code work if you replace sleep 1000 with Thread.sleep(1000).
TL;DR: Do not use Thread interruption as abort criterion, but use some custom flag instead.
You are not using Thread.sleep() which would throw InterruptedException, but GDKs Object.sleep() which handles and ignores interruptions: http://docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/lang/Object.html#sleep(long)
Either use Thread.sleep() instead like: (interrupting in the catch block is useless in your case)
def t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
println i
Thread.sleep 1000
}
} catch (InterruptedException e) {
println "Catched exception"
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
Or use the variant of Object.sleep() with a Closure and abort your loop in there, e. g. by throwing InterruptedException like:
def t
t = Thread.start('name') {
try {
for (int i = 0; i < 10 && !Thread.interrupted(); ++i) {
println i
sleep(1000) {
throw new InterruptedException()
}
}
} catch (InterruptedException e) {
println "Catched exception"
}
}
println "Interrupting thread in 1..."
sleep 1000
println "Interrupting thread..."
t.interrupt()
Having solved your confusion, now let me advice not to do what you are trying to do. Interrupting is any no way a good method for usage as abort condition. A sleep or blocking IO can always be interrupted due to various reasons. The much better approach is to make your run-loop check some boolean flag that you toggle to abort the work.
In my c++11 project, I need to generate two threads which run infinitely. Here is an example:
static vector<int> vec;
static std::mutex mtx;
static std::condition_variable cond;
static bool done = false;
void f1()
{
while(!done)
{
// do something with vec and mtx
}
}
void f2()
{
while(!done)
{
// do something with vec and mtx
}
}
thread t1(f1);
thread t2(f2);
void finish(int s)
{
done = true;
// what should I do???
}
int main()
{
signal(SIGINT, finish);
t1.join();
t2.join();
return 0;
}
Normally, I won't stop or kill this program. But in case of exception, I think I need to do something for ctrl-c, which is used to kill the program. But I don't know how to quit this program properly.
If I'm right, t1 and t2 might continue executing even if the main has returned 0. So I think I need to make them detach like this:
void finish()
{
done = true;
t1.detach();
t2.detach();
}
However, when I execute the program and do ctrl-c, I get an error:
terminate called after throwing an instance of 'std::system_error'
I've found this link, so I think the problem is the same: mtx and/or cond has been destroyed while t1 or t2 hasn't finished yet.
So how could I kill the program properly? Or I don't need to deal with the signal ctrl-c and the program itself knows what to do to quit properly?
done should be std::atomic<bool>, or unsequenced reads/writes are not legal.
Accessing atomic variables is only safe in a signal handler if std::atomic<bool>::is_lock_free is true. Check that. If it isn't true, your program should probably abort with an error in main.
When you .join(), you wait for the thread to finish executing. And you don't want to exit main unless the threads have finished.
In short, do this:
static std::atomic<bool> done = false;
(rest of code goes here)
int main()
{
if (!done.is_lock_free()) return 10; // error
signal(SIGINT, finish);
t1.join();
t2.join();
}
sub worker {
exit 1;
}
my $thr = threads->create(\&worker);
while ($thr->is_running()) {
print "running\n";
}
my $rc = $thr->join();
exit $rc;
I come from Python. Is there something similar to try/except that I can use around while($thr->is_running)
I get (because I exit 1 in worker):
Perl exited with active threads:
0 running and unjoined
1 finished and unjoined
0 running and detached
I want to be able to catch the exit or other compiliation error worker might have
use strict;
use warnings;
use threads;
sub worker {
my $bad = 1/0;
}
my $thr = threads->create( \&worker );
while ( $thr->is_running() ) {
sleep 1;
}
my $rc = $thr->join(); #NB - RC will be 'undef' because there's no return.
OUTPUT:
Thread 1 terminated abnormally: Illegal division by zero at mythread.pl line 6.
Is it possible to catch it the error? and how and where?
Don't call exit in your thread. That exits your whole program. threads -> exit is what you want.
http://perldoc.perl.org/threads.html#EXITING-A-THREAD
threads->exit()
If needed, a thread can be exited at any time by calling threads->exit() . This will cause the thread to return undef in a scalar context, or the empty list in a list context.
When called from the main thread, this behaves the same as exit(0).
join waits for the thread to complete.
Don't use $a. It's a bad variable name anyway, but it's also used for perl sort.
You're capturing $rc but that implies a return in your thread. As it, it'll be undefined.
But this will work:
use strict;
use warnings;
use threads;
sub worker {
sleep 10;
threads->exit;
}
my $thr = threads->create( \&worker );
while ( $thr->is_running() ) {
print $thr ->tid, " running\n";
sleep 1;
}
print $thr ->tid, " not running\n";
sleep 5;
my $rc = $thr->join(); #NB - RC will be 'undef' because there's no return.
In the latter case, $rc is undef because you exited. You can test for it being undefined if you want to trap an abnormal exit. (Just make sure you do actually return something on a success).
Alternatively, wrap your code in the thread with an eval because that won't be a fatal error. Doesn't come up too often, but I'd suggest rather than trying to capture the broad spectrum of possible fatal errors, you're far better off just testing whether it completed successfully instead.
To answer your second question - something like this:
use strict;
use warnings;
use threads;
sub worker {
sleep 5;
my $fatal = 1 / 0;
return 1;
}
sub otherworker {
sleep 4;
eval { my $fatal = 1 / 0; };
if ($#) { return $# }
else { return "No error" }
}
my $thr = threads->create( \&worker );
my $thr2 = threads->create( \&otherworker );
while ( $thr->is_running() ) {
print $thr ->tid, " running\n";
sleep 1;
}
print $thr ->tid, " not running\n";
foreach my $thread ( threads->list ) {
my $return_code = $thread->join;
if ( not defined $return_code ) {
print $thread ->tid(), ": terminated abnormally\n";
}
else {
print $thread ->tid, ": exited with $return_code \n";
}
}
First of all, this is a follow up to a previous question of mine.
I would like to use threading in Tcl but in collaboration with Itcl.
Here is a sample:
package require Itcl
package require Thread
::itcl::class ThreadTest {
variable thread [thread::create {thread::wait}]
variable isRunning 0
method start {} {
set isRunning 1
thread::send $thread {
proc loop {} {
puts "thread running"
if { $isRunning } {
after 1000 loop
}
}
loop
}
}
method stop {} {
set isRunning 0
}
}
set t [ThreadTest \#auto]
$t start
vwait forever
However, when the condition statement tries to execute and check if the isRunning variable is true, I get a no such variable error. I understand that this is because a proc only has access to the global scope. However, in this situation, I would like to contain the variable local to the class.
Is there a way to accomplish this?
Tcl variables are per-interpreter, and interpreters are strongly bound to single threads (which greatly reduces the number of global-level locks required). To do what you want, you need to use a shared variable. Luckily, support for them is included with the Thread package (documentation here). You might then rewrite your code like this:
package require Itcl
package require Thread
::itcl::class ThreadTest {
variable thread [thread::create {thread::wait}]
constructor {} {
tsv::set isRunning $this 0
}
method start {} {
tsv::set isRunning $this 1
thread::send $thread {
proc loop {handle} {
puts "thread running"
if { [tsv::get isRunning $handle] } {
after 1000 loop $handle
}
}
}
thread::send $thread [list loop $this]
}
method stop {} {
tsv::set isRunning $this 0
}
}
set t [ThreadTest \#auto]
$t start
vwait forever
I'm trying to create a thread and let it run until my main signals it to start, which I think is done with SetEvent. But the code in the thread is never executed. Below is the bare code I have stripped down of (I think) unrelated functions. Is the algorithm correct ?
Here is what I thought it did :
When in the main, the thread is created, which means it'll run in the background. When the event is set (SetEvent), the thread picks it up at WaitForSingleObject and then execute the code in the thread, right ?
HANDLE hThread;
HANDLE Event;
DWORD Thread()
{
while(1)
{
wait = WaitForSingleObject(Event, INFINITE)
//This is where I want to execute something
}
}
int _tmain()
{
DWORD dw;
int i;
Event = CreateEvent(NULL,false,false,NULL);
hThread = CreateThread(NULL,0,Thread,EventA,0,NULL);
while(1)
{
if (condition is correct)
{
SetEvent(Event);
}
CloseHandle(Thread);
CloseHandle(Event);
}
return 0;
}
Thanks for having read.
Move CloseHandle lines out of the while loop.