1[comment {-*- tcl -*- doctools manpage}]
2[manpage_begin thread n 2.6]
3[moddesc {Tcl Threading}]
4[titledesc {Extension for script access to Tcl threading}]
5[require Tcl 8.4]
6[require Thread [opt 2.6]]
7
8[description]
9The [package thread] extension creates threads that contain Tcl 
10interpreters, and it lets you send scripts to those threads for
11evaluation.
12
13Additionaly, it provides script-level access to basic thread 
14synchronization primitives, like mutexes and condition variables.
15
16[section COMMANDS]
17This section describes commands for creating and destroying threads
18and sending scripts to threads for evaluation.
19
20
21
22[list_begin definitions]
23
24[call [cmd thread::create] [opt -joinable] [opt -preserved] [opt script]]
25
26This command creates a thread that contains a Tcl interpreter. 
27The Tcl interpreter either evaluates the optional [option script], if
28specified, or it waits in the event loop for scripts that arrive via
29the [cmd thread::send] command. The result, if any, of the
30optional [option script] is never returned to the caller.
31The result of [cmd thread::create] is the ID of the thread. This is
32the opaque handle which identifies the newly created thread for
33all other package commands. The handle of the thread goes out of scope
34automatically when thread is marked for exit
35(see the [cmd thread::release] command below).
36
37[nl]
38
39If the optional [option script] argument contains the [cmd thread::wait]
40command the thread will enter into the event loop. If such command is not
41found  in the [option script] the thread will run the [option script] to 
42the end and exit. In that case, the handle may be safely ignored since it 
43refers to a thread which does not exists any more at the time when the 
44command returns.
45
46[nl]
47
48Using flag [option -joinable] it is possible to create a joinable
49thread, i.e. one upon whose exit can be waited upon by using 
50[cmd thread::join] command. 
51Note that failure to join a thread created with [option -joinable] flag
52results in resource and memory leaks. 
53
54
55[nl]
56
57Threads created by the [cmd thread::create] cannot be destroyed 
58forcefully. Consequently, there is no corresponding thread destroy
59command. A thread may only be released using the [cmd thread::release] 
60and if its internal reference count drops to zero, the thread is 
61marked for exit. This kicks the thread out of the event loop 
62servicing and the thread continues to execute commands passed in 
63the [option script] argument, following the [cmd thread::wait]
64command. If this was the last command in the script, as usualy the
65case, the thread will exit.
66
67[nl]
68
69It is possible to create a situation in which it may be impossible
70to terminate the thread, for example by putting some endless loop 
71after the [cmd thread::wait] or entering the event loop again by 
72doing an vwait-type of command. In such cases, the thread may never
73exit. This is considered to be a bad practice and should be avoided 
74if possible. This is best illustrated by the example below:
75
76[example {
77    # You should never do ...
78    set tid [thread::create {
79        package require Http
80        thread::wait
81        vwait forever ; # <-- this!
82    }]
83}]
84
85The thread created in the above example will never be able to exit.
86After it has been released with the last matching [cmd thread::release]
87call, the thread will jump out of the [cmd thread::wait] and continue 
88to execute commands following. It will enter [cmd vwait] command and 
89wait endlessly for events. There is no way one can terminate such thread,
90so you wouldn't want to do this!
91
92[nl]
93
94Each newly created has its internal reference counter set to 0 (zero), 
95i.e. it is unreserved. This counter gets incremented by a call to 
96[cmd thread::preserve] and decremented by a call to [cmd thread::release]
97command. These two commands implement simple but effective thread 
98reservation system and offer predictable and controllable thread 
99termination capabilities. It is however possible to create initialy 
100preserved threads by using flag [option -preserved] of the 
101[cmd thread::create] command. Threads created with this flag have the 
102initial value of the reference counter of 1 (one), and are thus 
103initially marked reserved. 
104
105
106[call [cmd thread::preserve] [opt id]]
107
108This command increments the thread reference counter. Each call
109to this command increments the reference counter by one (1). 
110Command returns the value of the reference counter after the increment. 
111If called with the optional thread [option id], the command preserves
112the given thread. Otherwise the current thread is preserved.
113
114[nl]
115
116With reference counting, one can implement controlled access to a 
117shared Tcl thread. By incrementing the reference counter, the 
118caller signalizes that he/she wishes to use the thread for a longer
119period of time. By decrementing the counter, caller signalizes that 
120he/she has finished using the thread.
121
122[call [cmd thread::release] [opt -wait] [opt id]]
123
124This command decrements the thread reference counter. Each call to 
125this command decrements the reference counter by one (1). 
126If called with the optional thread [option id], the command releases
127the given thread. Otherwise, the current thread is released.
128Command returns the value of the reference counter after the decrement.
129When the reference counter reaches zero (0), the target thread is 
130marked for termination. You should not reference the thread after the
131[cmd thread::release] command returns zero or negative integer. 
132The handle of the thread goes out of scope and should not be used any
133more. Any following reference to the same thread handle will result 
134in Tcl error.
135
136[nl]
137
138Optional flag [option -wait] instructs the caller thread to wait for 
139the target thread to exit, if the effect of the command would result 
140in termination of the target thread, i.e. if the return result would
141be zero (0). Without the flag, the caller thread does not wait for 
142the target thread to exit. Care must be taken when using the 
143[option -wait], since this may block the caller thread indefinitely.
144This option has been implemented for some special uses of the extension
145and is deprecated for regular use. Regular users should create joinable
146threads by using the [option -joinable] option of the [cmd thread::create]
147command and the [cmd thread::join] to wait for thread to exit. 
148
149[call [cmd thread::id]]
150
151This command returns the ID of the current thread.
152
153[call [cmd thread::errorproc] [opt procname]]
154
155This command sets a handler for errors that occur in scripts sent 
156asynchronously, using the [option -async] flag of the 
157[cmd thread::send] command, to other threads. If no handler 
158is specified, the current handler is returned. The empty string
159resets the handler to default (unspecified) value.
160An uncaught error in a thread causes an error message to be sent
161to the standard error channel. This default reporting scheme can
162be changed by registering a procedure which is called to report
163the error. The [arg procname] is called in the interpreter that
164invoked the [cmd thread::errorproc] command. The [arg procname]
165is called like this:
166
167[example {
168    myerrorproc thread_id errorInfo
169}]
170
171[call [cmd thread::unwind]]
172
173Use of this command is deprecated in favour of more advanced thread
174reservation system implemented with [cmd thread::preserve] and 
175[cmd thread::release] commands. Support for [cmd thread::unwind] 
176command will dissapear in some future major release of the extension.
177[nl]
178This command stops a prior [cmd thread::wait] command. Execution of
179the script passed to newly created thread will continue from the 
180[cmd thread::wait] command. If [cmd thread::wait] was the last command
181in the script, the thread will exit. The command returns empty result
182but may trigger Tcl error with the message "target thread died" in some
183situations.
184
185
186[call [cmd thread::exit]]
187
188Use of this command is deprecated in favour of more advanced thread
189reservation system implemented with [cmd thread::preserve] and 
190[cmd thread::release] commands. Support for [cmd thread::exit] 
191command will dissapear in some future major release of the extension.
192[nl]
193This command forces a thread stuck in the [cmd thread::wait]
194command to unconditionaly exit. The execution of [cmd thread::exit]
195command is guaranteed to leave the program memory in the unconsistent
196state, produce memory leaks and otherwise affect other subsytem(s)
197of the Tcl application in an unpredictable manner. The command 
198returns empty result but may trigger Tcl error with the message
199"target thread died" in some situations.
200
201[call [cmd thread::names]]
202
203This command returns a list of thread IDs. These are only for
204threads that have been created via [cmd thread::create] command.
205If your application creates other threads at the C level, they
206are not reported by this command.
207
208
209[call [cmd thread::exists] [arg id]]
210
211Returns true (1) if thread given by the [arg id] parameter exists, 
212false (0) otherwise. This applies only for threads that have
213been created via [cmd thread::create] command.
214
215
216[call [cmd thread::send] [opt -async] [opt -head] [arg id] [arg script] [opt varname]]
217
218This command passes a [arg script] to another thread and, optionally,
219waits for the result. If the [option -async] flag is specified, the 
220command does not wait for the result and it returns empty string.
221The target thread must enter it's event loop in order to receive 
222scripts sent via this command. This is done by default for threads 
223created without a startup script. Threads can enter the event loop 
224explicitly by calling [cmd thread::wait] or any other relevant Tcl/Tk
225command, like [cmd update], [cmd vwait], etc. 
226
227[nl]
228
229Optional [option varname] specifies name of the variable to store
230the result of the [arg script]. Without the [option -async] flag,
231the command returns the evaluation code, similarily to the standard 
232Tcl [cmd catch] command. If, however, the [option -async] flag is
233specified, the command returns immediately and caller can later 
234[cmd vwait] on [opt varname] to get the result of the passed [arg script]
235
236[example {
237    set t1 [thread::create]
238    set t2 [thread::create] 
239    thread::send -async $t1 "set a 1" result
240    thread::send -async $t2 "set b 2" result 
241    for {set i 0} {$i < 2} {incr i} {
242        vwait result
243    }
244}]
245
246In the above example, two threads were fed work and both of them were
247instructed to signalize the same variable "result" in the calling thread.
248The caller entered the event loop twice to get both results. Note, 
249however, that the order of the received results may vary, depending on 
250the current system load, type of work done, etc, etc.
251
252[nl]
253
254Many threads can simultaneously send scripts to the target thread for 
255execution. All of them are entered into the event queue of the target 
256thread and executed on the FIFO basis, intermingled with optional other
257events pending in the event queue of the target thread.
258Using the optional [opt -head] switch, scripts posted to the thread's
259event queue can be placed on the head, instead on the tail of the queue,
260thus being executed in the LIFO fashion.
261
262
263[call [cmd thread::broadcast] [arg id] [arg script]]
264
265This command passes a [arg script] to all threads created by the
266package for execution. It does not wait for response from any of
267the threads.
268
269[call [cmd thread::wait]]
270
271This enters the event loop so a thread can receive messages from 
272the [cmd thread::send] command. This command should only be used
273within the script passed to the [cmd thread::create]. It should
274be the very last command in the script. If this is not the case,
275the exiting thread will continue executing the script lines past
276the [cmd thread::wait] which is usually not what you want and/or
277expect.
278
279[example {
280    set t1 [thread::create {
281        #
282        # Do some initialization work here
283        #
284        thread::wait ; # Enter the event loop
285    }]
286}]
287
288[call [cmd thread::eval] [opt {-lock mutex}] [arg arg] [opt {arg ...}]]
289
290This command concatenates passed arguments and evaluates the 
291resulting script under the mutex protection. If no mutex is
292specified by using the [opt {-lock mutex}] optional argument,
293the internal static mutex is used.
294
295
296[call [cmd thread::join] [arg id]]
297
298This command waits for the thread with ID [arg id] to exit and
299then returns it's exit code. Errors will be returned for threads
300which are not joinable or already waited upon by another thread.
301Upon the join the handle of the thread has gone out of scope and
302should not be used any more.
303
304
305[call [cmd thread::configure] [arg id] [opt option] [opt value] [opt ...]]
306
307This command configures various low-level aspects of the thread with
308ID [arg id] in the similar way as the standard Tcl command 
309[cmd fconfigure] configures some Tcl channel options. Options currently
310supported are: [option -eventmark] and [option -unwindonerror].
311
312[nl]
313
314The [option -eventmark] option, when set, limits the number of 
315asynchronously posted scripts to the thread event loop. 
316The [cmd {thread::send -async}] command will block until the number
317of pending scripts in the event loop does not drop below the value
318configured with [option -eventmark]. Default value for the 
319[option -eventmark] is 0 (zero) which effectively disables the checking,
320i.e. allows for unlimited number of posted scripts.
321
322[nl]
323
324The [option -unwindonerror] option, when set, causes the 
325target thread to unwind if the result of the script processing 
326resulted in error. Default value for the [option -unwindonerror]
327is 0 (false), i.e. thread continues to process scripts after one
328of the posted scripts fails.
329
330
331[call [cmd thread::transfer] [arg id] [arg channel]]
332
333This moves the specified [arg channel] from the current thread 
334and interpreter to the main interpreter of the thread with the 
335given [arg id]. After the move the current interpreter has no
336access to the channel any more, but the main interpreter of the
337target thread will be able to use it from now on.
338The command waits until the other thread has incorporated the
339channel. Because of this it is possible to deadlock the 
340participating threads by commanding the other through a 
341synchronous [cmd thread::send] to transfer a channel to us.
342This easily extends into longer loops of threads waiting for 
343each other. Other restrictions: the channel in question must 
344not be shared among multiple interpreters running in the 
345sending thread. This automatically excludes the special channels
346for standard input, output and error.
347
348[nl]
349
350Due to the internal Tcl core implementation and the restriction on 
351transferring shared channels, one has to take extra measures when
352transferring socket channels created by accepting the connection
353out of the [cmd socket] commands callback procedures:
354
355[example {
356    socket -server _Accept 2200
357    proc _Accept {s ipaddr port} {
358        after idle [list Accept $s $ipaddr $port]
359    }
360    proc Accept {s ipaddr port} {
361        set tid [thread::create]
362        thread::transfer $tid $s
363    }
364}]
365
366[call [cmd thread::detach] [arg channel]]
367
368This detaches the specified [arg channel] from the current thread and 
369interpreter. After that, the current interpreter has no access to the
370channel any more. The channel is in the parked state until some other
371(or the same) thread attaches the channel again with [cmd thread::attach].
372Restrictions: same as for transferring shared channels with the
373[cmd thread::transfer] command.
374
375[call [cmd thread::attach] [arg channel]]
376
377This attaches the previously detached [arg channel] in the
378current thread/interpreter. For already existing channels, 
379the command does nothing, i.e. it is not an error to attach the
380same channel more than once. The first operation will actualy
381perform the operation, while all subsequent operation will just
382do nothing. Command throws error if the [arg channel] cannot be
383found in the list of detached channels and/or in the current
384interpreter.
385
386[call [cmd thread::mutex]]
387
388Mutexes are most common thread synchronization primitives. 
389They are used to synchronize access from two or more threads to one or 
390more shared resources. This command provides script-level access to 
391exclusive and/or recursive mutexes. Exclusive mutexes can be locked 
392only once by one thread, while recursive mutexes can be locked many 
393times by the same thread. For recursive mutexes, number of lock and 
394unlock operations must match, otherwise, the mutex will never be 
395released, which would lead to various deadlock situations.
396[nl]
397Care has to be taken when using mutexes in an multithreading program.
398Improper use of mutexes may lead to various deadlock situations, 
399especially when using exclusive mutexes.
400
401[nl]
402
403The [cmd thread::mutex] command supports following subcommands and options:
404
405[list_begin definitions]
406
407[call [cmd thread::mutex] [method create] [opt -recursive]]
408
409Creates the mutex and returns it's opaque handle. This handle
410should be used for any future reference to the newly created mutex.
411If no optional [opt -recursive] argument was specified, the command
412creates the exclusive mutex. With the [opt -recursive] argument,
413the command creates a recursive mutex.
414
415[call [cmd thread::mutex] [method destroy] [arg mutex]]
416
417Destroys the [arg mutex]. Mutex should be in unlocked state before
418the destroy attempt. If the mutex is locked, the command will throw 
419Tcl error. 
420
421[call [cmd thread::mutex] [method lock] [arg mutex]]
422
423Locks the [arg mutex]. Locking the exclusive mutex may throw Tcl 
424error if on attempt to lock the same mutex twice from the same
425thread. If your program logic forces you to lock the same mutex 
426twice or more from the same thread (this may happen in recursive 
427procedure invocations) you should consider using the recursive mutexes. 
428
429[call [cmd thread::mutex] [method unlock] [arg mutex]]
430
431Unlocks the [arg mutex] so some other thread may lock it again.
432Attempt to unlock the already unlocked mutex will throw Tcl error.
433
434[list_end]
435
436[nl]
437
438[call [cmd thread::rwmutex]]
439
440This command creates many-readers/single-writer mutexes. Reader/writer
441mutexes allow you to serialize access to a shared resource more optimally. 
442In situations where a shared resource gets mostly read and seldom modified, 
443you might gain some performace by using reader/writer mutexes instead of 
444exclusive or recursive mutexes. 
445[nl]
446For reading the resource, thread should obtain a read lock on the resource.
447Read lock is non-exclusive, meaning that more than one thread can
448obtain a read lock to the same resource, without waiting on other readers.
449For changing the resource, however, a thread must obtain a exclusive
450write lock. This lock effectively blocks all threads from gaining the
451read-lock while the resource is been modified by the writer thread.
452Only after the write lock has been released, the resource may be read-locked
453again. 
454
455[nl]
456
457The [cmd thread::rwmutex] command supports following subcommands and options:
458
459[list_begin definitions]
460
461[call [cmd thread::rwmutex] [method create]]
462
463Creates the reader/writer mutex and returns it's opaque handle.
464This handle should be used for any future reference to the newly 
465created mutex.
466
467[call [cmd thread::rwmutex] [method destroy] [arg mutex]]
468
469Destroys the reader/writer [arg mutex]. If the mutex is already locked,
470attempt to destroy it will throw Tcl error.
471
472[call [cmd thread::rwmutex] [method rlock] [arg mutex]]
473
474Locks the [arg mutex] for reading. More than one thread may read-lock
475the same [arg mutex] at the same time.
476
477[call [cmd thread::rwmutex] [method wlock] [arg mutex]]
478
479Locks the [arg mutex] for writing. Only one thread may write-lock
480the same [arg mutex] at the same time. Attempt to write-lock same
481[arg mutex] twice from the same thread will throw Tcl error.
482
483[call [cmd thread::rwmutex] [method unlock] [arg mutex]]
484
485Unlocks the [arg mutex] so some other thread may lock it again.
486Attempt to unlock already unlocked [arg mutex] will throw Tcl error.
487
488[list_end]
489
490[nl]
491
492[call [cmd thread::cond]]
493
494This command provides script-level access to condition variables.
495A condition variable creates a safe environment for the program 
496to test some condition, sleep on it when false and be awakened 
497when it might have become true. A condition variable is always 
498used in the conjuction with an exclusive mutex. If you attempt
499to use other type of mutex in conjuction with the condition 
500variable, a Tcl error will be thrown.
501
502[nl]
503
504The command supports following subcommands and options:
505
506[list_begin definitions]
507
508[call [cmd thread::cond] [method create]]
509
510Creates the condition variable and returns it's opaque handle.
511This handle should be used for any future reference to newly 
512created condition variable.
513
514[call [cmd thread::cond] [method destroy] [arg cond]]
515
516Destroys condition variable [arg cond]. Extreme care has to be taken 
517that nobody is using (i.e. waiting on) the condition variable, 
518otherwise unexpected errors may happen.
519
520[call [cmd thread::cond] [method notify] [arg cond]]
521
522Wakes up all threads waiting on the condition variable [arg cond].
523
524[call [cmd thread::cond] [method wait] [arg cond] [arg mutex] [opt ms]]
525
526This command is used to suspend program execution until the condition
527variable [arg cond] has been signalled or the optional timer has expired.
528The exclusive [arg mutex] must be locked by the calling thread on entrance
529to this command. If the mutex is not locked, Tcl error is thrown.
530While waiting on the [arg cond], the command releases [arg mutex]. 
531Before returning to the calling thread, the command re-acquires the 
532[arg mutex] again. Unlocking the [arg mutex] and waiting on the 
533condition variable [arg cond] is done atomically.
534
535[nl]
536
537The [option ms] command option, if given, must be an integer specifying
538time interval in milliseconds the command waits to be signalled. 
539Otherwise the command waits on condition notify forever.
540
541[nl]
542
543In multithreading programs, there are many situations where a thread has
544to wait for some event to happen until it is allowed to proceed.
545This is usually accomplished by repeatedly testing a condition under the
546mutex protection and waiting on the condition variable until the condition
547evaluates to true:
548
549[example {
550    set mutex [thread::mutex create]
551    set cond  [thread::cond  create]
552
553    thread::mutex lock $mutex
554    while {<some_condition_is_true>} {
555        thread::cond wait $cond $mutex
556    }
557    # Do some work under mutex protection
558    thread::mutex unlock $mutex
559}]
560
561Repeated testing of the condition is needed since the condition variable 
562may get signalled without the condition being actually changed (spurious 
563thread wake-ups, for example).
564
565[list_end]
566
567[list_end]
568
569[section DISCUSSION]
570The fundamental threading model in Tcl is that there can be one or
571more Tcl interpreters per thread, but each Tcl interpreter should
572only be used by a single thread which created it.
573A "shared memory" abstraction is awkward to provide in Tcl because
574Tcl makes assumptions about variable and data ownership. Therefore
575this extension supports a simple form of threading where the main
576thread can manage several background, or "worker" threads. 
577For example, an event-driven server can pass requests to worker 
578threads, and then await responses from worker threads or new client
579requests. Everything goes through the common Tcl event loop, so 
580message passing between threads works naturally with event-driven I/O, 
581[cmd vwait] on variables, and so forth. For the transfer of bulk
582information it is possible to move channels between the threads.
583
584[para]
585
586For advanced multithreading scripts, script-level access to two
587basic synchronization primitives, mutex and condition variables,
588is also supported.
589
590[see_also tsv tpool ttrace [uri http://www.tcl.tk/doc/howto/thread_model.html]]
591
592[keywords thread events {message passing} synchronization mutex]
593
594[manpage_end]
595