Manual Pages for UNIX Darwin command on man thread
MyWebUniversity

Manual Pages for UNIX Darwin command on man thread

thread(n) thread(n)

NAME

thread - Extension for script access to Tcl threading

SYNOPSIS

package require TTccll 88..33 package require TThhrreeaadd ??22..66??

tthhrreeaadd::::ccrreeaattee ?-joinable? ?-preserved? ?script?

tthhrreeaadd::::pprreesseerrvvee ?id?

tthhrreeaadd::::rreelleeaassee ?-wait? ?id?

tthhrreeaadd::::iidd tthhrreeaadd::::eerrrroorrpprroocc ?procname? tthhrreeaadd::::uunnwwiinndd tthhrreeaadd::::eexxiitt tthhrreeaadd::::nnaammeess tthhrreeaadd::::eexxiissttss id

tthhrreeaadd::::sseenndd ?-async? id script ?varname?

tthhrreeaadd::::bbrrooaaddccaasstt id script tthhrreeaadd::::wwaaiitt

tthhrreeaadd::::eevvaall ?-lock mutex? arg ?arg ...?

tthhrreeaadd::::jjooiinn id tthhrreeaadd::::ccoonnffiigguurree id ?option? ?value? ?...? tthhrreeaadd::::ttrraannssffeerr id channel tthhrreeaadd::::ddeettaacchh channel tthhrreeaadd::::aattttaacchh channel tthhrreeaadd::::mmuutteexx

tthhrreeaadd::::mmuutteexx ccrreeaattee ?-recursive?

tthhrreeaadd::::mmuutteexx ddeessttrrooyy mutex tthhrreeaadd::::mmuutteexx lloocckk mutex tthhrreeaadd::::mmuutteexx uunnlloocckk mutex tthhrreeaadd::::rrwwmmuutteexx tthhrreeaadd::::rrwwmmuutteexx ccrreeaattee tthhrreeaadd::::rrwwmmuutteexx ddeessttrrooyy mutex tthhrreeaadd::::rrwwmmuutteexx rrlloocckk mutex tthhrreeaadd::::rrwwmmuutteexx wwlloocckk mutex tthhrreeaadd::::rrwwmmuutteexx uunnlloocckk mutex tthhrreeaadd::::ccoonndd tthhrreeaadd::::ccoonndd ccrreeaattee tthhrreeaadd::::ccoonndd ddeessttrrooyy cond tthhrreeaadd::::ccoonndd nnoottiiffyy cond tthhrreeaadd::::ccoonndd wwaaiitt cond mutex ?ms?

DESCRIPTION

The tthhrreeaadd extension creates threads that contain Tcl interpreters, and

it lets you send scripts to those threads for evaluation. Additionaly,

it provides script-level access to basic thread synchronization primi-

tives, like mutexes and condition variables. CCOOMMMMAANNDDSS

This section describes commands for creating and destroying threads and

sending scripts to threads for evaluation.

tthhrreeaadd::::ccrreeaattee ?-joinable? ?-preserved? ?script?

This command creates a thread that contains a Tcl interpreter.

The Tcl interpreter either evaluates the optional ssccrriipptt, if specified, or it waits in the event loop for scripts that arrive via the tthhrreeaadd::::sseenndd command. The result, if any, of the optional ssccrriipptt is never returned to the caller. The result of

tthhrreeaadd::::ccrreeaattee is the ID of the thread. This is the small inte-

ger handle which identifies the newly created thread for all

other package commands. The handle of the thread goes out of

scope automatically when thread is marked for exit (see the

tthhrreeaadd::::rreelleeaassee command below).

If the optional ssccrriipptt argument contains the tthhrreeaadd::::wwaaiitt com-

mand the thread will enter into the event loop. If such command

is not found in the ssccrriipptt the thread will run the ssccrriipptt to

the end and exit. In that case, the handle may be safely ignored

since it refers to a thread which does not exists any more at

the time when the command returns.

Using flag -jjooiinnaabbllee it is possible to create a joinable thread,

i.e. one upon whose exit can be waited upon by using

tthhrreeaadd::::jjooiinn command. Note that only Tcl8.4+ core supports join-

able threads. Note also that failure to join a thread created

with -jjooiinnaabbllee flag results in resource and memory leaks.

Threads created by the tthhrreeaadd::::ccrreeaattee cannot be destroyed force-

fully. Consequently, there is no corresponding thread destroy

command. A thread may only be released using the tthhrreeaadd::::rreelleeaassee

and if its internal reference count drops to zero, the thread is

marked for exit. This kicks the thread out of the event loop

servicing and the thread continues to execute commands passed in

the ssccrriipptt argument, following the tthhrreeaadd::::wwaaiitt command. If this was the last command in the script, as usualy the case, the

thread will exit.

It is possible to create a situation in which it may be impossi-

ble to terminate the thread, for example by putting some endless

loop after the tthhrreeaadd::::wwaaiitt or entering the event loop again by

doing an vwait-type of command. In such cases, the thread may

never exit. This is considered to be a bad practice and should be avoided if possible. This is best illustrated by the example below:

# You should never do ...

set tid [thread::create {

package require Http

thread::wait

vwait forever ; # <- this!

}]

The thread created in the above example will never be able to

exit. After it has been released with the last matching

tthhrreeaadd::::rreelleeaassee call, the thread will jump out of the

tthhrreeaadd::::wwaaiitt and continue to execute commands following. It will enter vvwwaaiitt command and wait endlessly for events. There is no

way one can terminate such thread, so you wouldn't want to do

this! Each newly created has its internal reference counter set to 0 (zero), i.e. it is unreserved. This counter gets incremented by a call to tthhrreeaadd::::pprreesseerrvvee and decremented by a call to tthhrreeaadd::::rreelleeaassee command. These two commands implement simple but

effective thread reservation system and offer predictable and

controllable thread termination capabilities. It is however pos-

sible to create initialy preserved threads by using flag -pprree-

sseerrvveedd of the tthhrreeaadd::::ccrreeaattee command. Threads created with this flag have the initial value of the reference counter of 1 (one), and are thus initially marked reserved. tthhrreeaadd::::pprreesseerrvvee ?id?

This command increments the thread reference counter. Each call

to this command increments the reference counter by one (1). Command returns the value of the reference counter after the

increment. If called with the optional thread iidd, the command

preserves the given thread. Otherwise the current thread is pre-

served. With reference counting, one can implement controlled access to

a shared Tcl thread. By incrementing the reference counter, the

caller signalizes that he/she wishes to use the thread for a

longer period of time. By decrementing the counter, caller sig-

nalizes that he/she has finished using the thread.

tthhrreeaadd::::rreelleeaassee ?-wait? ?id?

This command decrements the thread reference counter. Each call

to this command decrements the reference counter by one (1). If

called with the optional thread iidd, the command releases the

given thread. Otherwise, the current thread is released. Com-

mand returns the value of the reference counter after the decre-

ment. When the reference counter reaches zero (0), the target

thread is marked for termination. You should not reference the

thread after the tthhrreeaadd::::rreelleeaassee command returns zero or nega-

tive integer. The handle of the thread goes out of scope and

should not be used any more. Any following reference to the same

thread handle will result in Tcl error.

Optional flag -wwaaiitt instructs the caller thread to wait for the

target thread to exit, if the effect of the command would result

in termination of the target thread, i.e. if the return result

would be zero (0). Without the flag, the caller thread does not

wait for the target thread to exit. Care must be taken when

using the -wwaaiitt, since this may block the caller thread indefi-

nitely. This option has been implemented for users of Tcl 8.3 version only. Users of Tcl 8.4 or later should create joinable

threads, by using the -jjooiinnaabbllee option of the tthhrreeaadd::::ccrreeaattee

command and the tthhrreeaadd::::jjooiinn to wait for thread exit.

tthhrreeaadd::::iidd

This command returns the ID of the current thread.

tthhrreeaadd::::eerrrroorrpprroocc ?procname? This command sets a handler for errors that occur in scripts

sent asynchronously, using the -aassyynncc flag of the tthhrreeaadd::::sseenndd

command, to other threads. If no handler is specified, the cur-

rent handler is returned. The empty string resets the handler to

default (unspecified) value. An uncaught error in a thread

causes an error message to be sent to the standard error chan-

nel. This default reporting scheme can be changed by registering a procedure which is called to report the error. The procname is called in the interpreter that invoked the tthhrreeaadd::::eerrrroorrpprroocc command. The procname is called like this:

myerrorproc threadid errorInfo

tthhrreeaadd::::uunnwwiinndd Use of this command is deprecated in favour of more advanced

thread reservation system implemented with tthhrreeaadd::::pprreesseerrvvee and

tthhrreeaadd::::rreelleeaassee commands. Support for tthhrreeaadd::::uunnwwiinndd command will dissapear in some future major release of the extension. This command stops a prior tthhrreeaadd::::wwaaiitt command. Execution of

the script passed to newly created thread will continue from the

tthhrreeaadd::::wwaaiitt command. If tthhrreeaadd::::wwaaiitt was the last command in

the script, the thread will exit. The command returns empty

result but may trigger Tcl error with the message "target thread

died" in some situations. tthhrreeaadd::::eexxiitt Use of this command is deprecated in favour of more advanced

thread reservation system implemented with tthhrreeaadd::::pprreesseerrvvee and

tthhrreeaadd::::rreelleeaassee commands. Support for tthhrreeaadd::::eexxiitt command will dissapear in some future major release of the extension.

This command forces a thread stuck in the tthhrreeaadd::::wwaaiitt command

to unconditionaly exit. The execution of tthhrreeaadd::::eexxiitt command is guaranteed to leave the program memory in the unconsistent

state, produce memory leaks and otherwise affect other sub-

sytem(s) of the Tcl application in an unpredictable manner. The command returns empty result but may trigger Tcl error with the

message "target thread died" in some situations.

tthhrreeaadd::::nnaammeess

This command returns a list of thread IDs. These are only for

threads that have been created via tthhrreeaadd::::ccrreeaattee command. If

your application creates other threads at the C level, they are

not reported by this command. tthhrreeaadd::::eexxiissttss id

Returns true (1) if thread given by the id parameter exists,

false (0) otherwise. This applies only for threads that have

been created via tthhrreeaadd::::ccrreeaattee command.

tthhrreeaadd::::sseenndd ?-async? id script ?varname?

This command passes a script to another thread and, optionally,

waits for the result. If the -aassyynncc flag is specified, the com-

mand does not wait for the result and it returns empty string.

The target thread must enter it's event loop in order to receive

scripts sent via this command. This is done by default for

threads created without a startup script. Threads can enter the

event loop explicitly by calling tthhrreeaadd::::wwaaiitt or any other rele-

vant Tcl/Tk command, like uuppddaattee, vvwwaaiitt, etc. Optional vvaarrnnaammee specifies name of the variable to store the

result of the script. Without the -aassyynncc flag, the command

returns the evaluation code, similarily to the standard Tcl

ccaattcchh command. If, however, the -aassyynncc flag is specified, the

command returns immediately and caller can later vvwwaaiitt on ?var-

name? to get the result of the passed script

set t1 [thread::create]

set t2 [thread::create]

thread::send -async $t1 "set a 1" result

thread::send -async $t2 "set b 2" result

for {set i 0} {$i < 2} {incr i} {

vwait result }

In the above example, two threads were fed work and both of them

were instructed to signalize the same variable "result" in the

calling thread. The caller entered the event loop twice to get

both results. Note, however, that the order of the received results may vary, depending on the current system load, type of work done, etc, etc.

Many threads can simultaneously send scripts to the target

thread for execution. All of them are entered into the event

queue of the target thread and executed on the FIFO basis,

intermingled with optional other events pending in the event

queue of the target thread.

tthhrreeaadd::::bbrrooaaddccaasstt id script

This command passes a script to all threads created by the pack-

age for execution. It does not wait for response from any of the

threads.

tthhrreeaadd::::wwaaiitt

This enters the event loop so a thread can receive messages from

the tthhrreeaadd::::sseenndd command. This command should only be used within the script passed to the tthhrreeaadd::::ccrreeaattee. It should be the very last command in the script. If this is not the case, the

exiting thread will continue executing the script lines pass the

tthhrreeaadd::::wwaaiitt which is usually not what you want and/or expect.

set t1 [thread::create {

#

# Do some initialization work here

#

thread::wait ; # Enter the event loop

}]

tthhrreeaadd::::eevvaall ?-lock mutex? arg ?arg ...?

This command concatenates passed arguments and evaluates the resulting script under the mutex protection. If no mutex is

specified by using the ?-lock mutex? optional argument, the

internal static mutex is used. tthhrreeaadd::::jjooiinn id

This command waits for the thread with ID id to exit and then

returns it's exit code. Errors will be returned for threads

which are not joinable or already waited upon by another thread.

Upon the join the handle of the thread has gone out of scope and

should not be used any more.

NOTE: This command is available only when loaded into the

Tcl8.4+ shell. tthhrreeaadd::::ccoonnffiigguurree id ?option? ?value? ?...?

This command configures various low-level aspects of the thread

with ID id in the similar way as the standard Tcl command ffccoonn-

ffiigguurree configures some Tcl channel options. Options currently

supported are: -eevveennttmmaarrkk and -uunnwwiinnddoonneerrrroorr.

The -eevveennttmmaarrkk option, when set, limits the number of asyn-

chronously posted scripts to the thread event loop. The

tthhrreeaadd::::sseenndd -aassyynncc command will block until the number of pend-

ing scripts in the event loop does not drop below the value con-

figured with -eevveennttmmaarrkk. Default value for the -eevveennttmmaarrkk is 0

(zero) which effectively disables the checking, i.e. allows for unlimited number of posted scripts.

The -uunnwwiinnddoonneerrrroorr option, when set, causes the target thread to

unwind if the result of the script processing resulted in error.

Default value for the -uunnwwiinnddoonneerrrroorr is 0 (false), i.e. thread

continues to process scripts after one of the posted scripts fails. tthhrreeaadd::::ttrraannssffeerr id channel

This moves the specified channel from the current thread and

interpreter to the main interpreter of the thread with the given

id. After the move the current interpreter has no access to the

channel any more, but the main interpreter of the target thread

will be able to use it from now on. The command waits until the

other thread has incorporated the channel. Because of this it is

possible to deadlock the participating threads by commanding the

other through a synchronous tthhrreeaadd::::sseenndd to transfer a channel

to us. This easily extends into longer loops of threads waiting

for each other. Other restrictions: the channel in question must not be shared among multiple interpreters running in the sending

thread. This automatically excludes the special channels for

standard input, output and error. Due to the internal Tcl core implementation and the restriction on transferring shared channels, one has to take extra measures

when transferring socket channels created by accepting the con-

nection out of the ssoocckkeett commands callback procedures:

socket -server Accept 2200

proc Accept {s ipaddr port} {

after idle [list Accept $s $ipaddr $port]

} proc Accept {s ipaddr port} {

set tid [thread::create]

thread::transfer $tid $s

}

NOTE: this command is available only when loaded into the

Tcl8.4+ shell. tthhrreeaadd::::ddeettaacchh channel

This detaches the specified channel from the current thread and

interpreter. After that, the current interpreter has no access to the channel any more. The channel is in the parked state

until some other (or the same) thread attaches the channel again

with tthhrreeaadd::::aattttaacchh. Restrictions: same as for transferring shared channels with the tthhrreeaadd::::ttrraannssffeerr command.

NOTE: this command is available only when loaded into the

Tcl8.4+ shell. tthhrreeaadd::::aattttaacchh channel This attaches the previously detached channel in the current

thread/interpreter. For already existing channels, the command

does nothing, i.e. it is not an error to attach the same channel more than once. The first operation will actualy perform the operation, while all subsequent operation will just do nothing. Command throws error if the channel cannot be found in the list of detached channels and/or in the current interpreter.

NOTE: this command is available only when loaded into the

Tcl8.4+ shell. tthhrreeaadd::::mmuutteexx

Mutexes are most common thread synchronization primitives. They

are used to synchronize access from two or more threads to one

or more shared resources. This command provides script-level

access to exclusive and/or recursive mutexes. Exclusive mutexes

can be locked only once by one thread, while recursive mutexes

can be locked many times by the same thread. For recursive

mutexes, number of lock and unlock operations must match, other-

wise, the mutex will never be released, which would lead to var-

ious deadlock situations.

Care has to be taken when using mutexes in an multithreading

program. Improper use of mutexes may lead to various deadlock situations, especially when using exclusive mutexes. The tthhrreeaadd::::mmuutteexx command supports following subcommands and options:

tthhrreeaadd::::mmuutteexx ccrreeaattee ?-recursive?

Creates the mutex and returns it's opaque handle. This handle should be used for any future reference to the

newly created mutex. If no optional ?-recursive? argu-

ment was specified, the command creates the exclusive

mutex. With the ?-recursive? argument, the command cre-

ates a recursive mutex. tthhrreeaadd::::mmuutteexx ddeessttrrooyy mutex Destroys the mutex. Mutex should be in unlocked state before the destroy attempt. If the mutex is locked, the command will throw Tcl error. tthhrreeaadd::::mmuutteexx lloocckk mutex Locks the mutex. Locking the exclusive mutex may throw Tcl error if on attempt to lock the same mutex twice from

the same thread. If your program logic forces you to lock

the same mutex twice or more from the same thread (this

may happen in recursive procedure invocations) you should consider using the recursive mutexes. tthhrreeaadd::::mmuutteexx uunnlloocckk mutex

Unlocks the mutex so some other thread may lock it again.

Attempt to unlock the already unlocked mutex will throw Tcl error. tthhrreeaadd::::rrwwmmuutteexx

This command creates many-readers/single-writer mutexes.

Reader/writer mutexes allow you to serialize access to a shared resource more optimally. In situations where a shared resource

gets mostly read and seldom modified, you might gain some per-

formace by using reader/writer mutexes instead of exclusive or recursive mutexes.

For reading the resource, thread should obtain a read lock on

the resource. Read lock is non-exclusive, meaning that more

than one thread can obtain a read lock to the same resource,

without waiting on other readers. For changing the resource,

however, a thread must obtain a exclusive write lock. This lock

effectively blocks all threads from gaining the read-lock while

the resource is been modified by the writer thread. Only after

the write lock has been released, the resource may be read-

locked again. The tthhrreeaadd::::rrwwmmuutteexx command supports following subcommands and options: tthhrreeaadd::::rrwwmmuutteexx ccrreeaattee Creates the reader/writer mutex and returns it's opaque

handle. This handle should be used for any future refer-

ence to the newly created mutex. tthhrreeaadd::::rrwwmmuutteexx ddeessttrrooyy mutex Destroys the reader/writer mutex. If the mutex is already locked, attempt to destroy it will throw Tcl error. tthhrreeaadd::::rrwwmmuutteexx rrlloocckk mutex

Locks the mutex for reading. More than one thread may

read-lock the same mutex at the same time.

tthhrreeaadd::::rrwwmmuutteexx wwlloocckk mutex

Locks the mutex for writing. Only one thread may write-

lock the same mutex at the same time. Attempt to write-

lock same mutex twice from the same thread will throw Tcl

error. tthhrreeaadd::::rrwwmmuutteexx uunnlloocckk mutex

Unlocks the mutex so some other thread may lock it again.

Attempt to unlock already unlocked mutex will throw Tcl error. tthhrreeaadd::::ccoonndd

This command provides script-level access to condition vari-

ables. A condition variable creates a safe environment for the program to test some condition, sleep on it when false and be awakened when it might have become true. A condition variable is always used in the conjuction with an exclusive mutex. If you

attempt to use other type of mutex in conjuction with the condi-

tion variable, a Tcl error will be thrown. The command supports following subcommands and options: tthhrreeaadd::::ccoonndd ccrreeaattee Creates the condition variable and returns it's opaque

handle. This handle should be used for any future refer-

ence to newly created condition variable. tthhrreeaadd::::ccoonndd ddeessttrrooyy cond Destroys condition variable cond. Extreme care has to be

taken that nobody is using (i.e. waiting on) the condi-

tion variable, otherwise unexpected errors may happen. tthhrreeaadd::::ccoonndd nnoottiiffyy cond

Wakes up all threads waiting on the condition variable

cond. tthhrreeaadd::::ccoonndd wwaaiitt cond mutex ?ms? This command is used to suspend program execution until the condition variable cond has been signalled or the optional timer has expired. The exclusive mutex must be

locked by the calling thread on entrance to this command.

If the mutex is not locked, Tcl error is thrown. While waiting on the cond, the command releases mutex. Before

returning to the calling thread, the command re-acquires

the mutex again. Unlocking the mutex and waiting on the condition variable cond is done atomically.

The mmss command option, if given, must be an integer spec-

ifying time interval in milliseconds the command waits to be signalled. Otherwise the command waits on condition notify forever.

In multithreading programs, there are many situations

where a thread has to wait for some event to happen until

it is allowed to proceed. This is usually accomplished

by repeatedly testing a condition under the mutex protec-

tion and waiting on the condition variable until the con-

dition evaluates to true:

set mutex [thread::mutex create]

set cond [thread::cond create]

thread::mutex lock

while {} {

thread::cond wait $cond $mutex

}

# Do some work under mutex protection

thread::mutex unlock

Repeated testing of the condition is needed since the

condition variable may get signalled without the condi-

tion being actually changed (spurious thread wake-ups,

for example). DDIISSCCUUSSSSIIOONN

The fundamental threading model in Tcl is that there can be one or more

Tcl interpreters per thread, but each Tcl interpreter should only be

used by a single thread which created it. A "shared memory" abstrac-

tion is awkward to provide in Tcl because Tcl makes assumptions about variable and data ownership. Therefore this extension supports a simple

form of threading where the main thread can manage several background,

or "worker" threads. For example, an event-driven server can pass

requests to worker threads, and then await responses from worker

threads or new client requests. Everything goes through the common Tcl

event loop, so message passing between threads works naturally with

event-driven I/O, vvwwaaiitt on variables, and so forth. For the transfer of

bulk information it is possible to move channels between the threads.

For advanced multithreading scripts, script-level access to two basic

synchronization primitives, mutex and condition variables, is also sup-

ported.

SEE ALSO

http://www.tcl.tk/doc/howto/threadmodel.html, tpool, tsv, ttrace

KKEEYYWWOORRDDSS

events, message passing, mutex, synchronization, thread

Tcl Threading 2.6 thread(n)




Contact us      |      About us      |      Term of use      |       Copyright © 2000-2019 MyWebUniversity.com ™