Go to the first, previous, next, last section, table of contents.


Thread

The thread package provides support for multithreaded programming. This package is based on POSIX thread library.

Before using functions and variables in Thread Package, following function call should be made to dynamically load necessary library.

(use 'thread)

Basic Thread Operations

Function: thread:create fun
fun (thread function) must be a function that takes no arguments. thread:create creates and starts a new thread that executes fun. It returns a thread object that represents the new thread.

It recognizes following keyword arguments.
detachstate should be 'joinable or 'detached. Chooses whether the thread is created in the joinable state or in the detached state. 'joinable is for PTHREAD_CREATE_JOINABLE: the thread can be joined later by thread:join. 'detached is for PTHREAD_CREATE_DETACHED: the thread cannot be joined and resources allocated to the thread is automatically released when fun returns. Default is 'joinable.
schedpolicy should be 'other, 'rr, or 'fifo. Selects the scheduling policy for the thread. 'other is for SCHED_OTHER; 'rr is for SCHED_RR; and 'fifo is for SCHED_FIFO. Default is 'other.
schedparam should be an integer. Changes the scheduling priority for the thread. Default is 0.
inheritsched should be 'explicit or 'inherit. Chooses whether the scheduling policy and scheduling parameter for the newly created thread are determined by the values of schedpolicy or schedparam arguments. 'explicit is for PTHREAD_EXPLICIT_SCHED: those attributes are inherited from the parent thread. 'inherit is for PTHREAD_INHERIT_SCHED: those attributes determined from schedpolicy and schedparam arguments. Default is 'explicit.
scope should be 'system or 'process. Chooses the scheduling contention scope for the created thread. 'system is for PTHREAD_SCOPE_SYSTEM: the thread contend for CPU time with all processes running on the machine. 'process is for PTHREAD_SCOPE_PROCESS: scheduling contension occurs only between the threads of the running process. Default is 'system.

Example:

(thread:create 
  (lambda () 
    (display "Thread 1")
    (newline))
  :detachstate 'detached)  ==> #<thread>

@use{thread}

Function: thread? obj
Returns #t if obj is a thread object, otherwise returns #f.

Function: thread:exit retval
Terminates the execution of the calling thread. retval specifies the value that can be collected by thread:join.

Function: thread:cancel thread
Sends a cancellation request to thread. Returns an unspecified value.

@use{thread}

Function: thread:join thread
Suspends the execution of the calling thread until thread terminates: that is, the thread function returns; thread:exit is called; or cancelled by thread:cancel. When thread terminates by cencellation, thread:join returns an unspecified value. Otherwise, it returns the value that the thread function returns or thread:exit specifies.

@use{thread}

Cancellation

Function: thread:setcancelstate state
Changes the cancellation state for the calling thread -- that is, whether cancellation requests are ignored or not. state should be either 'enable or 'disable. 'enable is for PTHREAD_CANCEL_ENABLE, meaning that cancellation is to be enabled. 'disable is for PTHREAD_CANCEL_DISABLE, meaning that cancellation is to be disabled. Returns the current cancellation state ('enable or 'disable).
(thread:setcancelstate 'disable) ==> enable

@use{thread}

Function: thread:setcanceltype type
Changes the type of responses the type of responses to cancellation requests. type should be either 'deferred or 'asynchronous. 'deferred is for PTHREAD_CANCEL_DEFERRED, to keep the cancellation request pending until the next cancellation point. 'asynchronous is for PTHREAD_CANCEL_ASYNCHRONOUS, to cancel the thread as soon as the cancellation request is received. Returns the current cancellation type ('deferred or 'asynchronous).

@use{thread}

Function: thread:testcancel
Does nothing except testing for pending cancellation and executing it. Returns an unspecified value. Its purpose is to introduce explicit checks for cancellation in long sequences of codes that do not call cancellation point functions otherwise.

@use{thread}

Cleanup Handler

Function: thread:with-cleanup cleanup-handler fun
Both cleanup-handler and fun must be a function that takes no argument. Calls fun with no argument. If fun returns, thread:with-cleanup returns that value. In this case, cleanup-handler does nothing. If fun does not return (that is, terminated either by thread:exit or cancellation), cleanup-handler is called with no argument on thread termination and thread:with-cleanup never returns.
(define mutex (thread:make-mutex))
(begin
  (thread:mutex-lock mutex)
  (thread:with-cleanup
    (lambda () (thread:mutex-unlock mutex))
    (lambda () (some-fun)))
  (thread:mutex-unlock mutex))

@use{thread}

Mutex

Function: thread:make-mutex
Returns a mutex object.

@use{thread}

Function: thread:mutex-lock mutex
Locks the mutex. mutex should be a mutex object. If the mutex is currently unlocked, it becomes locked and owned by the calling thread, and thread:mutex-lock returns immediately. If the mutex is already locked by another thread, thread:mutex-lock suspends the calling thread until the mutex is unlocked. Returns an unspecified value.

@use{thread}

Function: thread:mutex-trylock mutex
thread:mutex-trylock tries to lock the mutex. If the mutex is currently unlocked, the mutex is locked by the calling thread and thread:mutex-trylock returns #t. If the mutex is currently locked, it does not block and returns #f immediately.

@use{thread}

Function: thread:mutex-unlock mutex
Unlocks the mutex. Returns an unspecified value.

@use{thread}

Condition Variable

Function: thread:make-cond
Returns a condition variable object.

@use{thread}

Function: thread:cond-signal cond
Restarts one of the threads that are waiting on the condition variable cond. If no threads are waiting on cond, nothing happens. Returns an unspecified value.

@use{thread}

Function: thread:broadcast cond
Restarts all the threads that are waiting on the condition variable cond. Returns an unspecified value.

@use{thread}

Function: thread:cond-wait cond mutex
thread:cond-wait atomically unlocks the mutex and waits for the condition variable cond. The mutex must be locked by the calling thread on entrance to thread:cond-wait. Before returning to the calling thread, thread:cond-wait re-acquires mutex. Returns an unspecified value.

@use{thread}

Function: thread:cond-timedwait cond mutex sec
[nanosec]

Atomically unlocks mutex and waits on cond, as thread:cond-wait does, but it also bounds the duration of the wait. If cond has not been signaled before the time specified by sec and optional nanosec, mutex is re-acquired and thread:cond-timedwait returns #f. Otherwise (that is, cond is signaled) it returns #t.

The time specified by sec and optional nanosec is an absolute time. If sec and nanosec (if supplied) are both 0, it corresponds to 00:00:00 GMT, January 1, 1970.

@use{thread}

POSIX Semaphore

Function: thread:make-sem value
Returns a semaphore object that has an initial value of value.

@use{thread}

Function: thread:sem-wait sem
Suspends the calling thread until the semaphore represented by sem has non-zero value. It then atomically decreases the semaphore value.

@use{thread}

Function: thread:sem-trywait sem
This is a non-blocking variant of thread:sem-wait. If the semaphore count is zero, thread:sem-trywaie does not suspend but returns #f immediately. Otherwise the behavior is the same as thread:wait-sem.

@use{thread}

Function: thread:sem-post sem
Atomically increases the value of the semaphore represented by sem. Returns an unspecified value.

@use{thread}

Function: thread:sem-getvalue sem
Returns the value of the semaphore represented by sem.

@use{thread}

Thread-Specific Data

Function: thread:getspecific key
key should be a symbol. Returns the value of thread-specific data associated with key.

@use{thread}

Function: thread:setspecific key val
key should be a symbol. Associates val with key in the thread-specific data. Returns an unspecified value.

@use{thread}

Threads and Signal Handling

Function: thread:sigmask how newmask
Changes the signal mask for the calling thread. how specifies how the signal mask is changed. If how is @SIG_SETMASK, the signal mask is set to newmask. If how is @SIG_BLOCK, the signals specified by newmask are added to the current signal mask. If how is @SIG_UNBLOCK, the signals specified by newmask are removed from the current signal mask.

newmask should be a signal set created and manipulated by signal-related functions See section Signal Handling.

(define sigset (make-sigset))
(sigemptyset sigset)
(sigaddset sigset @SIGINT)
(thread:sigmask @SIG_BLOCK sigset)

@use{thread}

Function: thread:kill thread signo
Sends signal number signo to the thread thread.
(define th (thread:create 
             (lambda () (let loop () (loop)))))
(thread:kill th @SIGINT)

@use{thread}

Function: sigwait sigset
Suspends the calling thread until one of the signals in sigset is delivered to the calling thread. Returns the signal number received.

For thread:sigwait to work reliably, the signals being waited for must be blocked in all threads, not only in the calling thread. The best way to achieve this is block those signals before any threads are created.

(thread:create
  (lambda ()
    (let ((sigset (make-sigset)))
      (sigemptyset sigset)
      (sigaddset sigset @SIGINT)
      (let loop ()
        (let ((signo (thread:sigwait sigset)))
          (display "SIGINT received")
          (newline)
          (loop))))))

@use{thread}

Miscellaneous Thread Functions

Function: thread:self
Returns the thread object for the calling thread.

@use{thread}

Function: thread:equal? thread1 thread2
Returns #t if thread1 and thread2 represent the same thread, otherwise returns #f.

@use{thread}

Function: thread:detach thread
Puts the thread in the detached state. This guarantees that resources consumed by thread will be freed immediately when thread terminates. However, this prevents other threads from synchronizing on the termination of thread using thread:join. Returns an unspecified value.

@use{thread}

Function: thread:atfork prepare parent child
Registers handler functions to be called just before and just after a new process is created with fork. prepare, parent , and child should be functions that take no arguments. prepare handler will be called from the parent process, just before the new process is created. parent handler will be called from the parent process, just before fork returns. child handler will be called from the child process, just before fork returns. thread:atfork returns an unspecified value.

thread:atfork can be called several times to install several sets of handlers. At fork time, prepare handlers are called in LIFO order (last added, first called), while parent and child handler are called in FIFO order (first added, first called).

Internally, thread:atfork uses following global variables: @@atfork_prepare, @@atfork_parent, and @@atfork_child.

@use{thread}

Function: thread:setschedparam thread policy priority
Sets the scheduling parameters for the thread thread. policy can be either @SCHED_OTHER (regular, non-reltime scheduling), @SCHED_RR (realtime, round-robin), or @SCHED_FIFO (realtime, first-in first-out). priority specifies the scheduling priority for the two realtime policies.

@use{thread}

Function: thread:getschedparam thread
Returns the scheduling policy and scheduling priority for the thread thread. Actually, it returns a pair whose car is an integer representing the policy (@SCHED_OTHER, @SCHED_RR, or @SCHED_FIFO) and cdr is an integer representing the priority.
(thread:getschedparam (thread:self)) ==> (0 . 0)

@use{thread}


Go to the first, previous, next, last section, table of contents.