Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Do parallel in TCL

1,661 views
Skip to first unread message

Ashwin Tech

unread,
May 20, 2011, 9:00:08 PM5/20/11
to
I have 2 procs procA and ProcB. These procs run on devices X,Y and Z.

curently I call it like :

X procA
Y procA
Z porcA

procA takes a long time to execute.
Since X,Y and Z are independant, I want them to execute them in
parallel on X, Y and Z.

I want a generic API like do_parallel ( procA {X,Y,Z} ) or similar.

Kindly suggest how I can achieve this.

Thanks

Ashwin Tech

unread,
May 20, 2011, 9:01:16 PM5/20/11
to

tomas

unread,
May 21, 2011, 1:59:14 AM5/21/11
to
Ashwin Tech <ashwin.t...@gmail.com> writes:

> I have 2 procs procA and ProcB. These procs run on devices X,Y and Z.
>
> curently I call it like :
>
> X procA
> Y procA
> Z porcA
>
> procA takes a long time to execute.
> Since X,Y and Z are independant, I want them to execute them in
> parallel on X, Y and Z.
>
> I want a generic API like do_parallel ( procA {X,Y,Z} ) or similar.

Ashwin,

please describe your problem in a way there is a chance of understanding
it. Does the Tcl program run on each of the devices? Or on a central
computer talking to the devices?

I'll assume that the program runs on one computer and talks to the
devices X, Y and Z attached to it.

Do the devices talk to the computer while procA is running?

You might start three instances of the program, each talking to one
device and let your OS do the scheduling for you (that's what OSes are
for, after all). What would be the drawbacks of such an approach *in
your specific case*?

Then, of course, if running several instances of the program is out (for
what reasons?), you might resort to asynchronous I/O (look up the
documentation for fileevent). But I am making too many assumptions, so I
might be totally wrong on what your needs are.

Regards
-- tomás

Goeran Hanke

unread,
May 22, 2011, 3:29:33 PM5/22/11
to
Am 21.05.2011 03:00, schrieb Ashwin Tech:
> I have 2 procs procA and ProcB. These procs run on devices X,Y and Z.
>
> curently I call it like :
>
> X procA
> Y procA
> Z porcA
>
> procA takes a long time to execute.
> Since X,Y and Z are independant, I want them to execute them in
> parallel on X, Y and Z.
>
> I want a generic API like do_parallel ( procA {X,Y,Z} ) or similar.


Hi Ashwin Tech,

you can use threads or processes. In general you can use files, pipes or
sockets to communicate between processes and threads. If you use threads
then you can use tcl variables.

A possible thread based solution might be the following snippet.

Greetings Göran


--------------------------------------------------------------------------


proc procA device {
# procA - do something with device
# this is a demo function: it waits between 1 an 10 seconds
# and returns the device and the waiting time
set delay [expr {1000 * int (10*rand ()+1)}]
after $delay
return "$device: $delay"
}


proc do_parallel {procname devlist} {
# do_parallel - generic procedure that involve the proc "procname"
# with every argument in devlist in a separate thread
package require Thread
foreach dev $devlist {
set ::tid($dev) [thread::create { thread::wait } ]
thread::send $::tid($dev) \
[list proc $procname [info args $procname] \
[info body $procname] ]
thread::send -async $::tid($dev) [list $procname $dev]
::result($dev)
trace add variable ::result($dev) write printResults
}


}

proc printResults {name1 name2 op} {
# printResults - simple trace function that prints the results
if {$name2 == ""} {
set varname $name1
} {
set varname [format %s(%s) $name1 $name2]
}
puts `[set $varname]`
}


do_parallel procA [list X Y Z]

vwait forever

tomk

unread,
May 22, 2011, 3:58:43 PM5/22/11
to
Take a look at this page.
http://wiki.tcl.tk/25977
tomk

Donal K. Fellows

unread,
May 23, 2011, 9:27:37 AM5/23/11
to
On May 21, 2:01 am, Ashwin Tech <ashwin.techni...@gmail.com> wrote:
> I want a generic API like do_parallel ( procA {X,Y,Z} ) or similar.

Since interpreters aren't shared across threads (let alone processes)
you have to do a little work. If it's easy to replicate the code
(e.g., because you can just [source] it from a file) then your best
bet is to just use a thread pool or something like that:

package require Thread
set operands [list X Y Z]
set workerSource "worker.tcl"

# Construct the thread pool
set pool [tpool::create -maxworkers [llength $operands] \
-initcmd [list source $workerSource]]

# Start the workers
foreach operand $operands {
lappend jobs [tpool::post -nowait $pool [list procA $operand]
}

# Wait for everything to finish
while {[llength $jobs]} {
tpool::wait $pool $jobs jobs
# Assume we don't need to pick up the results; if we did,
# we'd do so here for the *finished* jobs with ids returned
# by [tpool::wait]...
}

# Clean up
tpool::release $pool

There's documentation for the thread pool code at:
http://tcl.cvs.sourceforge.net/viewvc/tcl/thread/doc/html/tpool.html

Donal.

0 new messages