0.9.2.9: thread objects
[sbcl.git] / doc / manual / threading.texinfo
1 @node  Threading
2 @comment  node-name,  next,  previous,  up
3 @chapter Threading
4
5 SBCL supports a fairly low-level threading interface that maps onto
6 the host operating system's concept of threads or lightweight
7 processes.  This means that threads may take advantage of hardware
8 multiprocessing on machines that have more than one CPU, but it does 
9 not allow Lisp control of the scheduler.  This is found in the
10 SB-THREAD package.
11
12 This requires x86 and Linux kernel 2.6 or systems with NPTL backports.
13
14 @menu
15 * Special Variables::           
16 * Mutex Support::               
17 * Waitqueue/condition variables::  
18 * Sessions/Debugging::          
19 * Implementation (Linux x86)::  
20 @end menu
21
22 @node Special Variables
23 @comment  node-name,  next,  previous,  up
24 @section Special Variables
25
26 The interaction of special variables with multiple threads is mostly
27 as one would expect, but users of other Lisps are warned that the
28 behaviour of locally bound specials differs in places from what they
29 may expect.
30
31 @itemize
32 @item 
33 global special values are visible across all threads;
34 @item
35 bindings (e.g. using LET) are local to the thread;
36 @item
37 initial values in a new thread are taken from the thread that created it. 
38 @end itemize
39
40 @node Mutex Support
41 @comment  node-name,  next,  previous,  up
42 @section Mutex Support
43
44 Mutexes are used for controlling access to a shared resource. One
45 thread is allowed to hold the mutex, others which attempt to take it
46 will be made to wait until it's free. Threads are woken in the order
47 that they go to sleep.
48
49 There isn't a timeout on mutex acquisition, but the usual WITH-TIMEOUT
50 macro (which throws a TIMEOUT condition after n seconds) can be used
51 if you want a bounded wait.
52
53 @lisp
54 (defpackage :demo (:use "CL" "SB-THREAD" "SB-EXT"))
55
56 (in-package :demo)
57
58 (defvar *a-mutex* (make-mutex :name "my lock"))
59
60 (defun thread-fn ()
61   (format t "Thread ~A running ~%" *current-thread*)
62   (with-mutex (*a-mutex*)
63     (format t "Thread ~A got the lock~%" *current-thread*)
64     (sleep (random 5)))
65   (format t "Thread ~A dropped lock, dying now~%" *current-thread*)))
66
67 (make-thread #'thread-fn)
68 (make-thread #'thread-fn)
69
70 @end lisp
71
72 @node Waitqueue/condition variables
73 @comment  node-name,  next,  previous,  up
74 @section Waitqueue/condition variables
75
76 These are based on the POSIX condition variable design, hence the
77 annoyingly CL-conflicting name. For use when you want to check a
78 condition and sleep until it's true. For example: you have a shared
79 queue, a writer process checking ``queue is empty'' and one or more
80 readers that need to know when ``queue is not empty''. It sounds
81 simple, but is astonishingly easy to deadlock if another process runs
82 when you weren't expecting it to.
83
84 There are three components:
85
86 @itemize
87 @item 
88 the condition itself (not represented in code)
89
90 @item 
91 the condition variable (a.k.a waitqueue) which proxies for it
92
93 @item 
94 a lock to hold while testing the condition 
95 @end itemize
96
97 Important stuff to be aware of:
98
99 @itemize
100 @item 
101 when calling condition-wait, you must hold the mutex. condition-wait
102 will drop the mutex while it waits, and obtain it again before
103 returning for whatever reason;
104
105 @item 
106 likewise, you must be holding the mutex around calls to
107 condition-notify;
108
109 @item 
110 a process may return from condition-wait in several circumstances: it
111 is not guaranteed that the underlying condition has become true. You
112 must check that the resource is ready for whatever you want to do to
113 it.
114
115 @end itemize
116
117 @lisp
118 (defvar *buffer-queue* (make-waitqueue))
119 (defvar *buffer-lock* (make-mutex :name "buffer lock"))
120
121 (defvar *buffer* (list nil))
122
123 (defun reader ()
124   (with-mutex (*buffer-lock*)
125     (loop
126      (condition-wait *buffer-queue* *buffer-lock*)
127      (loop
128       (unless *buffer* (return))
129       (let ((head (car *buffer*)))
130         (setf *buffer* (cdr *buffer*))
131         (format t "reader ~A woke, read ~A~%" 
132                 *current-thread* head))))))
133
134 (defun writer ()
135   (loop
136    (sleep (random 5))
137    (with-mutex (*buffer-lock*)
138      (let ((el (intern
139                 (string (code-char 
140                          (+ (char-code #\A) (random 26)))))))
141        (setf *buffer* (cons el *buffer*)))
142      (condition-notify *buffer-queue*))))
143
144 (make-thread #'writer)
145 (make-thread #'reader)
146 (make-thread #'reader)       
147
148 @end lisp
149
150 @node Sessions/Debugging
151 @comment  node-name,  next,  previous,  up
152 @section Sessions/Debugging
153
154 If the user has multiple views onto the same Lisp image (for example,
155 using multiple terminals, or a windowing system, or network access)
156 they are typically set up as multiple @dfn{sessions} such that each
157 view has its own collection of foreground/background/stopped threads.
158 A thread which wishes to create a new session can use
159 @code{sb-thread:with-new-session} to remove itself from the current
160 session (which it shares with its parent and siblings) and create a
161 fresh one.  
162 # See also @code{sb-thread:make-listener-thread}.
163
164 Within a single session, threads arbitrate between themselves for the
165 user's attention.  A thread may be in one of three notional states:
166 foreground, background, or stopped.  When a background process
167 attempts to print a repl prompt or to enter the debugger, it will stop
168 and print a message saying that it has stopped.  The user at his
169 leisure may switch to that thread to find out what it needs.  If a
170 background thread enters the debugger, selecting any restart will put
171 it back into the background before it resumes.  Arbitration for the
172 input stream is managed by calls to @code{sb-thread:get-foreground}
173 (which may block) and @code{sb-thread:release-foreground}.
174
175 @code{sb-ext:quit} terminates all threads in the current session, but
176 leaves other sessions running.
177
178 @node Implementation (Linux x86)
179 @comment  node-name,  next,  previous,  up
180 @section Implementation (Linux x86)
181
182 On Linux x86, threading is implemented using @code{clone()} and does
183 not involve pthreads.  This is not because there is anything wrong
184 with pthreads @emph{per se}, but there is plenty wrong (from our
185 perspective) with LinuxThreads.  SBCL threads are mapped 1:1 onto
186 Linux tasks which share a VM but nothing else - each has its own
187 process id and can be seen in e.g. @command{ps} output.
188
189 Per-thread local bindings for special variables is achieved using the
190 %fs segment register to point to a per-thread storage area.  This may
191 cause interesting results if you link to foreign code that expects
192 threading or creates new threads, and the thread library in question
193 uses %fs in an incompatible way.
194
195 Queues require the @code{sys_futex()} system call to be available:
196 this is the reason for the NPTL requirement.  We test at runtime that
197 this system call exists.
198
199 Garbage collection is done with the existing Conservative Generational
200 GC.  Allocation is done in small (typically 8k) regions: each thread
201 has its own region so this involves no stopping. However, when a
202 region fills, a lock must be obtained while another is allocated, and
203 when a collection is required, all processes are stopped.  This is
204 achieved by sending them signals, which may make for interesting
205 behaviour if they are interrupted in system calls.  The streams
206 interface is believed to handle the required system call restarting
207 correctly, but this may be a consideration when making other blocking
208 calls e.g. from foreign library code.
209
210 Large amounts of the SBCL library have not been inspected for
211 thread-safety.  Some of the obviously unsafe areas have large locks
212 around them, so compilation and fasl loading, for example, cannot be
213 parallelized.  Work is ongoing in this area.
214
215 A new thread by default is created in the same POSIX process group and
216 session as the thread it was created by.  This has an impact on
217 keyboard interrupt handling: pressing your terminal's intr key
218 (typically @kbd{Control-C}) will interrupt all processes in the
219 foreground process group, including Lisp threads that SBCL considers
220 to be notionally `background'.  This is undesirable, so background
221 threads are set to ignore the SIGINT signal.
222
223 @code{sb-thread:make-listener-thread} in addition to creating a new
224 Lisp session makes a new POSIX session, so that pressing
225 @kbd{Control-C} in one window will not interrupt another listener -
226 this has been found to be embarrassing.