Hi guys

I'd like to share a test I did lately on Rivet with Tcl threads. FWIK
the subject has been brought up in the past various times and only
speaking about Apache worker threads, not specifically about the
usefulness of Tcl threads in Rivet applications. As a matter of fact I
wasn't totally sure Tcl threads could work with Rivet and definitely I
had no idea about inherent limitations or pitfalls of having Tcl
threads in Rivet scripts.

Rivet configure.ac includes the TEA_ENABLE_THREADS macro which checks
whether Rivet is being build with a threaded Tcl and enables/disables
threads accordingly. So provided your Tcl installation was build
with --enable-threads, also Rivet gets build likewise.

In the following example a pool of threads are created the first time
the script is run and then at each request they get sent a procedure
to be executed. The procedure forces the threads to wait for a
random time interval, thus even though they are notified in a definite
order they return a result in random order. The script works as
expected and I found 2 relevant limitations:

 - Tcl threads cannot access to the stdout channel (inherent to Tcl
threads), thus threads cannot produce output straight away and in case
they have to communicate with the master thread to do so. Personally I
can see Tcl threads useful mostly within initialization scripts and/or
BeforeScripts operating on strictly separate channels and databases. 

 - Rivet threads cannot gain access to Rivet commands because they
don't go through the same initialization of the master interpreter.
This would require a better modularization of the code of Rivet. This
one should in case be addressed very carefully analyzing the possible
implication for Rivet internal status and data integrity.

If anybody ever felt they could benefit from threads in a Rivet
application this is time to speak up and express their thoughts.

<pre><?
    package require Thread

    proc thread_random_wait {} {

       set thread_wait [expr int(1000*rand())] 
       after $thread_wait
       return [thread::id]
    }

    proc signal_threads { pool procname } {
        upvar $pool thread_pool

        set result 0
        foreach id [array names thread_pool] {

          puts "--->>> $thread_pool($id)"
          ::thread::send -async $thread_pool($id) [info body $procname] result

        }

        puts "waiting for results from threads"
        for {set i 0} {$i < [llength [array names thread_pool]]} {incr i} {
           vwait ::result
           puts "<<<--- $::result"
        }

        puts "done\!"
    }

    if {![array exists ::thread_pool]} {
        for {set i 0} {$i < 10} {incr i} { set ::thread_pool($i) 
[::thread::create] }
    } else {
        puts "thread pool existing"
    }
    puts "Apache child pid [pid]"
    signal_threads ::thread_pool thread_random_wait
?></pre>


 












---------------------------------------------------------------------
To unsubscribe, e-mail: rivet-dev-unsubscr...@tcl.apache.org
For additional commands, e-mail: rivet-dev-h...@tcl.apache.org

Reply via email to