Sujet : Re: Thread with -async exits prematurely
De : rich (at) *nospam* example.invalid (Rich)
Groupes : comp.lang.tclDate : 26. Jun 2024, 23:12:48
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <v5i3p0$2bch1$1@dont-email.me>
References : 1 2 3
User-Agent : tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Luis Mendes <
luisXXXlupeXXX@gmail.com> wrote:
Hi Rich,
Once again, thank you very much for your help.
I could manage to application run in a multi-threaded way.
Still, there are a couple of things that I haven't yet understood, maybe
you (or other person) can help me figure this out.
1. Regarding vwait
As stated in https://www.tcl-lang.org/man/tcl/TclCmd/vwait.htm
"""It continues processing events until some event handler sets the value
of the global variable varName. Once varName has been set, the vwait
command will return as soon as the event handler that modified varName
completes."""
This was a difficulty I had before, maybe because English is not my main
language.
I thought that varName would have to change for every event handler that
signaled the end of some operation, like:
It is not the "value" that triggers vwait, it is the action of
"writing" (any write of anything) to the variable.
2. Regarding the script that you modified, I changed it a bit as well to
show what I don't understand.
The thread::names command shows all the threads that have been created
from the start of execution and not only the ones that were created in the
last cycle.
And this is confirmed by thread::exists that show 1 for all of them.
I was expecting that threads would no longer exist after an event handler
sets a varName for vwait.
Otherwise, we can end up with millions of threads existing at the same
time.
That is because that version does not "delete" the threads that finish
(preferably you'd reuse threads rather than delete and recreate them
over and over so I did not try to 'release' them when they finished).
Creation of a thread takes some non-zero amount of time, so if you
reuse existing threads you amortize the creation time across each
usage. If you recreate them anew each time, you pay the cost (in time)
to create them each time you use them.
Below is a patch for the code you posted in the last message that
actually "deletes" the threads when they 'complete':
--- thread-test2.orig 2024-06-26 17:55:57.564273473 -0400
+++ thread-test2 2024-06-26 18:04:58.037504557 -0400
@@ -21,6 +21,7 @@
proc sourceFiles {args} {
source oo.tcl
ns0::runAnsible $args
+ return [thread::id]
}
puts stderr "Thread: [thread::id] waiting"
thread::wait
@@ -33,13 +34,15 @@
puts "++++++++ cycle [incr cycle]"
while {$nr_live_threads < $nr_max_threads} {
puts stderr "Main: live=$nr_live_threads max=$nr_max_threads"
- set tid [thread::create $init_script]
+ set tid [thread::create -preserved $init_script]
incr nr_live_threads
thread::send -async $tid [list sourceFiles ....] sync
}
puts stderr "Main: waiting for a child to exit."
vwait sync
- puts stderr "Main: a child exited."
+ set exited $sync
+ puts stderr "Main: child '$exited' exited."
+ thread::release $exited
foreach tn [thread::names] {
puts "$tn\t\t[thread::exists $tn]"
}