From: tom.rmadilo on
On Nov 22, 1:11 pm, Helmut Giese <hgi...(a)ratiosoft.com> wrote:
> 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

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.
From: tom.rmadilo on
On Nov 22, 10:17 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
> On Nov 22, 1:11 pm, Helmut Giese <hgi...(a)ratiosoft.com> wrote:
>
>
>
> > 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
>
> 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:
> 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.
From: tom.rmadilo on
On Nov 22, 10:34 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
> On Nov 22, 10:17 pm, "tom.rmadilo" <tom.rmad...(a)gmail.com> wrote:
>
>
>
> > On Nov 22, 1:11 pm, Helmut Giese <hgi...(a)ratiosoft.com> wrote:
>
> > > 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
>
> > 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:
> >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.
From: Donal K. Fellows on
On 23 Nov, 04:54, Will Duquette <w...(a)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.
From: Helmut Giese on
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