SynchronizationAndThreadAPI - leftmike/foment GitHub Wiki

(import (foment base)) to use these procedures.

Threads

procedure: (current-thread)

Returns the current thread.

procedure: (thread? obj)

Returns #t if obj is a thread, otherwise returns #f.

procedure: (run-thread thunk)

A new thread will be returned. The new thread will execute thunk which is a procedure taking no arguments.

procedure: (exit-thread obj)

Runs all outstanding dynamic-wind after procedures for the current thread. If the current thread is the only thread, then the running program is terminated. Otherwise, only the current thread is terminated.

procedure: (emergency-exit-thread obj)

Terminate the current thread.

procedure: (sleep k)

Sleep for k milliseconds.

Exclusives

procedure: (exclusive? obj)

Returns #t if obj is an exclusive, otherwise returns #f.

procedure: (make-exclusive)

Returns a new exclusive.

procedure: (enter-exclusive exclusive)

Wait, if necessary, until the exclusive is available, and then enter it. Only a single thread at a time may enter the exclusive. The wait for the exclusive could be potentially indefinate.

Exclusives may be entered recursively. For the exclusive to become available, leave-exclusive must be called once for ever call to enter-exclusive.

procedure: (leave-exclusive exclusive)

Leave the exclusive and make it available. Another thread may enter it.

procedure: (try-exclusive exclusive)

Attempt to enter the exclusive without waiting. If the exclusive is entered return #t, otherwise return #f.

syntax: (with-exclusive exclusive expr1 expr2 ...)

Enter the exclusive, evaluate the expressions expr1 expr2 ..., and leave the exclusive. The exclusive will be entered when the execution of the expressions begin and when a capture continuation is invoked. The exclusive will be left whether the expressions return normally or by an exception being raised or by a capture continuation being invoked.

Conditions

procedure: (condition? obj)

Returns #t if obj is an condition, otherwise returns #f.

procedure: (make-condition)

Returns a new condition.

procedure: (condition-wait condition exclusive)
procedure: (condition-wait condition exclusive timeout)

Leave exclusive and wait on condition. This is done atomically. When condition-wait returns the exclusive will have been entered. Conditions are subject to wakeups not associated with an explicit wake. You must recheck a predicate when condition-wait returns.

If timeout is specified, then return when either the wait completes or the timeout has elapsed. If the wait completes, return #t otherwise return #f. The timeout is a relative number of seconds or an absolute time; see SRFI 18.

procedure: (condition-wake condition)

Wake one thread waiting on condition.

procedure: (condition-wake-all condition )

Wake all threads waiting on condition.

Example

Conditions and exclusives are used to implement a mailbox. One or more producer threads put items into the mailbox and one or more consumer threads get items out of the mailbox.

(define not-empty (make-condition))
(define not-full (make-condition))
(define lock (make-exclusive))
(define mailbox #f)
(define mailbox-full #f)
(define next-item 1)
(define last-item 100)

(define (producer)
    (sleep (random 100))
    (enter-exclusive lock)
    (let ((item next-item))
        (define (put item)
            (if mailbox-full
                (begin
                    (condition-wait not-full lock)
                    (put item))
                (begin
                    (set! mailbox item)
                    (set! mailbox-full #t)
                    (leave-exclusive lock)
                    (condition-wake not-empty))))
        (set! next-item (+ next-item 1))
        (if (> next-item last-item)
            (leave-exclusive lock) ; All done.
            (begin
                (put item)
                (producer)))))

(define (consumer)
    (define (get)
        (if mailbox-full
            (begin
                (set! mailbox-full #f)
                (let ((item mailbox))
                    (condition-wake not-full)
                    (leave-exclusive lock)
                    item))
            (begin
                (condition-wait not-empty lock)
                (get))))
    (enter-exclusive lock)
    (let ((item (get)))
        (write item)
        (display " ")
        (consumer)))

(run-thread producer)
(run-thread producer)
(run-thread consumer)
(run-thread consumer)
(run-thread consumer)
(run-thread consumer)

(sleep 4000)
(display "
")

SRFI 18: Multithreading support

(import (srfi 18)) to use SRFI 18. It is supported with the following exceptions.

  • The primordial thread is not special. Allowing it to return will terminate the process, but using exit-thread to end it will not.

  • Mutex state is not tracked and mutex-lock! with a timeout (or thread) arguments are not supported.

⚠️ **GitHub.com Fallback** ⚠️