|
The thread system provides the following data types: - Thread (a virtual processor which shares object
space with all other threads)
- Mutex (a mutual exclusion device,
also known as a lock and binary semaphore)
- Condition variable (a set of blocked threads)
The STklos thread system is conform to SRFI-18
(Multithreading support), and implement
all the SRFI mechanisms. See this SRFI documentation for a more complete
description
9.1 Threads
(make-thread thunk) | STklos procedure |
(make-thread thunk name)
(make-thread thunk name stack-size)
Returns a new thread. This thread is not automatically made runnable
(the procedure thread-start! must be used for this). A thread has the
following fields: name, specific, end-result, end-exception, and a list
of locked/owned mutexes it owns. The thread's execution consists of a call
to thunk with the "initial continuation". This continuation causes the
(then) current thread to store the result in its end-result field, abandon
all mutexes it owns, and finally terminate. The dynamic-wind
stack of the initial continuation is empty. The optional name is an
arbitrary Scheme object which identifies the thread (useful for debugging);
it defaults to an unspecified value. The specific field is set to an
unspecified value. The thread inherits the dynamic environment from the
current thread. Moreover, in this dynamic environment the exception handler
is bound to the "initial exception handler" which is a unary procedure
which causes the (then) current thread to store in its end-exception
field an "uncaught exception" object whose "reason" is the argument
of the handler, abandon all mutexes it owns, and finally terminate.
Note: The optional parameter stack-size permits to specify
the size (in words) reserved for the thread. This option does not exist
in SRFI-18. |
(current-thread) | STklos procedure |
Returns the current thread.
(eq? (current-thread) (current-thread)) ⇒ #t
|
|
(thread-start! thread) | STklos procedure |
Makes thread runnable. The thread must be a new thread.
Thread-start! returns the thread.
(let ((t (thread-start! (make-thread
(lambda () (write 'a))))))
(write 'b)
(thread-join! t)) ⇒ unspecified
after writing ab or ba
|
|
(thread-yield!) | STklos procedure |
The current thread exits the running state as if its quantum had
expired. Thread-yield! returns an unspecified value. |
(thread-terminate! thread) | STklos procedure |
Causes an abnormal termination of the thread . If the thread is not
already terminated, all mutexes owned by the thread become
unlocked/abandoned and a "terminated thread exception" object is stored
in the thread's end-exception field. If thread is the current thread,
thread-terminate! does not return. Otherwise, thread-terminate!
returns an unspecified value; the termination of the thread will occur
before thread-terminate! returns.
Note:
This operation must be used carefully because it terminates a thread
abruptly and it is impossible for that thread to perform any kind of
cleanup. This may be a problem if the thread is in the middle of a
critical section where some structure has been put in an inconsistent
state. However, another thread attempting to enter this critical section
will raise an "abandoned mutex exception" because the mutex is
unlocked/abandoned. |
(thread-sleep! timeout) | STklos procedure |
The current thread waits until the timeout is reached. This blocks the
thread only if timeout represents a point in the future. It is an error
for timeout to be #f . Thread-sleep! returns an unspecified value. |
(thread-join! thread) | STklos procedure |
(thread-join! thread timeout)
(thread-join! thread timeout timeout-val)
The current thread waits until the thread terminates (normally or not)
or until the timeout is reached if timeout is supplied.
If the timeout is reached, thread-join! returns timeout-val if it is
supplied, otherwise a "join timeout exception" is raised.
If the thread terminated normally, the content of the end-result
field is returned, otherwise the content of the end-exception field
is raised.
(let ((t (thread-start! (make-thread (lambda ()
(expt 2 100))))))
(thread-sleep! 1)
(thread-join! t)) ⇒ 1267650600228229401496703205376
|
|
(thread? obj) | STklos procedure |
Returns #t if obj is a thread, otherwise returns #f .
(thread? (current-thread)) ⇒ #t
(thread? 'foo) ⇒ #f
|
|
(thread-name thread) | STklos procedure |
Returns the name of the thread .
(thread-name (make-thread (lambda () #f) 'foo)) ⇒ foo
|
|
(thread-stack-size thread) | STklos procedure |
Returns the allocated stack size for thread .
Note that this procedure is not present in SRFI-18. |
(thread-specific thread) | STklos procedure |
Returns the content of the thread 's specific field. |
(thread-specific-set! thread) | STklos procedure |
Stores obj into the thread 's specific field. Thread-specific-set!
returns an unspecified value.
(thread-specific-set! (current-thread) "hello")
⇒ unspecified
(thread-specific (current-thread))
⇒ "hello"
|
|
9.2 Mutexes
(make-mutex) | STklos procedure |
(make-mutex name)
Returns a new mutex in the unlocked/not-abandoned state. The optional name
is an arbitrary Scheme object which identifies the mutex
(useful for debugging); it defaults to an unspecified value.
The mutex's specific field is set to an unspecified value. |
(mutex? obj) | STklos procedure |
Returns #t if obj is a mutex, otherwise returns #f . |
(mutex-name mutex) | STklos procedure |
Returns the name of the mutex .
(mutex-name (make-mutex 'foo)) ⇒ foo
|
|
(mutex-specific mutex) | STklos procedure |
Returns the content of the mutex 's specific field. |
(mutex-specific! mutex obj) | STklos procedure |
Stores obj into the mutex 's specific field and eturns an unspecified value.
(define m (make-mutex))
(mutex-specific-set! m "hello") ⇒ unspecified
(mutex-specific m) ⇒ "hello"
(define (mutex-lock-recursively! mutex)
(if (eq? (mutex-state mutex) (current-thread))
(let ((n (mutex-specific mutex)))
(mutex-specific-set! mutex (+ n 1)))
(begin
(mutex-lock! mutex)
(mutex-specific-set! mutex 0))))
(define (mutex-unlock-recursively! mutex)
(let ((n (mutex-specific mutex)))
(if (= n 0)
(mutex-unlock! mutex)
(mutex-specific-set! mutex (- n 1)))))
|
|
(mutex-state mutex) | STklos procedure |
Returns information about the state of the mutex . The possible results
are:
- thread T: the mutex is in the locked/owned state and
thread T is the owner of the mutex
- symbol not-owned: the mutex is in the locked/not-owned
state
- symbol abandoned: the mutex is in the unlocked/abandoned
state
- symbol not-abandoned: the mutex is in the
unlocked/not-abandoned state
(mutex-state (make-mutex)) ⇒ not-abandoned
(define (thread-alive? thread)
(let ((mutex (make-mutex)))
(mutex-lock! mutex #f thread)
(let ((state (mutex-state mutex)))
(mutex-unlock! mutex) ; avoid space leak
(eq? state thread))))
|
|
(mutex-lock! mutex) | STklos procedure |
(mutex-lock! mutex timeout)
(mutex-lock! mutex timeout thread)
If the mutex is currently locked, the current thread waits until the
mutex is unlocked, or until the timeout is reached if timeout is supplied.
If the timeout is reached, mutex-lock! returns #f .
Otherwise, the state of the mutex is changed as follows:
- if thread is
#f the mutex becomes locked/not-owned,
- otherwise, let T be thread (or the current thread if thread
is not supplied),
- if T is terminated the mutex becomes unlocked/abandoned,
- otherwise mutex becomes locked/owned with T as the owner.
After changing the state of the mutex, an "abandoned mutex exception" is
raised if the mutex was unlocked/abandoned before the state change,
otherwise mutex-lock! returns #t .
(define (sleep! timeout)
;; an alternate implementation of thread-sleep!
(let ((m (make-mutex)))
(mutex-lock! m #f #f)
(mutex-lock! m timeout #f)))
|
|
(mutex-unlock! mutex) | STklos procedure |
(mutex-unlock! mutex condition-variable)
(mutex-unlock! mutex condition-variable timeout)
Unlocks the mutex by making it unlocked/not-abandoned. It is not an error
to unlock an unlocked mutex and a mutex that is owned by any thread.
If condition-variable is supplied, the current thread is blocked and
added to the condition-variable before unlocking mutex ; the thread
can unblock at any time but no later than when an appropriate call to
condition-variable-signal! or condition-variable-broadcast! is
performed (see below), and no later than the timeout (if timeout is
supplied). If there are threads waiting to lock this mutex, the scheduler
selects a thread, the mutex becomes locked/owned or locked/not-owned,
and the thread is unblocked. mutex-unlock! returns #f when the
timeout is reached, otherwise it returns #t . |
9.3 Condition Variables
(make-conditon-variable) | STklos procedure |
(make-conditon-variable name)
Returns a new empty condition variable. The optional name is an arbitrary
Scheme object which identifies the condition variable (useful for debugging);
it defaults to an unspecified value. The condition variable's specific
field is set to an unspecified value. |
(conditon-variable? obj) | STklos procedure |
Returns #t if obj is a condition variable, otherwise returns #f . |
(conditon-variable-name conditon-variable) | STklos procedure |
eturns the name of the condition-variable . |
(conditon-variable-specific conditon-variable) | STklos procedure |
Returns the content of the condition-variable 's specific field. |
(conditon-variable-specific-set! conditon-variable obj) | STklos procedure |
Stores obj into the condition-variable 's specific field. |
(condition-variable-signal! condition-variable) | STklos procedure |
If there are threads blocked on the condition-variable , the scheduler
selects a thread and unblocks it. Condition-variable-signal! returns
an unspecified value. |
(condition-variable-broadcast! condition-variable) | STklos procedure |
Unblocks all the threads blocked on the condition-variable .
Condition-variable-broadcast! returns an unspecified value. |
9.4 Conditions
(join-timeout-exception? obj) | STklos procedure |
Returns #t if obj is a "join timeout exception" object, otherwise returns #f.
A join timeout exception is raised when thread-join! is called, the timeout
is reached and no timeout-val is supplied. |
(abandoned-mutex-exception? obj) | STklos procedure |
Returns #t if obj is an "abandoned mutex exception" object, otherwise returns
#f. An abandoned mutex exception is raised when the current thread locks
a mutex that was owned by a thread which terminated (see mutex-lock! ). |
(terminated-thread-exception? obj) | STklos procedure |
Returns #t if obj is a "terminated thread exception" object, otherwise
returns #f. A terminated thread exception is raised when thread-join! is
called and the target thread has terminated as a result of a call to
thread-terminate! . |
(uncaught-exception? obj) | STklos procedure |
Returns #t if obj is an "uncaught exception" object, otherwise returns
#f. An uncaught exception is raised when thread-join! is called and the
target thread has terminated because it raised an exception that called
the initial exception handler of that thread. |
(uncaught-exception-reason exc) | STklos procedure |
Returns the object which was passed to the initial exception handler
of that thread (exc must be an "uncaught exception" object). |
|