<html><head>
<title>thread - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- thread.n
-->
<body><div class="doctools">
<h1 class="doctools_title">thread(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>thread - Extension for script access to Tcl threading</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
</ul>
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>The <b class="package">thread</b> 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 primitives, like mutexes and condition variables.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">COMMANDS</a></h2>
<p>This section describes commands for creating and destroying threads
and sending scripts to threads for evaluation.</p>
<dl class="doctools_definitions">
<dt><a name="1"><b class="cmd">thread::create</b> <span class="opt">?-joinable?</span> <span class="opt">?-preserved?</span> <span class="opt">?script?</span></a></dt>
................................................................................
<p>Threads created by the <b class="cmd">thread::create</b> cannot be destroyed
forcefully. Consequently, there is no corresponding thread destroy
command. A thread may only be released using the <b class="cmd">thread::release</b>
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 <b class="option">script</b> argument, following the <b class="cmd">thread::wait</b>
command. If this was the last command in the script, as usualy the
case, the thread will exit.</p>
<p>It is possible to create a situation in which it may be impossible
to terminate the thread, for example by putting some endless loop
after the <b class="cmd">thread::wait</b> 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:</p>
................................................................................
wait endlessly for events. There is no way one can terminate such thread,
so you wouldn't want to do this!</p>
<p>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
<b class="cmd">thread::preserve</b> and decremented by a call to <b class="cmd">thread::release</b>
command. These two commands implement simple but effective thread
reservation system and offer predictable and controllable thread
termination capabilities. It is however possible to create initialy
preserved threads by using flag <b class="option">-preserved</b> of the
<b class="cmd">thread::create</b> command. Threads created with this flag have the
initial value of the reference counter of 1 (one), and are thus
initially marked reserved.</p></dd>
<dt><a name="2"><b class="cmd">thread::preserve</b> <span class="opt">?id?</span></a></dt>
<dd><p>This command increments the thread reference counter. Each call
to this command increments the reference counter by one (1).
................................................................................
until there are no further invocations of the interpreter left on the
call stack. If <i class="arg">result</i> is present, it will be used as the error
message string; otherwise, a default error message string will be used.</p></dd>
<dt><a name="7"><b class="cmd">thread::unwind</b></a></dt>
<dd><p>Use of this command is deprecated in favour of more advanced thread
reservation system implemented with <b class="cmd">thread::preserve</b> and
<b class="cmd">thread::release</b> commands. Support for <b class="cmd">thread::unwind</b>
command will dissapear in some future major release of the extension.</p>
<p>This command stops a prior <b class="cmd">thread::wait</b> command. Execution of
the script passed to newly created thread will continue from the
<b class="cmd">thread::wait</b> command. If <b class="cmd">thread::wait</b> was the last command
in the script, the thread will exit. The command returns empty result
but may trigger Tcl error with the message &quot;target thread died&quot; in some
situations.</p></dd>
<dt><a name="8"><b class="cmd">thread::exit</b> <span class="opt">?status?</span></a></dt>
<dd><p>Use of this command is deprecated in favour of more advanced thread
reservation system implemented with <b class="cmd">thread::preserve</b> and
<b class="cmd">thread::release</b> commands. Support for <b class="cmd">thread::exit</b>
command will dissapear in some future major release of the extension.</p>
<p>This command forces a thread stuck in the <b class="cmd">thread::wait</b> command to
unconditionaly exit. The thread's exit status defaults to 666 and can be
specified using the optional <i class="arg">status</i> argument. The execution of
<b class="cmd">thread::exit</b> command is guaranteed to leave the program memory in the
unconsistent state, produce memory leaks and otherwise affect other subsytem(s)
of the Tcl application in an unpredictable manner. The command returns empty
result but may trigger Tcl error with the message &quot;target thread died&quot; in some
situations.</p></dd>
<dt><a name="9"><b class="cmd">thread::names</b></a></dt>
<dd><p>This command returns a list of thread IDs. These are only for
threads that have been created via <b class="cmd">thread::create</b> command.
If your application creates other threads at the C level, they
................................................................................
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 <b class="cmd">thread::wait</b> or any other relevant Tcl/Tk
command, like <b class="cmd">update</b>, <b class="cmd">vwait</b>, etc.</p>
<p>Optional <b class="option">varname</b> specifies name of the variable to store
the result of the <i class="arg">script</i>. Without the <b class="option">-async</b> flag,
the command returns the evaluation code, similarily to the standard
Tcl <b class="cmd">catch</b> command. If, however, the <b class="option">-async</b> flag is
specified, the command returns immediately and caller can later
<b class="cmd">vwait</b> on <span class="opt">?varname?</span> to get the result of the passed <i class="arg">script</i></p>
<pre class="doctools_example">
set t1 [thread::create]
set t2 [thread::create]
thread::send -async $t1 &quot;set a 1&quot; result
................................................................................
Upon the join the handle of the thread has gone out of scope and
should not be used any more.</p></dd>
<dt><a name="16"><b class="cmd">thread::configure</b> <i class="arg">id</i> <span class="opt">?option?</span> <span class="opt">?value?</span> <span class="opt">?...?</span></a></dt>
<dd><p>This command configures various low-level aspects of the thread with
ID <i class="arg">id</i> in the similar way as the standard Tcl command
<b class="cmd">fconfigure</b> configures some Tcl channel options. Options currently
supported are: <b class="option">-eventmark</b> and <b class="option">-unwindonerror</b>.</p>
<p>The <b class="option">-eventmark</b> option, when set, limits the number of
asynchronously posted scripts to the thread event loop.The <b class="cmd">thread::send -async</b> command will block until the numberof pending scripts in the event loop does not drop below the valueconfigured with <b class="option">-eventmark</b>. Default value for the<b class="option">-eventmark</b> is 0 (zero) which effectively disables the checking,i.e. allows for unlimited number of posted scripts.</p>
<p>The <b class="option">-unwindonerror</b> option, when set, causes thetarget thread to unwind if the result of the script processingresulted in error. Default value for the <b class="option">-unwindonerror</b>is 0 (false), i.e. thread continues to process scripts after oneof the posted scripts fails.</p></dd>
<dt><a name="17"><b class="cmd">thread::transfer</b> <i class="arg">id</i> <i class="arg">channel</i></a></dt>
<dd><p>This moves the specified <i class="arg">channel</i> from the current thread
and interpreter to the main interpreter of the thread with the
given <i class="arg">id</i>. 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
................................................................................
(or the same) thread attaches the channel again with <b class="cmd">thread::attach</b>.
Restrictions: same as for transferring shared channels with the
<b class="cmd">thread::transfer</b> command.</p></dd>
<dt><a name="19"><b class="cmd">thread::attach</b> <i class="arg">channel</i></a></dt>
<dd><p>This attaches the previously detached <i class="arg">channel</i> 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 <i class="arg">channel</i> cannot be
found in the list of detached channels and/or in the current
interpreter.</p></dd>
<dt><a name="20"><b class="cmd">thread::mutex</b></a></dt>
<dd><p>Mutexes are most common thread synchronization primitives.
They are used to synchronize access from two or more threads to one or
................................................................................
<dd><p>Unlocks the <i class="arg">mutex</i> so some other thread may lock it again.
Attempt to unlock the already unlocked mutex will throw Tcl error.</p></dd>
</dl></dd>
<dt><a name="25"><b class="cmd">thread::rwmutex</b></a></dt>
<dd><p>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 performace by using reader/writer mutexes instead of
exclusive or recursive mutexes.</p>
<p>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.
................................................................................
Attempt to unlock already unlocked <i class="arg">mutex</i> will throw Tcl error.</p></dd>
</dl></dd>
<dt><a name="31"><b class="cmd">thread::cond</b></a></dt>
<dd><p>This command provides script-level access to condition variables.
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 condition
variable, a Tcl error will be thrown.</p>
<p>The command supports following subcommands and options:</p>
<dl class="doctools_definitions">
<dt><a name="32"><b class="cmd">thread::cond</b> <b class="method">create</b></a></dt>
<dd><p>Creates the condition variable and returns it's opaque handle.
This handle should be used for any future reference to newly
created condition variable.</p></dd>

<!DOCTYPE html><html><head>
<title>thread - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- thread.n
-->
<body><div class="doctools">
<h1 class="doctools_title">thread(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>thread - Extension for script access to Tcl threading</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
</ul>
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>The <b class="package">thread</b> extension creates threads that contain Tcl
interpreters, and it lets you send scripts to those threads for
evaluation.
Additionally, it provides script-level access to basic thread
synchronization primitives, like mutexes and condition variables.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">COMMANDS</a></h2>
<p>This section describes commands for creating and destroying threads
and sending scripts to threads for evaluation.</p>
<dl class="doctools_definitions">
<dt><a name="1"><b class="cmd">thread::create</b> <span class="opt">?-joinable?</span> <span class="opt">?-preserved?</span> <span class="opt">?script?</span></a></dt>
................................................................................
<p>Threads created by the <b class="cmd">thread::create</b> cannot be destroyed
forcefully. Consequently, there is no corresponding thread destroy
command. A thread may only be released using the <b class="cmd">thread::release</b>
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 <b class="option">script</b> argument, following the <b class="cmd">thread::wait</b>
command. If this was the last command in the script, as usually the
case, the thread will exit.</p>
<p>It is possible to create a situation in which it may be impossible
to terminate the thread, for example by putting some endless loop
after the <b class="cmd">thread::wait</b> 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:</p>
................................................................................
wait endlessly for events. There is no way one can terminate such thread,
so you wouldn't want to do this!</p>
<p>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
<b class="cmd">thread::preserve</b> and decremented by a call to <b class="cmd">thread::release</b>
command. These two commands implement simple but effective thread
reservation system and offer predictable and controllable thread
termination capabilities. It is however possible to create initially
preserved threads by using flag <b class="option">-preserved</b> of the
<b class="cmd">thread::create</b> command. Threads created with this flag have the
initial value of the reference counter of 1 (one), and are thus
initially marked reserved.</p></dd>
<dt><a name="2"><b class="cmd">thread::preserve</b> <span class="opt">?id?</span></a></dt>
<dd><p>This command increments the thread reference counter. Each call
to this command increments the reference counter by one (1).
................................................................................
until there are no further invocations of the interpreter left on the
call stack. If <i class="arg">result</i> is present, it will be used as the error
message string; otherwise, a default error message string will be used.</p></dd>
<dt><a name="7"><b class="cmd">thread::unwind</b></a></dt>
<dd><p>Use of this command is deprecated in favour of more advanced thread
reservation system implemented with <b class="cmd">thread::preserve</b> and
<b class="cmd">thread::release</b> commands. Support for <b class="cmd">thread::unwind</b>
command will disappear in some future major release of the extension.</p>
<p>This command stops a prior <b class="cmd">thread::wait</b> command. Execution of
the script passed to newly created thread will continue from the
<b class="cmd">thread::wait</b> command. If <b class="cmd">thread::wait</b> was the last command
in the script, the thread will exit. The command returns empty result
but may trigger Tcl error with the message &quot;target thread died&quot; in some
situations.</p></dd>
<dt><a name="8"><b class="cmd">thread::exit</b> <span class="opt">?status?</span></a></dt>
<dd><p>Use of this command is deprecated in favour of more advanced thread
reservation system implemented with <b class="cmd">thread::preserve</b> and
<b class="cmd">thread::release</b> commands. Support for <b class="cmd">thread::exit</b>
command will disappear in some future major release of the extension.</p>
<p>This command forces a thread stuck in the <b class="cmd">thread::wait</b> command to
unconditionally exit. The thread's exit status defaults to 666 and can be
specified using the optional <i class="arg">status</i> argument. The execution of
<b class="cmd">thread::exit</b> command is guaranteed to leave the program memory in the
inconsistent state, produce memory leaks and otherwise affect other subsystem(s)
of the Tcl application in an unpredictable manner. The command returns empty
result but may trigger Tcl error with the message &quot;target thread died&quot; in some
situations.</p></dd>
<dt><a name="9"><b class="cmd">thread::names</b></a></dt>
<dd><p>This command returns a list of thread IDs. These are only for
threads that have been created via <b class="cmd">thread::create</b> command.
If your application creates other threads at the C level, they
................................................................................
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 <b class="cmd">thread::wait</b> or any other relevant Tcl/Tk
command, like <b class="cmd">update</b>, <b class="cmd">vwait</b>, etc.</p>
<p>Optional <b class="option">varname</b> specifies name of the variable to store
the result of the <i class="arg">script</i>. Without the <b class="option">-async</b> flag,
the command returns the evaluation code, similarly to the standard
Tcl <b class="cmd">catch</b> command. If, however, the <b class="option">-async</b> flag is
specified, the command returns immediately and caller can later
<b class="cmd">vwait</b> on <span class="opt">?varname?</span> to get the result of the passed <i class="arg">script</i></p>
<pre class="doctools_example">
set t1 [thread::create]
set t2 [thread::create]
thread::send -async $t1 &quot;set a 1&quot; result
................................................................................
Upon the join the handle of the thread has gone out of scope and
should not be used any more.</p></dd>
<dt><a name="16"><b class="cmd">thread::configure</b> <i class="arg">id</i> <span class="opt">?option?</span> <span class="opt">?value?</span> <span class="opt">?...?</span></a></dt>
<dd><p>This command configures various low-level aspects of the thread with
ID <i class="arg">id</i> in the similar way as the standard Tcl command
<b class="cmd">fconfigure</b> configures some Tcl channel options. Options currently
supported are: <b class="option">-eventmark</b> and <b class="option">-unwindonerror</b>.</p>
<p>When <b class="option">-eventmark</b> is provided with a value greater than 0 (zero), thatvalue is the maximum number of asynchronously posted scripts that may bepending for the thread. <b class="cmd">thread::send -async</b> blocks until the number of
pending scripts in the event loop drops below the <b class="option">-eventmark</b> value.</p><p>When <b class="option">-unwindonerror</b> is provided with a value of true, an error resultin a script causes the thread to unwind, making it unavailable to evaluateadditional scripts.</p></dd>
<dt><a name="17"><b class="cmd">thread::transfer</b> <i class="arg">id</i> <i class="arg">channel</i></a></dt>
<dd><p>This moves the specified <i class="arg">channel</i> from the current thread
and interpreter to the main interpreter of the thread with the
given <i class="arg">id</i>. 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
................................................................................
(or the same) thread attaches the channel again with <b class="cmd">thread::attach</b>.
Restrictions: same as for transferring shared channels with the
<b class="cmd">thread::transfer</b> command.</p></dd>
<dt><a name="19"><b class="cmd">thread::attach</b> <i class="arg">channel</i></a></dt>
<dd><p>This attaches the previously detached <i class="arg">channel</i> 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 actually
perform the operation, while all subsequent operation will just
do nothing. Command throws error if the <i class="arg">channel</i> cannot be
found in the list of detached channels and/or in the current
interpreter.</p></dd>
<dt><a name="20"><b class="cmd">thread::mutex</b></a></dt>
<dd><p>Mutexes are most common thread synchronization primitives.
They are used to synchronize access from two or more threads to one or
................................................................................
<dd><p>Unlocks the <i class="arg">mutex</i> so some other thread may lock it again.
Attempt to unlock the already unlocked mutex will throw Tcl error.</p></dd>
</dl></dd>
<dt><a name="25"><b class="cmd">thread::rwmutex</b></a></dt>
<dd><p>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 performance by using reader/writer mutexes instead of
exclusive or recursive mutexes.</p>
<p>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.
................................................................................
Attempt to unlock already unlocked <i class="arg">mutex</i> will throw Tcl error.</p></dd>
</dl></dd>
<dt><a name="31"><b class="cmd">thread::cond</b></a></dt>
<dd><p>This command provides script-level access to condition variables.
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 conjunction with an exclusive mutex. If you attempt
to use other type of mutex in conjunction with the condition
variable, a Tcl error will be thrown.</p>
<p>The command supports following subcommands and options:</p>
<dl class="doctools_definitions">
<dt><a name="32"><b class="cmd">thread::cond</b> <b class="method">create</b></a></dt>
<dd><p>Creates the condition variable and returns it's opaque handle.
This handle should be used for any future reference to newly
created condition variable.</p></dd>

<html><head>
<title>tpool - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- tpool.n
-->
<body><div class="doctools">
<h1 class="doctools_title">tpool(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>tpool - Part of the Tcl threading extension implementing pools of worker threads.</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
<dl class="doctools_options">
<dt><b class="option">-minworkers</b> <i class="arg">number</i></dt>
<dd><p>Minimum number of worker threads needed for this threadpool instance.
During threadpool creation, the implementation will create somany
worker threads upfront and will keep at least number of them alive
during the lifetime of the threadpool instance.
Default value of this parameter is 0 (zero). which means that a newly
threadpool will have no worker threads initialy. All worker threads
will be started on demand by callers running <b class="cmd">tpool::post</b> command
and posting jobs to the job queue.</p></dd>
<dt><b class="option">-maxworkers</b> <i class="arg">number</i></dt>
<dd><p>Maximum number of worker threads allowed for this threadpool instance.
If a new job is pending and there are no idle worker threads available,
the implementation will try to create new worker thread. If the number
of available worker threads is lower than the given number,
................................................................................
used to load packages and commands in the worker, set default variables,
create namespaces, and such. If the passed script runs into a Tcl error,
the worker will not be created and the initiating command (either the
<b class="cmd">tpool::create</b> or <b class="cmd">tpool::post</b>) will throw error.
Default value for this option is unspecified, hence, the Tcl interpreter of
the worker thread will contain just the initial set of Tcl commands.</p></dd>
<dt><b class="option">-exitcmd</b> <i class="arg">script</i></dt>
<dd><p>Sets a Tcl script run when the idle worker thread exits. This is normaly
used to cleanup the state of the worker thread, release reserved resources,
cleanup memory and such.
Default value for this option is unspecified, thus no Tcl script will run
on the worker thread exit.</p></dd>
</dl></dd>
<dt><a name="2"><b class="cmd">tpool::names</b></a></dt>
<dd><p>This command returns a list of IDs of threadpools created with the

<!DOCTYPE html><html><head>
<title>tpool - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- tpool.n
-->
<body><div class="doctools">
<h1 class="doctools_title">tpool(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>tpool - Part of the Tcl threading extension implementing pools of worker threads.</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
<dl class="doctools_options">
<dt><b class="option">-minworkers</b> <i class="arg">number</i></dt>
<dd><p>Minimum number of worker threads needed for this threadpool instance.
During threadpool creation, the implementation will create somany
worker threads upfront and will keep at least number of them alive
during the lifetime of the threadpool instance.
Default value of this parameter is 0 (zero). which means that a newly
threadpool will have no worker threads initially. All worker threads
will be started on demand by callers running <b class="cmd">tpool::post</b> command
and posting jobs to the job queue.</p></dd>
<dt><b class="option">-maxworkers</b> <i class="arg">number</i></dt>
<dd><p>Maximum number of worker threads allowed for this threadpool instance.
If a new job is pending and there are no idle worker threads available,
the implementation will try to create new worker thread. If the number
of available worker threads is lower than the given number,
................................................................................
used to load packages and commands in the worker, set default variables,
create namespaces, and such. If the passed script runs into a Tcl error,
the worker will not be created and the initiating command (either the
<b class="cmd">tpool::create</b> or <b class="cmd">tpool::post</b>) will throw error.
Default value for this option is unspecified, hence, the Tcl interpreter of
the worker thread will contain just the initial set of Tcl commands.</p></dd>
<dt><b class="option">-exitcmd</b> <i class="arg">script</i></dt>
<dd><p>Sets a Tcl script run when the idle worker thread exits. This is normally
used to cleanup the state of the worker thread, release reserved resources,
cleanup memory and such.
Default value for this option is unspecified, thus no Tcl script will run
on the worker thread exit.</p></dd>
</dl></dd>
<dt><a name="2"><b class="cmd">tpool::names</b></a></dt>
<dd><p>This command returns a list of IDs of threadpools created with the

<html><head>
<title>tsv - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- tsv.n
-->
<body><div class="doctools">
<h1 class="doctools_title">tsv(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>tsv - Part of the Tcl threading extension allowing script level manipulation of data shared between threads.</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>This section describes commands implementing thread shared variables.
A thread shared variable is very similar to a Tcl array but in
contrast to a Tcl array it is created in shared memory and can
be accessed from many threads at the same time. Important feature of
thread shared variable is that each access to the variable is internaly
protected by a mutex so script programmer does not have to take care
about locking the variable himself.</p>
<p>Thread shared variables are not bound to any thread explicitly. That
means that when a thread which created any of thread shared variables
exits, the variable and associated memory is not unset/reclaimed.
User has to explicitly unset the variable to reclaim the memory
consumed by the variable.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">ELEMENT COMMANDS</a></h2>
<dl class="doctools_definitions">
<dt><a name="1"><b class="cmd">tsv::names</b> <span class="opt">?pattern?</span></a></dt>
<dd><p>Returns names of shared variables matching optional <span class="opt">?pattern?</span>
or all known variables if pattern is ommited.</p></dd>
<dt><a name="2"><b class="cmd">tsv::object</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Creates object accessor command for the <i class="arg">element</i> in the
shared variable <i class="arg">varname</i>. Using this command, one can apply most
of the other shared variable commands as method functions of
the element object command. The object command is automatically
deleted when the element which this command is pointing to is unset.</p>
<pre class="doctools_example">
................................................................................
% $string append &quot; appended&quot;
=&gt; A shared string appended
</pre>
</dd>
<dt><a name="3"><b class="cmd">tsv::set</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?value?</span></a></dt>
<dd><p>Sets the value of the <i class="arg">element</i> in the shared variable <i class="arg">varname</i>
to <i class="arg">value</i> and returns the value to caller. The <i class="arg">value</i>
may be ommited, in which case the command will return the current
value of the element. If the element cannot be found, error is triggered.</p></dd>
<dt><a name="4"><b class="cmd">tsv::get</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?namedvar?</span></a></dt>
<dd><p>Retrieves the value of the <i class="arg">element</i> from the shared variable <i class="arg">varname</i>.
If the optional argument <i class="arg">namedvar</i> is given, the value is
stored in the named variable. Return value of the command depends
of the existence of the optional argument <i class="arg">namedvar</i>.
If the argument is ommited and the requested element cannot be found
in the shared array, the command triggers error. If, however, the
optional argument is given on the command line, the command returns
true (1) if the element is found or false (0) if the element is not found.</p></dd>
<dt><a name="5"><b class="cmd">tsv::unset</b> <i class="arg">varname</i> <span class="opt">?element?</span></a></dt>
<dd><p>Unsets the <i class="arg">element</i> from the shared variable <i class="arg">varname</i>.
If the optional element is not given, it deletes the variable.</p></dd>
<dt><a name="6"><b class="cmd">tsv::exists</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Checks wether the <i class="arg">element</i> exists in the shared variable <i class="arg">varname</i>
and returns true (1) if it does or false (0) if it doesn't.</p></dd>
<dt><a name="7"><b class="cmd">tsv::pop</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Returns value of the <i class="arg">element</i> in the shared variable <i class="arg">varname</i>
and unsets the element, all in one atomic operation.</p></dd>
<dt><a name="8"><b class="cmd">tsv::move</b> <i class="arg">varname</i> <i class="arg">oldname</i> <i class="arg">newname</i></a></dt>
<dd><p>Renames the element <i class="arg">oldname</i> to the <i class="arg">newname</i> in the
shared variable <i class="arg">varname</i>. This effectively performs an get/unset/set
sequence of operations but all in one atomic step.</p></dd>
<dt><a name="9"><b class="cmd">tsv::incr</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?count?</span></a></dt>
<dd><p>Similar to standard Tcl <b class="cmd">incr</b> command but increments the value
of the <i class="arg">element</i> in shared variaboe <i class="arg">varname</i> instead of
the Tcl variable.</p></dd>
<dt><a name="10"><b class="cmd">tsv::append</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">value</i> <span class="opt">?value ...?</span></a></dt>
<dd><p>Similar to standard Tcl <b class="cmd">append</b> command but appends one or more
values to the <i class="arg">element</i> in shared variable <i class="arg">varname</i> instead of the
Tcl variable.</p></dd>
<dt><a name="11"><b class="cmd">tsv::lock</b> <i class="arg">varname</i> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></dt>
<dd><p>This command concatenates passed arguments and evaluates the
................................................................................
<dt><a name="21"><b class="cmd">tsv::lpop</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
<dd><p>Similar to the standard Tcl <b class="cmd">lindex</b> command but in addition to
returning, it also splices the value out of the <i class="arg">element</i>
from the shared variable <i class="arg">varname</i> in one atomic operation.
In contrast to the Tcl <b class="cmd">lindex</b> command, this command returns
no value to the caller.</p></dd>
<dt><a name="22"><b class="cmd">tsv::lpush</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
<dd><p>This command performes the opposite of the <b class="cmd">tsv::lpop</b> command.
As its counterpart, it returns no value to the caller.</p></dd>
</dl>
</div>
<div id="section4" class="doctools_section"><h2><a name="section4">ARRAY COMMANDS</a></h2>
<p>This command supports most of the options of the standard Tcl
<b class="cmd">array</b> command. In addition to those, it allows binding
a shared variable to some persisten storage databases. Currently the persistent
options supported are the famous GNU Gdbm and LMDB. These options have to be
selected during the package compilation time.
The implementation provides hooks for defining other persistency layers, if
needed.</p>
<dl class="doctools_definitions">
<dt><a name="23"><b class="cmd">tsv::array set</b> <i class="arg">varname</i> <i class="arg">list</i></a></dt>
<dd><p>Does the same as standard Tcl <b class="cmd">array set</b>.</p></dd>
................................................................................
command will return 0, and <i class="arg">retvar</i> will be left unchanged. If {} is
specified for <i class="arg">retvar</i>, the value is not returned, allowing the Tcl
programmer to determine if a <i class="arg">key</i> is present in a keyed list without
setting a variable as a side-effect.</p></dd>
<dt><a name="33"><b class="cmd">tsv::keylkeys</b> <i class="arg">varname</i> <i class="arg">keylist</i> <span class="opt">?key?</span></a></dt>
<dd><p>Return the a list of the keys in the keyed list <i class="arg">keylist</i> in the
shared variable <i class="arg">varname</i>. If <i class="arg">key</i> is specified, then it is
the name of a key field who's subfield keys are to be retrieved.</p></dd>
<dt><a name="34"><b class="cmd">tsv::keylset</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i> <i class="arg">value</i> <span class="opt">?key value..?</span></a></dt>
<dd><p>Set the value associated with <i class="arg">key</i>, in the keyed list <i class="arg">keylist</i>
to <i class="arg">value</i>. If the <i class="arg">keylist</i> does not exists, it is created.
If <i class="arg">key</i> is not currently in the list, it will be added. If it already
exists, <i class="arg">value</i> replaces the existing value. Multiple keywords and
values may be specified, if desired.</p></dd>
</dl>
................................................................................
improving performance. Special care has been taken to assure that all
object data is properly locked and deep-copied when moving objects between
threads.</p>
<p>Due to the internal design of the Tcl core, there is no provision of full
integration of shared variables within the Tcl syntax, unfortunately. All
access to shared data must be performed with the supplied package commands.
Also, variable traces are not supported. But even so, benefits of easy,
simple and safe shared data manipulation outweights imposed limitations.</p>
</div>
<div id="section7" class="doctools_section"><h2><a name="section7">CREDITS</a></h2>
<p>Thread shared variables are inspired by the nsv interface found in
AOLserver, a highly scalable Web server from America Online.</p>
</div>
<div id="see-also" class="doctools_section"><h2><a name="see-also">See Also</a></h2>
<p>thread, tpool, ttrace</p>
</div>
<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
<p>locking, synchronization, thread shared data, threads</p>
</div>
</div></body></html>

<!DOCTYPE html><html><head>
<title>tsv - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- tsv.n
-->
<body><div class="doctools">
<h1 class="doctools_title">tsv(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>tsv - Part of the Tcl threading extension allowing script level manipulation of data shared between threads.</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>This section describes commands implementing thread shared variables.
A thread shared variable is very similar to a Tcl array but in
contrast to a Tcl array it is created in shared memory and can
be accessed from many threads at the same time. Important feature of
thread shared variable is that each access to the variable is internally
protected by a mutex so script programmer does not have to take care
about locking the variable himself.</p>
<p>Thread shared variables are not bound to any thread explicitly. That
means that when a thread which created any of thread shared variables
exits, the variable and associated memory is not unset/reclaimed.
User has to explicitly unset the variable to reclaim the memory
consumed by the variable.</p>
</div>
<div id="section2" class="doctools_section"><h2><a name="section2">ELEMENT COMMANDS</a></h2>
<dl class="doctools_definitions">
<dt><a name="1"><b class="cmd">tsv::names</b> <span class="opt">?pattern?</span></a></dt>
<dd><p>Returns names of shared variables matching optional <span class="opt">?pattern?</span>
or all known variables if pattern is omitted.</p></dd>
<dt><a name="2"><b class="cmd">tsv::object</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Creates object accessor command for the <i class="arg">element</i> in the
shared variable <i class="arg">varname</i>. Using this command, one can apply most
of the other shared variable commands as method functions of
the element object command. The object command is automatically
deleted when the element which this command is pointing to is unset.</p>
<pre class="doctools_example">
................................................................................
% $string append &quot; appended&quot;
=&gt; A shared string appended
</pre>
</dd>
<dt><a name="3"><b class="cmd">tsv::set</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?value?</span></a></dt>
<dd><p>Sets the value of the <i class="arg">element</i> in the shared variable <i class="arg">varname</i>
to <i class="arg">value</i> and returns the value to caller. The <i class="arg">value</i>
may be omitted, in which case the command will return the current
value of the element. If the element cannot be found, error is triggered.</p></dd>
<dt><a name="4"><b class="cmd">tsv::get</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?namedvar?</span></a></dt>
<dd><p>Retrieves the value of the <i class="arg">element</i> from the shared variable <i class="arg">varname</i>.
If the optional argument <i class="arg">namedvar</i> is given, the value is
stored in the named variable. Return value of the command depends
of the existence of the optional argument <i class="arg">namedvar</i>.
If the argument is omitted and the requested element cannot be found
in the shared array, the command triggers error. If, however, the
optional argument is given on the command line, the command returns
true (1) if the element is found or false (0) if the element is not found.</p></dd>
<dt><a name="5"><b class="cmd">tsv::unset</b> <i class="arg">varname</i> <span class="opt">?element?</span></a></dt>
<dd><p>Unsets the <i class="arg">element</i> from the shared variable <i class="arg">varname</i>.
If the optional element is not given, it deletes the variable.</p></dd>
<dt><a name="6"><b class="cmd">tsv::exists</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Checks whether the <i class="arg">element</i> exists in the shared variable <i class="arg">varname</i>
and returns true (1) if it does or false (0) if it doesn't.</p></dd>
<dt><a name="7"><b class="cmd">tsv::pop</b> <i class="arg">varname</i> <i class="arg">element</i></a></dt>
<dd><p>Returns value of the <i class="arg">element</i> in the shared variable <i class="arg">varname</i>
and unsets the element, all in one atomic operation.</p></dd>
<dt><a name="8"><b class="cmd">tsv::move</b> <i class="arg">varname</i> <i class="arg">oldname</i> <i class="arg">newname</i></a></dt>
<dd><p>Renames the element <i class="arg">oldname</i> to the <i class="arg">newname</i> in the
shared variable <i class="arg">varname</i>. This effectively performs an get/unset/set
sequence of operations but all in one atomic step.</p></dd>
<dt><a name="9"><b class="cmd">tsv::incr</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?count?</span></a></dt>
<dd><p>Similar to standard Tcl <b class="cmd">incr</b> command but increments the value
of the <i class="arg">element</i> in shared variable <i class="arg">varname</i> instead of
the Tcl variable.</p></dd>
<dt><a name="10"><b class="cmd">tsv::append</b> <i class="arg">varname</i> <i class="arg">element</i> <i class="arg">value</i> <span class="opt">?value ...?</span></a></dt>
<dd><p>Similar to standard Tcl <b class="cmd">append</b> command but appends one or more
values to the <i class="arg">element</i> in shared variable <i class="arg">varname</i> instead of the
Tcl variable.</p></dd>
<dt><a name="11"><b class="cmd">tsv::lock</b> <i class="arg">varname</i> <i class="arg">arg</i> <span class="opt">?arg ...?</span></a></dt>
<dd><p>This command concatenates passed arguments and evaluates the
................................................................................
<dt><a name="21"><b class="cmd">tsv::lpop</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
<dd><p>Similar to the standard Tcl <b class="cmd">lindex</b> command but in addition to
returning, it also splices the value out of the <i class="arg">element</i>
from the shared variable <i class="arg">varname</i> in one atomic operation.
In contrast to the Tcl <b class="cmd">lindex</b> command, this command returns
no value to the caller.</p></dd>
<dt><a name="22"><b class="cmd">tsv::lpush</b> <i class="arg">varname</i> <i class="arg">element</i> <span class="opt">?index?</span></a></dt>
<dd><p>This command performs the opposite of the <b class="cmd">tsv::lpop</b> command.
As its counterpart, it returns no value to the caller.</p></dd>
</dl>
</div>
<div id="section4" class="doctools_section"><h2><a name="section4">ARRAY COMMANDS</a></h2>
<p>This command supports most of the options of the standard Tcl
<b class="cmd">array</b> command. In addition to those, it allows binding
a shared variable to some persistent storage databases. Currently the persistent
options supported are the famous GNU Gdbm and LMDB. These options have to be
selected during the package compilation time.
The implementation provides hooks for defining other persistency layers, if
needed.</p>
<dl class="doctools_definitions">
<dt><a name="23"><b class="cmd">tsv::array set</b> <i class="arg">varname</i> <i class="arg">list</i></a></dt>
<dd><p>Does the same as standard Tcl <b class="cmd">array set</b>.</p></dd>
................................................................................
command will return 0, and <i class="arg">retvar</i> will be left unchanged. If {} is
specified for <i class="arg">retvar</i>, the value is not returned, allowing the Tcl
programmer to determine if a <i class="arg">key</i> is present in a keyed list without
setting a variable as a side-effect.</p></dd>
<dt><a name="33"><b class="cmd">tsv::keylkeys</b> <i class="arg">varname</i> <i class="arg">keylist</i> <span class="opt">?key?</span></a></dt>
<dd><p>Return the a list of the keys in the keyed list <i class="arg">keylist</i> in the
shared variable <i class="arg">varname</i>. If <i class="arg">key</i> is specified, then it is
the name of a key field whose subfield keys are to be retrieved.</p></dd>
<dt><a name="34"><b class="cmd">tsv::keylset</b> <i class="arg">varname</i> <i class="arg">keylist</i> <i class="arg">key</i> <i class="arg">value</i> <span class="opt">?key value..?</span></a></dt>
<dd><p>Set the value associated with <i class="arg">key</i>, in the keyed list <i class="arg">keylist</i>
to <i class="arg">value</i>. If the <i class="arg">keylist</i> does not exists, it is created.
If <i class="arg">key</i> is not currently in the list, it will be added. If it already
exists, <i class="arg">value</i> replaces the existing value. Multiple keywords and
values may be specified, if desired.</p></dd>
</dl>
................................................................................
improving performance. Special care has been taken to assure that all
object data is properly locked and deep-copied when moving objects between
threads.</p>
<p>Due to the internal design of the Tcl core, there is no provision of full
integration of shared variables within the Tcl syntax, unfortunately. All
access to shared data must be performed with the supplied package commands.
Also, variable traces are not supported. But even so, benefits of easy,
simple and safe shared data manipulation outweighs imposed limitations.</p>
</div>
<div id="section7" class="doctools_section"><h2><a name="section7">CREDITS</a></h2>
<p>Thread shared variables are inspired by the nsv interface found in
AOLserver, a highly scalable Web server from America Online.</p>
</div>
<div id="see-also" class="doctools_section"><h2><a name="see-also">See Also</a></h2>
<p>thread, tpool, ttrace</p>
</div>
<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
<p>locking, synchronization, thread shared data, threads</p>
</div>
</div></body></html>

<html><head>
<title>ttrace - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- ttrace.n
-->
<body><div class="doctools">
<h1 class="doctools_title">ttrace(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>ttrace - Trace-based interpreter initialization</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
<li><a href="#16"><b class="cmd">ttrace::delentry</b> <i class="arg">cmd</i></a></li>
<li><a href="#17"><b class="cmd">ttrace::preload</b> <i class="arg">cmd</i></a></li>
</ul>
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>This package creates a framework for on-demand replication of the
interpreter state accross threads in an multithreading application.
It relies on the mechanics of Tcl command tracing and the Tcl
<b class="cmd">unknown</b> command and mechanism.</p>
<p>The package requires Tcl threading extension but can be alternatively
used stand-alone within the AOLserver, a scalable webserver from
America Online.</p>
<p>In a nutshell, a short sample illustrating the usage of the ttrace
with the Tcl threading extension:</p>
................................................................................
epoch change. For the Tcl threading extension, all threads created by
the extension are automatically updated. If the command execution
resulted in Tcl error, no state propagation takes place.</p>
<p>This is the most important user-level command of the package as
it wraps most of the commands described below. This greatly
simplifies things, because user need to learn just this (one)
command in order to effectively use the package. Other commands,
as desribed below, are included mostly for the sake of completeness.</p></dd>
<dt><a name="2"><b class="cmd">ttrace::enable</b></a></dt>
<dd><p>Activates all registered callbacks in the framework
and starts a new trace epoch. The trace epoch encapsulates all
changes done to the interpreter during the time traces are activated.</p></dd>
<dt><a name="3"><b class="cmd">ttrace::disable</b></a></dt>
<dd><p>Deactivates all registered callbacks in the framework
and closes the current trace epoch.</p></dd>
................................................................................
<dd><p>Used to clean-up all on-demand loaded resources in the interpreter.
It effectively brings Tcl interpreter to its pristine state.</p></dd>
<dt><a name="5"><b class="cmd">ttrace::update</b> <span class="opt">?epoch?</span></a></dt>
<dd><p>Used to refresh the state of the interpreter to match the optional
trace <span class="opt">?epoch?</span>. If the optional <span class="opt">?epoch?</span> is not given, it takes
the most recent trace epoch.</p></dd>
<dt><a name="6"><b class="cmd">ttrace::getscript</b></a></dt>
<dd><p>Returns a synthetized Tcl script which may be sourced in any interpreter.
This script sets the stage for the Tcl <b class="cmd">unknown</b> command so it can
load traced resources from the in-memory database. Normally, this command
is automatically invoked by other higher-level commands like
<b class="cmd">ttrace::eval</b> and <b class="cmd">ttrace::update</b>.</p></dd>
</dl>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">CALLBACK COMMANDS</a></h2>
<p>A word upfront: the package already includes callbacks for tracing
following Tcl commands: <b class="cmd">proc</b>, <b class="cmd">namespace</b>, <b class="cmd">variable</b>,
<b class="cmd">load</b>, and <b class="cmd">rename</b>. Additionaly, a set of callbacks for
tracing resources (object, clasess) for the XOTcl v1.3.8+, an
OO-extension to Tcl, is also provided.
This gives a solid base for solving most of the real-life needs and
serves as an example for people wanting to customize the package
to cover their specific needs.</p>
<p>Below, you can find commands for registering callbacks in the
framework and for writing callback scripts. These callbacks are
invoked by the framework in order to gather interpreter state
................................................................................
creates the requested resource in the interpreter on demand.
This way, users can update just one interpreter (master) in one
thread and replicate that interpreter state (or part of it) to other
threads/interpreters in the process.</p>
<p>Immediate benefit of such approach is the much smaller memory footprint
of the application and much faster thread creation. By not actually
loading all necessary procedures (and other resources) in every thread
at the thread initialization time, but by deffering this to the time the
resource is actually referenced, significant improvements in both
memory consumption and thread initialization time can be achieved. Some
tests have shown that memory footprint of an multithreading Tcl application
went down more than three times and thread startup time was reduced for
about 50 times. Note that your mileage may vary.
Other benefits include much finer control about what (and when) gets
replicated from the master to other Tcl thread/interpreters.</p>

<!DOCTYPE html><html><head>
<title>ttrace - Tcl Threading</title>
<style type="text/css"><!--
HTML {
background: #FFFFFF;
color: black;
}
BODY {
................................................................................
}
UL.doctools_requirements {
margin-bottom: 1em;
border-bottom: 1px solid black;
}
--></style>
</head>
<!-- Generated from file '' by tcllib/doctools with format 'html'
-->
<!-- ttrace.n
-->
<body><div class="doctools">
<h1 class="doctools_title">ttrace(n) 2.8 &quot;Tcl Threading&quot;</h1>
<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
<p>ttrace - Trace-based interpreter initialization</p>
</div>
<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
................................................................................
<li><a href="#16"><b class="cmd">ttrace::delentry</b> <i class="arg">cmd</i></a></li>
<li><a href="#17"><b class="cmd">ttrace::preload</b> <i class="arg">cmd</i></a></li>
</ul>
</div>
</div>
<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
<p>This package creates a framework for on-demand replication of the
interpreter state across threads in an multithreading application.
It relies on the mechanics of Tcl command tracing and the Tcl
<b class="cmd">unknown</b> command and mechanism.</p>
<p>The package requires Tcl threading extension but can be alternatively
used stand-alone within the AOLserver, a scalable webserver from
America Online.</p>
<p>In a nutshell, a short sample illustrating the usage of the ttrace
with the Tcl threading extension:</p>
................................................................................
epoch change. For the Tcl threading extension, all threads created by
the extension are automatically updated. If the command execution
resulted in Tcl error, no state propagation takes place.</p>
<p>This is the most important user-level command of the package as
it wraps most of the commands described below. This greatly
simplifies things, because user need to learn just this (one)
command in order to effectively use the package. Other commands,
as described below, are included mostly for the sake of completeness.</p></dd>
<dt><a name="2"><b class="cmd">ttrace::enable</b></a></dt>
<dd><p>Activates all registered callbacks in the framework
and starts a new trace epoch. The trace epoch encapsulates all
changes done to the interpreter during the time traces are activated.</p></dd>
<dt><a name="3"><b class="cmd">ttrace::disable</b></a></dt>
<dd><p>Deactivates all registered callbacks in the framework
and closes the current trace epoch.</p></dd>
................................................................................
<dd><p>Used to clean-up all on-demand loaded resources in the interpreter.
It effectively brings Tcl interpreter to its pristine state.</p></dd>
<dt><a name="5"><b class="cmd">ttrace::update</b> <span class="opt">?epoch?</span></a></dt>
<dd><p>Used to refresh the state of the interpreter to match the optional
trace <span class="opt">?epoch?</span>. If the optional <span class="opt">?epoch?</span> is not given, it takes
the most recent trace epoch.</p></dd>
<dt><a name="6"><b class="cmd">ttrace::getscript</b></a></dt>
<dd><p>Returns a synthesized Tcl script which may be sourced in any interpreter.
This script sets the stage for the Tcl <b class="cmd">unknown</b> command so it can
load traced resources from the in-memory database. Normally, this command
is automatically invoked by other higher-level commands like
<b class="cmd">ttrace::eval</b> and <b class="cmd">ttrace::update</b>.</p></dd>
</dl>
</div>
<div id="section3" class="doctools_section"><h2><a name="section3">CALLBACK COMMANDS</a></h2>
<p>A word upfront: the package already includes callbacks for tracing
following Tcl commands: <b class="cmd">proc</b>, <b class="cmd">namespace</b>, <b class="cmd">variable</b>,
<b class="cmd">load</b>, and <b class="cmd">rename</b>. Additionally, a set of callbacks for
tracing resources (object, classes) for the XOTcl v1.3.8+, an
OO-extension to Tcl, is also provided.
This gives a solid base for solving most of the real-life needs and
serves as an example for people wanting to customize the package
to cover their specific needs.</p>
<p>Below, you can find commands for registering callbacks in the
framework and for writing callback scripts. These callbacks are
invoked by the framework in order to gather interpreter state
................................................................................
creates the requested resource in the interpreter on demand.
This way, users can update just one interpreter (master) in one
thread and replicate that interpreter state (or part of it) to other
threads/interpreters in the process.</p>
<p>Immediate benefit of such approach is the much smaller memory footprint
of the application and much faster thread creation. By not actually
loading all necessary procedures (and other resources) in every thread
at the thread initialization time, but by deferring this to the time the
resource is actually referenced, significant improvements in both
memory consumption and thread initialization time can be achieved. Some
tests have shown that memory footprint of an multithreading Tcl application
went down more than three times and thread startup time was reduced for
about 50 times. Note that your mileage may vary.
Other benefits include much finer control about what (and when) gets
replicated from the master to other Tcl thread/interpreters.</p>

\fBthread::cond\fR \fBwait\fR \fIcond\fR \fImutex\fR ?ms?
.sp
.BE
.SH DESCRIPTION
The \fBthread\fR 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 primitives, like mutexes and condition variables\&.
.SH COMMANDS
This section describes commands for creating and destroying threads
and sending scripts to threads for evaluation\&.
.TP
\fBthread::create\fR ?-joinable? ?-preserved? ?script?
This command creates a thread that contains a Tcl interpreter\&.
................................................................................
Threads created by the \fBthread::create\fR cannot be destroyed
forcefully\&. Consequently, there is no corresponding thread destroy
command\&. A thread may only be released using the \fBthread::release\fR
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 \fBscript\fR argument, following the \fBthread::wait\fR
command\&. If this was the last command in the script, as usualy the
case, the thread will exit\&.
.sp
It is possible to create a situation in which it may be impossible
to terminate the thread, for example by putting some endless loop
after the \fBthread::wait\fR 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
................................................................................
so you wouldn't want to do this!
.sp
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
\fBthread::preserve\fR and decremented by a call to \fBthread::release\fR
command\&. These two commands implement simple but effective thread
reservation system and offer predictable and controllable thread
termination capabilities\&. It is however possible to create initialy
preserved threads by using flag \fB-preserved\fR of the
\fBthread::create\fR command\&. Threads created with this flag have the
initial value of the reference counter of 1 (one), and are thus
initially marked reserved\&.
.TP
\fBthread::preserve\fR ?id?
This command increments the thread reference counter\&. Each call
................................................................................
call stack\&. If \fIresult\fR is present, it will be used as the error
message string; otherwise, a default error message string will be used\&.
.TP
\fBthread::unwind\fR
Use of this command is deprecated in favour of more advanced thread
reservation system implemented with \fBthread::preserve\fR and
\fBthread::release\fR commands\&. Support for \fBthread::unwind\fR
command will dissapear in some future major release of the extension\&.
.sp
This command stops a prior \fBthread::wait\fR command\&. Execution of
the script passed to newly created thread will continue from the
\fBthread::wait\fR command\&. If \fBthread::wait\fR 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\&.
.TP
\fBthread::exit\fR ?status?
Use of this command is deprecated in favour of more advanced thread
reservation system implemented with \fBthread::preserve\fR and
\fBthread::release\fR commands\&. Support for \fBthread::exit\fR
command will dissapear in some future major release of the extension\&.
.sp
This command forces a thread stuck in the \fBthread::wait\fR command to
unconditionaly exit\&. The thread's exit status defaults to 666 and can be
specified using the optional \fIstatus\fR argument\&. The execution of
\fBthread::exit\fR command is guaranteed to leave the program memory in the
unconsistent state, produce memory leaks and otherwise affect other subsytem(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\&.
.TP
\fBthread::names\fR
This command returns a list of thread IDs\&. These are only for
threads that have been created via \fBthread::create\fR command\&.
................................................................................
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 \fBthread::wait\fR or any other relevant Tcl/Tk
command, like \fBupdate\fR, \fBvwait\fR, etc\&.
.sp
Optional \fBvarname\fR specifies name of the variable to store
the result of the \fIscript\fR\&. Without the \fB-async\fR flag,
the command returns the evaluation code, similarily to the standard
Tcl \fBcatch\fR command\&. If, however, the \fB-async\fR flag is
specified, the command returns immediately and caller can later
\fBvwait\fR on ?varname? to get the result of the passed \fIscript\fR
.CS
set t1 [thread::create]
................................................................................
.TP
\fBthread::configure\fR \fIid\fR ?option? ?value? ?\&.\&.\&.?
This command configures various low-level aspects of the thread with
ID \fIid\fR in the similar way as the standard Tcl command
\fBfconfigure\fR configures some Tcl channel options\&. Options currently
supported are: \fB-eventmark\fR and \fB-unwindonerror\fR\&.
.sp
The \fB-eventmark\fR option, when set, limits the number of
asynchronously posted scripts to the thread event loop\&.The \fBthread::send -async\fR command will block until the numberof pending scripts in the event loop does not drop below the valueconfigured with \fB-eventmark\fR\&. Default value for the\fB-eventmark\fR is 0 (zero) which effectively disables the checking,i\&.e\&. allows for unlimited number of posted scripts\&.
.sp
The \fB-unwindonerror\fR option, when set, causes thetarget thread to unwind if the result of the script processingresulted in error\&. Default value for the \fB-unwindonerror\fRis 0 (false), i\&.e\&. thread continues to process scripts after oneof the posted scripts fails\&.
.TP
\fBthread::transfer\fR \fIid\fR \fIchannel\fR
This moves the specified \fIchannel\fR from the current thread
and interpreter to the main interpreter of the thread with the
given \fIid\fR\&. 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\&.
................................................................................
Restrictions: same as for transferring shared channels with the
\fBthread::transfer\fR command\&.
.TP
\fBthread::attach\fR \fIchannel\fR
This attaches the previously detached \fIchannel\fR 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 \fIchannel\fR cannot be
found in the list of detached channels and/or in the current
interpreter\&.
.TP
\fBthread::mutex\fR
Mutexes are most common thread synchronization primitives\&.
................................................................................
.RE
.sp
.TP
\fBthread::rwmutex\fR
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 performace by using reader/writer mutexes instead of
exclusive or recursive mutexes\&.
.sp
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
................................................................................
.sp
.TP
\fBthread::cond\fR
This command provides script-level access to condition variables\&.
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 condition
variable, a Tcl error will be thrown\&.
.sp
The command supports following subcommands and options:
.RS
.TP
\fBthread::cond\fR \fBcreate\fR
Creates the condition variable and returns it's opaque handle\&.

\fBthread::cond\fR \fBwait\fR \fIcond\fR \fImutex\fR ?ms?
.sp
.BE
.SH DESCRIPTION
The \fBthread\fR extension creates threads that contain Tcl
interpreters, and it lets you send scripts to those threads for
evaluation\&.
Additionally, it provides script-level access to basic thread
synchronization primitives, like mutexes and condition variables\&.
.SH COMMANDS
This section describes commands for creating and destroying threads
and sending scripts to threads for evaluation\&.
.TP
\fBthread::create\fR ?-joinable? ?-preserved? ?script?
This command creates a thread that contains a Tcl interpreter\&.
................................................................................
Threads created by the \fBthread::create\fR cannot be destroyed
forcefully\&. Consequently, there is no corresponding thread destroy
command\&. A thread may only be released using the \fBthread::release\fR
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 \fBscript\fR argument, following the \fBthread::wait\fR
command\&. If this was the last command in the script, as usually the
case, the thread will exit\&.
.sp
It is possible to create a situation in which it may be impossible
to terminate the thread, for example by putting some endless loop
after the \fBthread::wait\fR 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
................................................................................
so you wouldn't want to do this!
.sp
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
\fBthread::preserve\fR and decremented by a call to \fBthread::release\fR
command\&. These two commands implement simple but effective thread
reservation system and offer predictable and controllable thread
termination capabilities\&. It is however possible to create initially
preserved threads by using flag \fB-preserved\fR of the
\fBthread::create\fR command\&. Threads created with this flag have the
initial value of the reference counter of 1 (one), and are thus
initially marked reserved\&.
.TP
\fBthread::preserve\fR ?id?
This command increments the thread reference counter\&. Each call
................................................................................
call stack\&. If \fIresult\fR is present, it will be used as the error
message string; otherwise, a default error message string will be used\&.
.TP
\fBthread::unwind\fR
Use of this command is deprecated in favour of more advanced thread
reservation system implemented with \fBthread::preserve\fR and
\fBthread::release\fR commands\&. Support for \fBthread::unwind\fR
command will disappear in some future major release of the extension\&.
.sp
This command stops a prior \fBthread::wait\fR command\&. Execution of
the script passed to newly created thread will continue from the
\fBthread::wait\fR command\&. If \fBthread::wait\fR 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\&.
.TP
\fBthread::exit\fR ?status?
Use of this command is deprecated in favour of more advanced thread
reservation system implemented with \fBthread::preserve\fR and
\fBthread::release\fR commands\&. Support for \fBthread::exit\fR
command will disappear in some future major release of the extension\&.
.sp
This command forces a thread stuck in the \fBthread::wait\fR command to
unconditionally exit\&. The thread's exit status defaults to 666 and can be
specified using the optional \fIstatus\fR argument\&. The execution of
\fBthread::exit\fR command is guaranteed to leave the program memory in the
inconsistent state, produce memory leaks and otherwise affect other subsystem(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\&.
.TP
\fBthread::names\fR
This command returns a list of thread IDs\&. These are only for
threads that have been created via \fBthread::create\fR command\&.
................................................................................
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 \fBthread::wait\fR or any other relevant Tcl/Tk
command, like \fBupdate\fR, \fBvwait\fR, etc\&.
.sp
Optional \fBvarname\fR specifies name of the variable to store
the result of the \fIscript\fR\&. Without the \fB-async\fR flag,
the command returns the evaluation code, similarly to the standard
Tcl \fBcatch\fR command\&. If, however, the \fB-async\fR flag is
specified, the command returns immediately and caller can later
\fBvwait\fR on ?varname? to get the result of the passed \fIscript\fR
.CS
set t1 [thread::create]
................................................................................
.TP
\fBthread::configure\fR \fIid\fR ?option? ?value? ?\&.\&.\&.?
This command configures various low-level aspects of the thread with
ID \fIid\fR in the similar way as the standard Tcl command
\fBfconfigure\fR configures some Tcl channel options\&. Options currently
supported are: \fB-eventmark\fR and \fB-unwindonerror\fR\&.
.sp
When \fB-eventmark\fR is provided with a value greater than 0 (zero), thatvalue is the maximum number of asynchronously posted scripts that may bepending for the thread\&. \fBthread::send -async\fR blocks until the number of
pending scripts in the event loop drops below the \fB-eventmark\fR value\&.
.sp
When \fB-unwindonerror\fR is provided with a value of true, an error resultin a script causes the thread to unwind, making it unavailable to evaluateadditional scripts\&.
.TP
\fBthread::transfer\fR \fIid\fR \fIchannel\fR
This moves the specified \fIchannel\fR from the current thread
and interpreter to the main interpreter of the thread with the
given \fIid\fR\&. 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\&.
................................................................................
Restrictions: same as for transferring shared channels with the
\fBthread::transfer\fR command\&.
.TP
\fBthread::attach\fR \fIchannel\fR
This attaches the previously detached \fIchannel\fR 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 actually
perform the operation, while all subsequent operation will just
do nothing\&. Command throws error if the \fIchannel\fR cannot be
found in the list of detached channels and/or in the current
interpreter\&.
.TP
\fBthread::mutex\fR
Mutexes are most common thread synchronization primitives\&.
................................................................................
.RE
.sp
.TP
\fBthread::rwmutex\fR
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 performance by using reader/writer mutexes instead of
exclusive or recursive mutexes\&.
.sp
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
................................................................................
.sp
.TP
\fBthread::cond\fR
This command provides script-level access to condition variables\&.
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 conjunction with an exclusive mutex\&. If you attempt
to use other type of mutex in conjunction with the condition
variable, a Tcl error will be thrown\&.
.sp
The command supports following subcommands and options:
.RS
.TP
\fBthread::cond\fR \fBcreate\fR
Creates the condition variable and returns it's opaque handle\&.

.TP
\fB-minworkers\fR \fInumber\fR
Minimum number of worker threads needed for this threadpool instance\&.
During threadpool creation, the implementation will create somany
worker threads upfront and will keep at least number of them alive
during the lifetime of the threadpool instance\&.
Default value of this parameter is 0 (zero)\&. which means that a newly
threadpool will have no worker threads initialy\&. All worker threads
will be started on demand by callers running \fBtpool::post\fR command
and posting jobs to the job queue\&.
.TP
\fB-maxworkers\fR \fInumber\fR
Maximum number of worker threads allowed for this threadpool instance\&.
If a new job is pending and there are no idle worker threads available,
the implementation will try to create new worker thread\&. If the number
................................................................................
create namespaces, and such\&. If the passed script runs into a Tcl error,
the worker will not be created and the initiating command (either the
\fBtpool::create\fR or \fBtpool::post\fR) will throw error\&.
Default value for this option is unspecified, hence, the Tcl interpreter of
the worker thread will contain just the initial set of Tcl commands\&.
.TP
\fB-exitcmd\fR \fIscript\fR
Sets a Tcl script run when the idle worker thread exits\&. This is normaly
used to cleanup the state of the worker thread, release reserved resources,
cleanup memory and such\&.
Default value for this option is unspecified, thus no Tcl script will run
on the worker thread exit\&.
.RE
.sp
.TP

.TP
\fB-minworkers\fR \fInumber\fR
Minimum number of worker threads needed for this threadpool instance\&.
During threadpool creation, the implementation will create somany
worker threads upfront and will keep at least number of them alive
during the lifetime of the threadpool instance\&.
Default value of this parameter is 0 (zero)\&. which means that a newly
threadpool will have no worker threads initially\&. All worker threads
will be started on demand by callers running \fBtpool::post\fR command
and posting jobs to the job queue\&.
.TP
\fB-maxworkers\fR \fInumber\fR
Maximum number of worker threads allowed for this threadpool instance\&.
If a new job is pending and there are no idle worker threads available,
the implementation will try to create new worker thread\&. If the number
................................................................................
create namespaces, and such\&. If the passed script runs into a Tcl error,
the worker will not be created and the initiating command (either the
\fBtpool::create\fR or \fBtpool::post\fR) will throw error\&.
Default value for this option is unspecified, hence, the Tcl interpreter of
the worker thread will contain just the initial set of Tcl commands\&.
.TP
\fB-exitcmd\fR \fIscript\fR
Sets a Tcl script run when the idle worker thread exits\&. This is normally
used to cleanup the state of the worker thread, release reserved resources,
cleanup memory and such\&.
Default value for this option is unspecified, thus no Tcl script will run
on the worker thread exit\&.
.RE
.sp
.TP

.sp
.BE
.SH DESCRIPTION
This section describes commands implementing thread shared variables\&.
A thread shared variable is very similar to a Tcl array but in
contrast to a Tcl array it is created in shared memory and can
be accessed from many threads at the same time\&. Important feature of
thread shared variable is that each access to the variable is internaly
protected by a mutex so script programmer does not have to take care
about locking the variable himself\&.
.PP
Thread shared variables are not bound to any thread explicitly\&. That
means that when a thread which created any of thread shared variables
exits, the variable and associated memory is not unset/reclaimed\&.
User has to explicitly unset the variable to reclaim the memory
consumed by the variable\&.
.SH "ELEMENT COMMANDS"
.TP
\fBtsv::names\fR ?pattern?
Returns names of shared variables matching optional ?pattern?
or all known variables if pattern is ommited\&.
.TP
\fBtsv::object\fR \fIvarname\fR \fIelement\fR
Creates object accessor command for the \fIelement\fR in the
shared variable \fIvarname\fR\&. Using this command, one can apply most
of the other shared variable commands as method functions of
the element object command\&. The object command is automatically
deleted when the element which this command is pointing to is unset\&.
................................................................................
=> A shared string appended
.CE
.TP
\fBtsv::set\fR \fIvarname\fR \fIelement\fR ?value?
Sets the value of the \fIelement\fR in the shared variable \fIvarname\fR
to \fIvalue\fR and returns the value to caller\&. The \fIvalue\fR
may be ommited, in which case the command will return the current
value of the element\&. If the element cannot be found, error is triggered\&.
.TP
\fBtsv::get\fR \fIvarname\fR \fIelement\fR ?namedvar?
Retrieves the value of the \fIelement\fR from the shared variable \fIvarname\fR\&.
If the optional argument \fInamedvar\fR is given, the value is
stored in the named variable\&. Return value of the command depends
of the existence of the optional argument \fInamedvar\fR\&.
If the argument is ommited and the requested element cannot be found
in the shared array, the command triggers error\&. If, however, the
optional argument is given on the command line, the command returns
true (1) if the element is found or false (0) if the element is not found\&.
.TP
\fBtsv::unset\fR \fIvarname\fR ?element?
Unsets the \fIelement\fR from the shared variable \fIvarname\fR\&.
If the optional element is not given, it deletes the variable\&.
.TP
\fBtsv::exists\fR \fIvarname\fR \fIelement\fR
Checks wether the \fIelement\fR exists in the shared variable \fIvarname\fR
and returns true (1) if it does or false (0) if it doesn't\&.
.TP
\fBtsv::pop\fR \fIvarname\fR \fIelement\fR
Returns value of the \fIelement\fR in the shared variable \fIvarname\fR
and unsets the element, all in one atomic operation\&.
.TP
\fBtsv::move\fR \fIvarname\fR \fIoldname\fR \fInewname\fR
Renames the element \fIoldname\fR to the \fInewname\fR in the
shared variable \fIvarname\fR\&. This effectively performs an get/unset/set
sequence of operations but all in one atomic step\&.
.TP
\fBtsv::incr\fR \fIvarname\fR \fIelement\fR ?count?
Similar to standard Tcl \fBincr\fR command but increments the value
of the \fIelement\fR in shared variaboe \fIvarname\fR instead of
the Tcl variable\&.
.TP
\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value \&.\&.\&.?
Similar to standard Tcl \fBappend\fR command but appends one or more
values to the \fIelement\fR in shared variable \fIvarname\fR instead of the
Tcl variable\&.
.TP
................................................................................
Similar to the standard Tcl \fBlindex\fR command but in addition to
returning, it also splices the value out of the \fIelement\fR
from the shared variable \fIvarname\fR in one atomic operation\&.
In contrast to the Tcl \fBlindex\fR command, this command returns
no value to the caller\&.
.TP
\fBtsv::lpush\fR \fIvarname\fR \fIelement\fR ?index?
This command performes the opposite of the \fBtsv::lpop\fR command\&.
As its counterpart, it returns no value to the caller\&.
.PP
.SH "ARRAY COMMANDS"
This command supports most of the options of the standard Tcl
\fBarray\fR command\&. In addition to those, it allows binding
a shared variable to some persisten storage databases\&. Currently the persistent
options supported are the famous GNU Gdbm and LMDB\&. These options have to be
selected during the package compilation time\&.
The implementation provides hooks for defining other persistency layers, if
needed\&.
.TP
\fBtsv::array set\fR \fIvarname\fR \fIlist\fR
Does the same as standard Tcl \fBarray set\fR\&.
................................................................................
specified for \fIretvar\fR, the value is not returned, allowing the Tcl
programmer to determine if a \fIkey\fR is present in a keyed list without
setting a variable as a side-effect\&.
.TP
\fBtsv::keylkeys\fR \fIvarname\fR \fIkeylist\fR ?key?
Return the a list of the keys in the keyed list \fIkeylist\fR in the
shared variable \fIvarname\fR\&. If \fIkey\fR is specified, then it is
the name of a key field who's subfield keys are to be retrieved\&.
.TP
\fBtsv::keylset\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR \fIvalue\fR ?key value\&.\&.?
Set the value associated with \fIkey\fR, in the keyed list \fIkeylist\fR
to \fIvalue\fR\&. If the \fIkeylist\fR does not exists, it is created\&.
If \fIkey\fR is not currently in the list, it will be added\&. If it already
exists, \fIvalue\fR replaces the existing value\&. Multiple keywords and
values may be specified, if desired\&.
................................................................................
object data is properly locked and deep-copied when moving objects between
threads\&.
.PP
Due to the internal design of the Tcl core, there is no provision of full
integration of shared variables within the Tcl syntax, unfortunately\&. All
access to shared data must be performed with the supplied package commands\&.
Also, variable traces are not supported\&. But even so, benefits of easy,
simple and safe shared data manipulation outweights imposed limitations\&.
.SH CREDITS
Thread shared variables are inspired by the nsv interface found in
AOLserver, a highly scalable Web server from America Online\&.
.SH "SEE ALSO"
thread, tpool, ttrace
.SH KEYWORDS
locking, synchronization, thread shared data, threads

.sp
.BE
.SH DESCRIPTION
This section describes commands implementing thread shared variables\&.
A thread shared variable is very similar to a Tcl array but in
contrast to a Tcl array it is created in shared memory and can
be accessed from many threads at the same time\&. Important feature of
thread shared variable is that each access to the variable is internally
protected by a mutex so script programmer does not have to take care
about locking the variable himself\&.
.PP
Thread shared variables are not bound to any thread explicitly\&. That
means that when a thread which created any of thread shared variables
exits, the variable and associated memory is not unset/reclaimed\&.
User has to explicitly unset the variable to reclaim the memory
consumed by the variable\&.
.SH "ELEMENT COMMANDS"
.TP
\fBtsv::names\fR ?pattern?
Returns names of shared variables matching optional ?pattern?
or all known variables if pattern is omitted\&.
.TP
\fBtsv::object\fR \fIvarname\fR \fIelement\fR
Creates object accessor command for the \fIelement\fR in the
shared variable \fIvarname\fR\&. Using this command, one can apply most
of the other shared variable commands as method functions of
the element object command\&. The object command is automatically
deleted when the element which this command is pointing to is unset\&.
................................................................................
=> A shared string appended
.CE
.TP
\fBtsv::set\fR \fIvarname\fR \fIelement\fR ?value?
Sets the value of the \fIelement\fR in the shared variable \fIvarname\fR
to \fIvalue\fR and returns the value to caller\&. The \fIvalue\fR
may be omitted, in which case the command will return the current
value of the element\&. If the element cannot be found, error is triggered\&.
.TP
\fBtsv::get\fR \fIvarname\fR \fIelement\fR ?namedvar?
Retrieves the value of the \fIelement\fR from the shared variable \fIvarname\fR\&.
If the optional argument \fInamedvar\fR is given, the value is
stored in the named variable\&. Return value of the command depends
of the existence of the optional argument \fInamedvar\fR\&.
If the argument is omitted and the requested element cannot be found
in the shared array, the command triggers error\&. If, however, the
optional argument is given on the command line, the command returns
true (1) if the element is found or false (0) if the element is not found\&.
.TP
\fBtsv::unset\fR \fIvarname\fR ?element?
Unsets the \fIelement\fR from the shared variable \fIvarname\fR\&.
If the optional element is not given, it deletes the variable\&.
.TP
\fBtsv::exists\fR \fIvarname\fR \fIelement\fR
Checks whether the \fIelement\fR exists in the shared variable \fIvarname\fR
and returns true (1) if it does or false (0) if it doesn't\&.
.TP
\fBtsv::pop\fR \fIvarname\fR \fIelement\fR
Returns value of the \fIelement\fR in the shared variable \fIvarname\fR
and unsets the element, all in one atomic operation\&.
.TP
\fBtsv::move\fR \fIvarname\fR \fIoldname\fR \fInewname\fR
Renames the element \fIoldname\fR to the \fInewname\fR in the
shared variable \fIvarname\fR\&. This effectively performs an get/unset/set
sequence of operations but all in one atomic step\&.
.TP
\fBtsv::incr\fR \fIvarname\fR \fIelement\fR ?count?
Similar to standard Tcl \fBincr\fR command but increments the value
of the \fIelement\fR in shared variable \fIvarname\fR instead of
the Tcl variable\&.
.TP
\fBtsv::append\fR \fIvarname\fR \fIelement\fR \fIvalue\fR ?value \&.\&.\&.?
Similar to standard Tcl \fBappend\fR command but appends one or more
values to the \fIelement\fR in shared variable \fIvarname\fR instead of the
Tcl variable\&.
.TP
................................................................................
Similar to the standard Tcl \fBlindex\fR command but in addition to
returning, it also splices the value out of the \fIelement\fR
from the shared variable \fIvarname\fR in one atomic operation\&.
In contrast to the Tcl \fBlindex\fR command, this command returns
no value to the caller\&.
.TP
\fBtsv::lpush\fR \fIvarname\fR \fIelement\fR ?index?
This command performs the opposite of the \fBtsv::lpop\fR command\&.
As its counterpart, it returns no value to the caller\&.
.PP
.SH "ARRAY COMMANDS"
This command supports most of the options of the standard Tcl
\fBarray\fR command\&. In addition to those, it allows binding
a shared variable to some persistent storage databases\&. Currently the persistent
options supported are the famous GNU Gdbm and LMDB\&. These options have to be
selected during the package compilation time\&.
The implementation provides hooks for defining other persistency layers, if
needed\&.
.TP
\fBtsv::array set\fR \fIvarname\fR \fIlist\fR
Does the same as standard Tcl \fBarray set\fR\&.
................................................................................
specified for \fIretvar\fR, the value is not returned, allowing the Tcl
programmer to determine if a \fIkey\fR is present in a keyed list without
setting a variable as a side-effect\&.
.TP
\fBtsv::keylkeys\fR \fIvarname\fR \fIkeylist\fR ?key?
Return the a list of the keys in the keyed list \fIkeylist\fR in the
shared variable \fIvarname\fR\&. If \fIkey\fR is specified, then it is
the name of a key field whose subfield keys are to be retrieved\&.
.TP
\fBtsv::keylset\fR \fIvarname\fR \fIkeylist\fR \fIkey\fR \fIvalue\fR ?key value\&.\&.?
Set the value associated with \fIkey\fR, in the keyed list \fIkeylist\fR
to \fIvalue\fR\&. If the \fIkeylist\fR does not exists, it is created\&.
If \fIkey\fR is not currently in the list, it will be added\&. If it already
exists, \fIvalue\fR replaces the existing value\&. Multiple keywords and
values may be specified, if desired\&.
................................................................................
object data is properly locked and deep-copied when moving objects between
threads\&.
.PP
Due to the internal design of the Tcl core, there is no provision of full
integration of shared variables within the Tcl syntax, unfortunately\&. All
access to shared data must be performed with the supplied package commands\&.
Also, variable traces are not supported\&. But even so, benefits of easy,
simple and safe shared data manipulation outweighs imposed limitations\&.
.SH CREDITS
Thread shared variables are inspired by the nsv interface found in
AOLserver, a highly scalable Web server from America Online\&.
.SH "SEE ALSO"
thread, tpool, ttrace
.SH KEYWORDS
locking, synchronization, thread shared data, threads

\fBttrace::delentry\fR \fIcmd\fR
.sp
\fBttrace::preload\fR \fIcmd\fR
.sp
.BE
.SH DESCRIPTION
This package creates a framework for on-demand replication of the
interpreter state accross threads in an multithreading application\&.
It relies on the mechanics of Tcl command tracing and the Tcl
\fBunknown\fR command and mechanism\&.
.PP
The package requires Tcl threading extension but can be alternatively
used stand-alone within the AOLserver, a scalable webserver from
America Online\&.
.PP
................................................................................
In a nutshell, a short sample illustrating the usage of the ttrace
with the Tcl threading extension:
.CS
% package require Ttrace
2\&.8\&.0
% set t1 [thread::create {package require Ttrace; thread::wait}]
tid0x1802800
% ttrace::eval {proc test args {return test-[thread::id]}}
% thread::send $t1 test
test-tid0x1802800
................................................................................
the extension are automatically updated\&. If the command execution
resulted in Tcl error, no state propagation takes place\&.
.sp
This is the most important user-level command of the package as
it wraps most of the commands described below\&. This greatly
simplifies things, because user need to learn just this (one)
command in order to effectively use the package\&. Other commands,
as desribed below, are included mostly for the sake of completeness\&.
.TP
\fBttrace::enable\fR
Activates all registered callbacks in the framework
and starts a new trace epoch\&. The trace epoch encapsulates all
changes done to the interpreter during the time traces are activated\&.
.TP
\fBttrace::disable\fR
................................................................................
.TP
\fBttrace::update\fR ?epoch?
Used to refresh the state of the interpreter to match the optional
trace ?epoch?\&. If the optional ?epoch? is not given, it takes
the most recent trace epoch\&.
.TP
\fBttrace::getscript\fR
Returns a synthetized Tcl script which may be sourced in any interpreter\&.
This script sets the stage for the Tcl \fBunknown\fR command so it can
load traced resources from the in-memory database\&. Normally, this command
is automatically invoked by other higher-level commands like
\fBttrace::eval\fR and \fBttrace::update\fR\&.
.PP
.SH "CALLBACK COMMANDS"
A word upfront: the package already includes callbacks for tracing
following Tcl commands: \fBproc\fR, \fBnamespace\fR, \fBvariable\fR,
\fBload\fR, and \fBrename\fR\&. Additionaly, a set of callbacks for
tracing resources (object, clasess) for the XOTcl v1\&.3\&.8+, an
OO-extension to Tcl, is also provided\&.
This gives a solid base for solving most of the real-life needs and
serves as an example for people wanting to customize the package
to cover their specific needs\&.
.PP
Below, you can find commands for registering callbacks in the
framework and for writing callback scripts\&. These callbacks are
................................................................................
This way, users can update just one interpreter (master) in one
thread and replicate that interpreter state (or part of it) to other
threads/interpreters in the process\&.
.PP
Immediate benefit of such approach is the much smaller memory footprint
of the application and much faster thread creation\&. By not actually
loading all necessary procedures (and other resources) in every thread
at the thread initialization time, but by deffering this to the time the
resource is actually referenced, significant improvements in both
memory consumption and thread initialization time can be achieved\&. Some
tests have shown that memory footprint of an multithreading Tcl application
went down more than three times and thread startup time was reduced for
about 50 times\&. Note that your mileage may vary\&.
Other benefits include much finer control about what (and when) gets
replicated from the master to other Tcl thread/interpreters\&.
.SH "SEE ALSO"
thread, tpool, tsv
.SH KEYWORDS
command tracing, introspection

\fBttrace::delentry\fR \fIcmd\fR
.sp
\fBttrace::preload\fR \fIcmd\fR
.sp
.BE
.SH DESCRIPTION
This package creates a framework for on-demand replication of the
interpreter state across threads in an multithreading application\&.
It relies on the mechanics of Tcl command tracing and the Tcl
\fBunknown\fR command and mechanism\&.
.PP
The package requires Tcl threading extension but can be alternatively
used stand-alone within the AOLserver, a scalable webserver from
America Online\&.
.PP
................................................................................
In a nutshell, a short sample illustrating the usage of the ttrace
with the Tcl threading extension:
.CS
% package require Ttrace
2\&.8\&.2
% set t1 [thread::create {package require Ttrace; thread::wait}]
tid0x1802800
% ttrace::eval {proc test args {return test-[thread::id]}}
% thread::send $t1 test
test-tid0x1802800
................................................................................
the extension are automatically updated\&. If the command execution
resulted in Tcl error, no state propagation takes place\&.
.sp
This is the most important user-level command of the package as
it wraps most of the commands described below\&. This greatly
simplifies things, because user need to learn just this (one)
command in order to effectively use the package\&. Other commands,
as described below, are included mostly for the sake of completeness\&.
.TP
\fBttrace::enable\fR
Activates all registered callbacks in the framework
and starts a new trace epoch\&. The trace epoch encapsulates all
changes done to the interpreter during the time traces are activated\&.
.TP
\fBttrace::disable\fR
................................................................................
.TP
\fBttrace::update\fR ?epoch?
Used to refresh the state of the interpreter to match the optional
trace ?epoch?\&. If the optional ?epoch? is not given, it takes
the most recent trace epoch\&.
.TP
\fBttrace::getscript\fR
Returns a synthesized Tcl script which may be sourced in any interpreter\&.
This script sets the stage for the Tcl \fBunknown\fR command so it can
load traced resources from the in-memory database\&. Normally, this command
is automatically invoked by other higher-level commands like
\fBttrace::eval\fR and \fBttrace::update\fR\&.
.PP
.SH "CALLBACK COMMANDS"
A word upfront: the package already includes callbacks for tracing
following Tcl commands: \fBproc\fR, \fBnamespace\fR, \fBvariable\fR,
\fBload\fR, and \fBrename\fR\&. Additionally, a set of callbacks for
tracing resources (object, classes) for the XOTcl v1\&.3\&.8+, an
OO-extension to Tcl, is also provided\&.
This gives a solid base for solving most of the real-life needs and
serves as an example for people wanting to customize the package
to cover their specific needs\&.
.PP
Below, you can find commands for registering callbacks in the
framework and for writing callback scripts\&. These callbacks are
................................................................................
This way, users can update just one interpreter (master) in one
thread and replicate that interpreter state (or part of it) to other
threads/interpreters in the process\&.
.PP
Immediate benefit of such approach is the much smaller memory footprint
of the application and much faster thread creation\&. By not actually
loading all necessary procedures (and other resources) in every thread
at the thread initialization time, but by deferring this to the time the
resource is actually referenced, significant improvements in both
memory consumption and thread initialization time can be achieved\&. Some
tests have shown that memory footprint of an multithreading Tcl application
went down more than three times and thread startup time was reduced for
about 50 times\&. Note that your mileage may vary\&.
Other benefits include much finer control about what (and when) gets
replicated from the master to other Tcl thread/interpreters\&.
.SH "SEE ALSO"
thread, tpool, tsv
.SH KEYWORDS
command tracing, introspection

This command configures various low-level aspects of the thread with
ID [arg id] in the similar way as the standard Tcl command
[cmd fconfigure] configures some Tcl channel options. Options currently
supported are: [option -eventmark] and [option -unwindonerror].
[para]
The [option -eventmark] option, when set, limits the number of
asynchronously posted scripts to the thread event loop.The [cmd {thread::send -async}] command will block until the numberof pending scripts in the event loop does not drop below the valueconfigured with [option -eventmark]. Default value for the[option -eventmark] is 0 (zero) which effectively disables the checking,i.e. allows for unlimited number of posted scripts.
[para]
The [option -unwindonerror] option, when set, causes thetarget thread to unwind if the result of the script processingresulted in error. Default value for the [option -unwindonerror]is 0 (false), i.e. thread continues to process scripts after oneof the posted scripts fails.
[call [cmd thread::transfer] [arg id] [arg channel]]
This moves the specified [arg channel] from the current thread
and interpreter to the main interpreter of the thread with the
given [arg id]. After the move the current interpreter has no

This command configures various low-level aspects of the thread with
ID [arg id] in the similar way as the standard Tcl command
[cmd fconfigure] configures some Tcl channel options. Options currently
supported are: [option -eventmark] and [option -unwindonerror].
[para]
When [option -eventmark] is provided with a value greater than 0 (zero), thatvalue is the maximum number of asynchronously posted scripts that may bepending for the thread. [cmd {thread::send -async}] blocks until the number of
pending scripts in the event loop drops below the [option -eventmark] value.
[para]
When [option -unwindonerror] is provided with a value of true, an error resultin a script causes the thread to unwind, making it unavailable to evaluateadditional scripts.
[call [cmd thread::transfer] [arg id] [arg channel]]
This moves the specified [arg channel] from the current thread
and interpreter to the main interpreter of the thread with the
given [arg id]. After the move the current interpreter has no