Threads
Warning! We are delving into the inner depths of Raku now. Threads are a
low-level API and should be avoided by almost all applications. However, if
your particular application needs direct
Thread
access, it is here for
you.1
Use of the Thread
class in Raku is straight-forward and looks very similar to
what you would expect if you are familiar with threading tools in other
languages:
my $t = Thread.start:
name => 'Background task',
:app_lifetime,
sub {
if rand > 0.5 { say 'weeble' }
else { say 'wobble' }
},
;
say "Starting $t.id(): $t.name()";
say "Main App Thread is $*THREAD.id(): $*THREAD.name()";
$t.finish; # wait for the thread to stop
Give the Thread.start
method some code to run and you’re off. The name
and
app_lifetime
options are optional. If app_lifetime
is False
(which is the
default), the thread will be terminated when the main application thread
terminates. If set to True
, the application will continue to run as long as
this thread is running. Under normal circumstances, only the main thread of your
application has this privilege.
All code, runs within a thread. Your code can access the thread it is running
in using the dynamic variable named $*THREAD
. This can be helpful for pulling
the .id
when debugging to help understand which thread a task is running in at
the moment.
When you want to pause the current thread to wait for another thread to finish,
you do that with the .finish
method (or you can use .join
, which is a
synonym for .finish
).
Another way to run a thread is to use a combination of .new
and .run
. This
is similar to .start
, but code must be passed as a named argument to .new
:
my $t2 = Thread.new:
name => 'Another task',
code => sub {
loop {
say 'stuff';
sleep 1;
}
},
;
# The thread does not start until we...
$t2.run;
# And then we'd better wait for it or we'll exit immediately
$t2.finish;
For the most part, I make mention of threads in the advent calendar as a way of
describing the “lanes” in which code runs. However, I will make use
$*THREAD.id
from time to time to help illustrate that code does run in
different threads. Otherwise, I will generally ignore the Thread
object
directly.
Almost all Raku programs should stick to using start
blocks or Promise.start
to start tasks to run on another thread. You should only make use of Thread
directly if you really need it, which is probably never or close to it for most
Raku developers.
Cheers.
-
As a point of clarification, a
Thread
object does not necessarily represent a specific OS thread, but it should get you as close as the implementation is able. ↩︎