Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Thread question regarding vwait

14 views
Skip to first unread message

Helmut Giese

unread,
Nov 22, 2009, 4:11:01 PM11/22/09
to
Hello out there,
contemplating the design for an upcoming application I implemented a
very basic prototype using Tcl's thread package.
BTW, it's truly amazing how fast you can get a multi-threading program
to work using this package - the errors I had were all due to my
insufficient reading of the documentation.

Scenario: I have a worker thread which must be prepared to stop and
continue execution.

I found it easy to implement this via the 'tsv' functions, e.g. in
order to check if the thread should stop I use in the central 'while'
loop
# check: stop?
if {[tsv::set ip stop]} {
break
}
where 'ip stop' is set by the "master". Easy.

Then, in order to know when to continue I use polling
# wait for 'continue'
while {[tsv::set ip stop]} {
after 50
}
Reacting only within 50 ms is ok here, and executing a couple of
commands every 50 ms doesn't burn many CPU cycles - but it's a bit
unpleasing esthetically.

It would be perfect if I could use a 'vwait' instead - but I don't
know how.

Can someone help me with my Sunday evening esthetic woes?
Best regards
Helmut Giese

Robert Heller

unread,
Nov 22, 2009, 5:23:05 PM11/22/09
to

vwait is part of the event loop logic. It is *bad* to mix threading and
event loops. Specifically, you can have the event loop in only ONE thread.

>
> Can someone help me with my Sunday evening esthetic woes?
> Best regards
> Helmut Giese
>

--
Robert Heller -- 978-544-6933
Deepwoods Software -- Download the Model Railroad System
http://www.deepsoft.com/ -- Binaries for Linux and MS-Windows
hel...@deepsoft.com -- http://www.deepsoft.com/ModelRailroadSystem/

Gerald W. Lester

unread,
Nov 22, 2009, 10:55:00 PM11/22/09
to

Robert,

Can you point me to something that says that?

Now you should not be doing vwaits on shared variables.

The reason I ask is because threads in Tcl normally communicate via sending
and receiving messages (::thread::wait) -- normally waiting in the event
loop for a message to arrive.

Now a while back, on some Linuxes, there was a restriction that the X event
loop be used only from a single thread (this was because some of the Xlibs
were not thread safe).


--
+------------------------------------------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Will Duquette

unread,
Nov 22, 2009, 11:54:26 PM11/22/09
to

Gerald,

Is Tk thread-safe? I'd understood that Tcl was thread-safe but that
Tk wasn't.

Gerald W. Lester

unread,
Nov 23, 2009, 12:05:15 AM11/23/09
to

I was under the impression that the problem was the Xlibs and not Tk.

That is best left to one of the core people.

tom.rmadilo

unread,
Nov 23, 2009, 1:17:53 AM11/23/09
to

This is very inefficient. You should be using condition variables to
wait. It is possible that some thread may never get a turn.

Assuming the threads package also supports condition variables, you
should look into it.

The logic is a little non-intuitive. I have an example, written in the
parent of tsv: nsv. The important proc is getPoll which shows the
typical while loop used in such a situation.

Here's a link:
ttp://www.junom.com/gitweb/gitweb.perl?p=tnt.git;a=blob;f=packages/db/tcl/datasource-procs.tcl;hb=HEAD

Since you are using the tsv stuff, take the next step and use
condition variables.

tom.rmadilo

unread,
Nov 23, 2009, 1:34:12 AM11/23/09
to
> http://www.junom.com/gitweb/gitweb.perl?p=tnt.git;a=blob;f=packages/db/tcl/d...

>
> Since you are using the tsv stuff, take the next step and use
> condition variables.

One oops in my code sample: instead of [ns_cond set], use [ns_cond
broadcast], or the equivalent thread package command. Broadcast wakes
up all threads, which might seem inefficient, but it ends up being
much more egalitarian. It is very likely that the same thread which
signaled the availability of a resource might grab it again, broadcast
seems to reduce this possibility significantly, at least in the
pthreads library.

tom.rmadilo

unread,
Nov 23, 2009, 2:20:41 AM11/23/09
to
> >http://www.junom.com/gitweb/gitweb.perl?p=tnt.git;a=blob;f=packages/d......

>
> > Since you are using the tsv stuff, take the next step and use
> > condition variables.
>
> One oops in my code sample: instead of [ns_cond set], use [ns_cond
> broadcast], or the equivalent thread package command. Broadcast wakes
> up all threads, which might seem inefficient, but it ends up being
> much more egalitarian. It is very likely that the same thread which
> signaled the availability of a resource might grab it again, broadcast
> seems to reduce this possibility significantly, at least in the
> pthreads library.

Here's a better reference:

http://www.flightlab.com/~joe/gutter/doc/thread-2.6.1/thread.html

Note that [thread::cond notify $condition] is equivalent to [ns_cond
broadcast], so you can't make the mistake I just described above. The
flightlab manpage has a very good description of what happens during
[thread::cond wait], plus a simple example. One mistake however, the
wait condition should have a negation like so:

set mutex [thread::mutex create]
set cond [thread::cond create]

thread::mutex lock $mutex
while {!<some_condition_is_true>} { # note negation missing in
original
thread::cond wait $cond $mutex
}
# Do some work under mutex protection
thread::mutex unlock $mutex

My example code shows what a condition looks like. It is also
important to [catch] all code between the mutex lock and unlock,
otherwise your resource will become unavailable (if an error occurs)
because the mutex was never released.

Donal K. Fellows

unread,
Nov 23, 2009, 4:30:08 AM11/23/09
to
On 23 Nov, 04:54, Will Duquette <w...@wjduquette.com> wrote:
> Is Tk thread-safe?  I'd understood that Tcl was thread-safe but that
> Tk wasn't.

Tk is from 8.5. Or at least probably is; it's now certain that it
wasn't in 8.4, as we found and corrected problems in the 8.5
development cycle. It's probably better to not use it from multiple
threads anyway (use in this way with Windows is a bit further advanced
as that's had someone actually working on it). Start a subprocess
instead if possible.

Donal.

Helmut Giese

unread,
Nov 23, 2009, 6:49:57 AM11/23/09
to
Hi Robert,
I think you are completely wrong on this one:

>vwait is part of the event loop logic. It is *bad* to mix threading and
>event loops. Specifically, you can have the event loop in only ONE thread.
1) From the man page of thread::send
Threads can enter the event loop explicitly by calling thread::wait or
any other relevant Tcl/Tk command, like update, vwait, etc.

2) Of course every thread has its own event loop (if started) - how
would you get any work done if it were otherwise?

Best regards
Helmut Giese

Helmut Giese

unread,
Nov 23, 2009, 6:53:58 AM11/23/09
to
Hi Tom,

>This is very inefficient. You should be using condition variables to
>wait. It is possible that some thread may never get a turn.
thanks for pointing me to condition variables. I had read about them
when glossing over the man page, but later failed to make the
connection.
This was an easy one - nice, no more polling.
Best regards
Helmut Giese

0 new messages