I had been using thread structure like this on my tcl8.4, win2k8 R2 64b platform
set var 3 set tid [thread::create { #1 #initialization code for aux thread proc pro1 def {} { #blah } thread::wait
}]
#2 set waiting 1 after 10000 {set waiting 0} vwait waiting
#other stuff here
#3 thread::send -async $tid [list proc1]
Once every so often (let say 2/100 execution cycle), when the code gets to #3, tcl pops up an error that says "proc1" is undefined.
Now, as I understand, this is happening because there is no guaranteed that #1 is executed before #3. thread::create returns as soon as the thread is created, without executing all the aux thread initialization code. So #2 is bought in as a stop gap. It gives some breathing room for the thread finish initialization and move to event loop. I don't really like this workaround, since it doesn't scale with the evolving initialization code. So if the wait time is not large enough, I would still see the proc not define error. What other option do I have?
Also, is there any way to pass a parameter from the main thread to the spawn thread (the var variable) during thread::create?
* py <pyj...@shaw.ca> | set tid [thread::create { | #1 | #initialization code for aux thread | proc pro1 def {} { | #blah | } | thread::wait | }] --<snip-snip>-- | Once every so often (let say 2/100 execution cycle), when the code | gets to #3, tcl pops up an error that says "proc1" is undefined.
| Now, as I understand, this is happening because there is no guaranteed | that #1 is executed before #3. thread::create returns as soon as the | thread is created, without executing all the aux thread initialization | code.
As I understand tcl::threads, the thread::send from #3 will only get handled by #1 when the event loop is entered in #1. This is done by thread::wait only after the proc has been defined, so there is no way that #1 reacts to the thread::send before the proc has been defined. Note that there is an obvious typo in the proc name ('pro1' vs 'proc1') in the code you've posted which might be the cause of the problem.
> I had been using thread structure like this on my tcl8.4, win2k8 R2 64b > platform
> set var 3 > set tid [thread::create { > #1 > #initialization code for aux thread > proc pro1 def {} { > #blah > } > thread::wait
> }]
> #2 > set waiting 1 > after 10000 {set waiting 0} > vwait waiting
> #other stuff here
> #3 > thread::send -async $tid [list proc1]
> Once every so often (let say 2/100 execution cycle), when the code gets > to #3, tcl pops up an error that says "proc1" is undefined.
> Now, as I understand, this is happening because there is no guaranteed > that #1 is executed before #3. thread::create returns as soon as the > thread is created, without executing all the aux thread initialization > code. So #2 is bought in as a stop gap. It gives some breathing room for > the thread finish initialization and move to event loop. I don't really > like this workaround, since it doesn't scale with the evolving > initialization code. So if the wait time is not large enough, I would > still see the proc not define error. What other option do I have?
That's strange. This race condition should happen only if your "initialization code for aux thread"calls the event loop (with [update], [vwait], [thread::wait], sync [http::geturl] or similar package doing it under the scenes). Please clarify, or better try to reduce the code and see if you still get the bug.
> Also, is there any way to pass a parameter from the main thread to the > spawn thread (the var variable) during thread::create?
Thread::create's argu;ent is a string, you can manipulate it. Typically:
set initcode { # blah proc ... proc ... set params }
Thanks guys. You are right, there are "update" in my initialization code that make the thread enter event loop prematurely. I was aware of vwait and thread::wait, didn't know about "update". After I made the change, the race condition is gone
> On 24 mai, 21:53, py<pyj...@shaw.ca> wrote: >> Hi,
>> I had been using thread structure like this on my tcl8.4, win2k8 R2 64b >> platform
>> set var 3 >> set tid [thread::create { >> #1 >> #initialization code for aux thread >> proc pro1 def {} { >> #blah >> } >> thread::wait
>> }]
>> #2 >> set waiting 1 >> after 10000 {set waiting 0} >> vwait waiting
>> #other stuff here
>> #3 >> thread::send -async $tid [list proc1]
>> Once every so often (let say 2/100 execution cycle), when the code gets >> to #3, tcl pops up an error that says "proc1" is undefined.
>> Now, as I understand, this is happening because there is no guaranteed >> that #1 is executed before #3. thread::create returns as soon as the >> thread is created, without executing all the aux thread initialization >> code. So #2 is bought in as a stop gap. It gives some breathing room for >> the thread finish initialization and move to event loop. I don't really >> like this workaround, since it doesn't scale with the evolving >> initialization code. So if the wait time is not large enough, I would >> still see the proc not define error. What other option do I have?
> That's strange. This race condition should happen only if your > "initialization code for aux thread"calls the event loop (with > [update], [vwait], [thread::wait], sync [http::geturl] or similar > package doing it under the scenes). Please clarify, or better try to > reduce the code and see if you still get the bug.
>> Also, is there any way to pass a parameter from the main thread to the >> spawn thread (the var variable) during thread::create?
> Thread::create's argu;ent is a string, you can manipulate it. > Typically:
> set initcode { > # blah > proc ... > proc ... > set params }