Prev: Subtyping vs Inheritance [Was: Re: Google's Go language and "goroutines"]
Next: Subtyping vs Inheritance [Was: Re: Google's Go language and "goroutines"]
From: tom.rmadilo on 23 Nov 2009 01:17 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 23 Nov 2009 01:34 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 23 Nov 2009 02:20 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 23 Nov 2009 04:30 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 23 Nov 2009 06:49
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 |