NAME

Thread::Suspend - suspend and resume threads from another thread

SYNOPSIS

use Thread::Suspend;             # exports all methods
use Thread::Suspend qw(suspend); # only exports suspend()
use Thread::Suspend ();          # threads class methods only

my $thread = threads->new( sub { whatever } );
$thread->suspend;                # suspend thread by object
threads->suspend( $thread );     # also
threads->suspend( $tid );        # suspend by thread ID
threads->suspend;                # suspend all (other) threads

$thread->suspended;              # true if thread is suspended
threads->suspended;              # true if all threads suspended

$thread->resume;                 # resume a single thread
threads->resume;                 # resume all suspended threads

threads->iambusy;                # don't allow suspending in thread
threads->iamdone;                # allow suspending again in thread

use Thread::Exit();
use Thread::Suspend();
$thread->kill;                   # kill thread by object
threads->kill;                   # kill all (other) threads
threads->kill( @thread );        # kill only listed threads

DESCRIPTION

                 *** A note of CAUTION ***

This module only functions on Perl versions 5.8.0 and later.
And then only when threads are enabled with -Dusethreads.  It
is of no use with any version of Perl before 5.8.0 or without
threads enabled.

                 *************************

This module adds the following features to threads that are sorely missed by some: the capability to suspend, to resume and to terminate execution of a thread.

METHODS

These are the methods.

suspend

$thread->suspend;                 # suspend execution of given thread
threads->suspend( $thread );      # same
threads->suspend( $thread->tid ); # same, but specified by thread ID

threads->suspend;                 # suspend all other threads

The "suspend" method allows you to suspend the execution of one or more threads. It accepts one or more thread objects or thread ID's (as obtained by the threads::tid() method).

If called as a class method or as a subroutine without parameters, then it will suspend all running threads but the current thread. This can only be done if Thread::Running has been loaded prior to loading Thread::Suspend. If this was not done, then calling "suspend" as a class method without parameters will die.

If called as an instance method without parameters, it will only check the thread associated with the object.

In list context it returns the thread ID's of the threads that have been to to suspend. In scalar context, it returns 1 or 0 to indicate whether all of the specified threads have been told to suspend.

You can call the suspended method to find out which threads are actually suspended.

resume

$thread->resume;                # resume execution of this thread
threads->resume( $thread );     # same
threads->resome( $thread->tid); # same

threads->resume;                # resume all threads that were suspended

The "resume" method allows you to resume execution of one or more threads that were previously suspended. It accepts one or more thread objects or thread ID's (as obtained by the threads::tid() method).

If called as a class method or as a subroutine without parameters, then it will check all threads of which it knows. If called as an instance method without parameters, it will only check the thread associated with the object.

In list context it returns thread id's of the threads that have been told to resume execution. In scalar context, it just returns 1 or 0 to indicate whether all of the (implicitely) indicated threads were told to resume execution.

suspended

$thread->suspended;                # true if thread is suspended
threads->suspended( $thread );     # same
threads->suspended( $thread->tid); # same

threads->suspended;                # true if all other threads suspended
threads->suspended( @tid );        # true if given threads suspended

The "suspended" method allows you to check whether one or more threads are actually suspended. It accepts one or more thread objects or thread ID's (as obtained by the threads::tid() method).

If called as a class method or as a subroutine without parameters, then it will check all threads of which it knows. If called as an instance method without parameters, it will only check the thread associated with the object.

In list context it returns thread id's of the threads that are actually suspended. In scalar context, it just returns 1 or 0 to indicate whether all of the (implicitely) indicated threads are suspended.

iambusy

threads->iambusy;         # don't allow suspending right now
iambusy();                # same

Sometimes you don't want certain sections of your code in a thread to be interrupted. The "iambusy" method can be called to indicate such a section. It can either be called as a class method or a subroutine (if exported).

Call the iamdone method to mark that the execution of the thread may be suspended again from other threads. Nested calls to "iambusy" are allowed. Only when each call to "iambusy" has been counteracted by a call to "iamdone" is suspending of the current thread allowed again.

Please note that if you call the "iambusy" method at the beginning of the execution of a thread, and never call the "iamdone" method in that thread, then that thread will never get suspended, but it may get killed.

iamdone

threads->iamdone;         # allow suspending again in principle
iamdone();                # same

The "iamdone" method can be called to indicate that the current thread may be suspended again from another thread. It is the opposite of iambusy. Please note that the number of "iamdone" method calls should counteract the number of nested "iambusy" calls to really allow suspending of the current thread again.

If suspending of the thread is allowed again, then immediate suspending of the thread will occur if another thread asked for suspending of the current thread while the current thread was busy.

kill

$thread->kill;            # kill only this thread
kill( $thread );          # same

threads->kill( @tid );    # kill all threads indicated by thread ID's
threads->kill;            # kill all running threads

                 *** A note of CAUTION ***

The C<kill()> method/subroutine can only work if the Thread::Exit module
has been loaded B<before> the Thread::Suspend module is loaded.
Therefore, calling the C<kill()> method/subroutine will B<die> when
called if Thread::Exit had not been loaded before Thread::Suspend was
loaded.

                 *************************

The "kill" method allows you to stop execution of one or more threads. It accepts one or more thread objects or thread ID's (as obtained by the threads::tid() method).

If called as a class method or as a subroutine without parameters, then it will kill all running threads but the current thread. This can only be done if Thread::Running has been loaded prior to loading Thread::Suspend. If this was not done, then calling "kill" as a class method without parameters will die.

If called as an instance method without parameters, it will only check the thread associated with the object.

In list context it returns the thread ID's of the threads that have been attempted to be killed. In scalar context, it returns 1 or 0 to indicate whether all of the specified threads have been attempted to be killed.

You can call Thread::Running's running method to find out which threads are actually running.

REQUIRED MODULES

load (any)
Thread::Signal (0.07)

CAVEATS

This module is dependent on the Thread::Signal module, with all of its CAVEATS applicable. However, if you are using the iambusy and iamdone methods to mark critical sections in your threaded code, this has the side-effect of not having to have working signals on your system. This is caused by the fact that iamdone checks the "suspended" flag without having received a signal.

This module uses the load module to make sure that subroutines are loaded only when they are needed.

The dependencies on Thread::Running and Thread::Exit are made conditional in such a way that they will not use any more memory (which is very important when using threads) then necessary. Unfortunately, these modules can not be loaded on demand, as they alter subtle characteristics of the environment at compile time, on which Thread::Suspend must be able to depend to act as expected. So there is no easy way around this seemingly awkward situation.

WHY NOT USE "SIGSTOP" AND "SIGCONT"?

Many operating systems already support the signals SIGSTOP (for halting execution of a process) and SIGCONT (for continuing execution of a process). The reason I've decided not to use that, is that in that way, execution may be halted in critical sections of Perl. This seemed like a Very Bad Idea(tm). Therefore a more general approach involving locking on a shared array, was chosen.

TODO

Examples should be added.

AUTHOR

Elizabeth Mattijsen, <liz@dijkmat.nl>.

Please report bugs to <perlbugs@dijkmat.nl>.

COPYRIGHT

Copyright (c) 2003 Elizabeth Mattijsen <liz@dijkmat.nl>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

SEE ALSO

threads, Thread::Signal, Thread::Running, Thread::Exit, load.