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