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