Sterling has too many projects

Blogging about Raku programming, microcontrollers & electronics, 3D printing, and whatever else...

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.


  1. 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.  ↩