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