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)
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}
#t if obj is a thread object, otherwise returns
#f.
thread:join.
@use{thread}
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}
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}
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}
@use{thread}
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}
@use{thread}
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}
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}
@use{thread}
@use{thread}
@use{thread}
@use{thread}
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}
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}
@use{thread}
@use{thread}
#f immediately. Otherwise the behavior is the same as
thread:wait-sem.
@use{thread}
@use{thread}
@use{thread}
@use{thread}
@use{thread}
@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}
(define th (thread:create
(lambda () (let loop () (loop)))))
(thread:kill th @SIGINT)
@use{thread}
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}
@use{thread}
#t if thread1 and thread2 represent the same
thread, otherwise returns #f.
@use{thread}
thread:join. Returns an unspecified value.
@use{thread}
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}
@use{thread}
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.