Standard library · Time and concurrency

thread

Holding and waiting for the threads that spawn creates.

import thread
On this page
  1. Types
  2. Functions

In Salam you start a function that should run alongside the rest of the program with spawn. It takes a function with no parameters and no result and gives back a number, the thread's handle. join, or thread.Join, waits for that thread to finish.

The thread package wraps that handle in a Thread so you can keep several of them in a vector and wait for all of them at once. Threads share the program's globals; for shared data use sync or atomic.

Types

Thread

struct Thread
A thread, running or finished.
NameTypeDescription
handlei64 = 0The handle spawn returned; zero means invalid.
thread-Join.salam
import thread
import sync

mut total := 0
mut lock := sync.Mutex {}

func worker():
    repeat 1000:
        sync.Lock(lock)
        total += 1
        sync.Unlock(lock)
    end
end

func main:
    lock = sync.NewMutex()
    first := thread.New(spawn(worker))
    println thread.Valid(first), thread.Handle(first) != 0
    mut group := Vector {} as Vector<thread.Thread>
    defer group.free()
    repeat 3:
        group = thread.Collect(group, spawn(worker))
    end
    thread.Join(first)
    thread.JoinAll(group)
    println group.len(), total
    empty := thread.New(0)
    println thread.Valid(empty), empty.handle
    thread.Join(empty)
    sync.Destroy(lock)
end
Outputtrue true 3 4000 false 0

Functions

New

func New(h: i64): Thread
Wraps a spawn handle in a Thread.

The example for this item is shown with the ones above: thread-Join.salam

SpawnStack

func SpawnStack(fn: i64, arg: void*, stack: u64): Thread
Starts a function on a new thread with a stack of the size you give, in bytes, for work that needs more than the default, such as deep recursion. The function takes a void* and returns nothing. If the system cannot give that stack it returns an invalid handle, so check with Valid.
thread-SpawnStack.salam
import thread

mut total := 0 as i64

func count(n: i64): i64:
    if n <= 0:
        ret 0
    end
    ret 1 + count(n - 1)
end

func work(_arg: void*):
    total = count(200000)
end

func main:
    stack := (64 * 1024 * 1024) as u64
    t := thread.SpawnStack(work, null, stack)
    println thread.Valid(t)
    thread.Join(t)
    println total
end
Outputtrue 200000

Join

func Join(t: Thread)
Waits for the thread to finish. It does nothing for an invalid thread.

The example for this item is shown with the ones above: thread-Join.salam

JoinAll

func JoinAll(threads: Vector<Thread>)
Waits for every thread in a vector to finish.

The example for this item is shown with the ones above: thread-Join.salam

Valid

func Valid(t: Thread): bool
True when the handle is not zero.

The example for this item is shown with the ones above: thread-Join.salam

Handle

func Handle(t: Thread): i64
The thread's handle.

The example for this item is shown with the ones above: thread-Join.salam

Collect

func Collect(threads: Vector<Thread>, h: i64): Vector<Thread>
Adds a new thread with this handle to a vector and returns the vector.

The example for this item is shown with the ones above: thread-Join.salam