han_perl has asked for the wisdom of the Perl Monks concerning the following question:

Is there any what to destroy a thread that hasn't finished yet?

For Example:
xc() is just a telnet function wrapper.
$cmd = "Some Never ending command";
$caTv = threads->create(\&xc, $cmd );

Now I want to somehow kill this thread. How would I do this?

Thanks.

Replies are listed 'Best First'.
Re: How to forcefully destroy a thread
by BrowserUk (Patriarch) on Aug 11, 2004 at 03:09 UTC

    Unfortunately, the threds api does not provide for this currently and using the normal eval/alarm method doesn't seem to co-exists well with threads.

    However, if you are on Win32, I do know of a very dirty way to do this, but it could leave perl in a unpredictable state.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    "Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon
Re: How to forcefully destroy a thread
by ikegami (Patriarch) on Aug 11, 2004 at 05:14 UTC
    I don't know much about multithreading in perl, so speaking generically, forcefully destroying threads tend to have unpredictable side effects. For example, they removed the ability to forcefully kill threads from the Java language/API. Would it be possible to run xc() as a seperate process (via forking, pipes) instead of running it as a seperate thread?
Re: How to forcefully destroy a thread
by zentara (Cardinal) on Aug 11, 2004 at 13:40 UTC
    Just hazarding a guess to what approach I would try, if posed with the problem.

    $threads->join will wait for the thread to finish and then rejoin the parent. So you will have to signal the thread somehow, to tell it to return early. So broadcast some variable, and have the thread periodically test it, and if there, the thread will immediately return. Here is some code posted awhile back by another monk which demonstrates the idea.

    #!/usr/bin/perl -w use threads; use threads::shared; my $status : shared; my $thr_work = threads->create( sub { # do some work. lock $status; return if $status; $status = "done"; cond_signal $status; return @whatever; } ); threads->create( sub { sleep 300; lock $status; return if $status; $status = "timed_out"; cond_signal $status; } )->detach; { lock $status; cond_wait $status until $status; if ( $status eq "done" ) { my @results = $thr_work->join; # process @results. } else { print "Timed out\n"; $thr_work->detatch; } }
    or you can work up your own method. Just use the cond_broadcast to share variables between threads. A super simple demo:
    #!/usr/bin/perl use threads; use threads::shared; use strict; our $a:shared = 1; print "main start->$a\n"; threads->create(\&display); threads->create(\&display1); print "hit enter to finish\n"; <STDIN>; #pauses for keypress print "main done-> $a\n"; sub display { our $a = 2; $a++; print "from t1->$a\n"; } sub display1 { our $a = 99; print "front2->$a\n"; $a++; lock $a; cond_broadcast($a); }

    I'm not really a human, but I play one on earth. flash japh
Re: How to forcefully destroy a thread
by Anonymous Monk on Aug 11, 2004 at 05:43 UTC
    I am looking for the same answer you are. I am running the code on Win32 (Perl 5.8.4). This is my code:
    my @threads; foreach my $suite (@suite) { push @threads, Thread->new(\&runThread, $suite); } foreach my $t (@threads) { push @outputLog, @{$t->join}; } sub runThread { my $self = Thread->self; logInfo("Thread #", $self->tid, " (@_) started..."); my @output = qx{start JVM instance here}; checkExitValue(); return \@output; }
    I had no luck prematurely terminating a thread, and if i kill the program, the threads (JVM instances) are still running utilizing my CPU by 100%. In Programming Perl edition 3 in a Thread Model chapter, they say a way to terminate a thread would be by calling a return in a top-level function, but it didnt quite work for me. I am still struggling. Anyone? Thanks.
        All the threads inside a single process has the same PID. So it will not work.

        -DBC
Re: How to forcefully destroy a thread
by TZapper (Acolyte) on Aug 12, 2004 at 09:00 UTC
    Note that the old threading model (5005threads) does not or has bad support for shared variables between threads. Since 5.8.4 is in use on Win32, the new model (ithreads) is readily available for you. It has backwards compatibility with the old model; the Thread module has been reworked to function as a frontend for both the old and the new model. But its not complete, because the data sharing models are directly opposed, anything to do with data sharing has to be thought differently (from ActiveState ASPN).
    use threads;
    and when creating the thread, use
    ... threads->new(/&runThread, $suite);
    instead of
    ... Thread->new(/&runThread, $suite)