Crush
Crush

Reputation: 1

how can parallel exec command running

i have this script and want to run the exec in parallel. at the moment it is running one after another. How do I do that?

Many thanks for your help

bind pub -|- !tt proc:tt
proc proc:tt {nick host handle channel arg} {

set search [lindex [split [stripcodes bcu $arg]] 0]

foreach name {name1 name2 name3 name4 name5} {
    set results [exec sh search.sh $name $search]
putnow "PRIVMSG $channel :results: $results"
}
}

at the moment the issue is in succession. but it should be parallel

[24.02.20/22:00:59] <testbot> results: /home/test/name1
[24.02.20/22:01:34] <testbot> results: /home/test/name2
[24.02.20/22:03:05] <testbot> results: /home/test/name3
[24.02.20/22:09:05] <testbot> results: /home/test/name4
[24.02.20/22:09:07] <testbot> results: /home/test/name5

Upvotes: 0

Views: 504

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137567

To run a command in the background and capture the results, you need to open a pipeline and run things asynchronously. (The exec command can run things in the background if & is its final argument, but not while capturing the results.)

bind pub -|- !tt proc:tt
proc proc:tt {nick host handle channel arg} {
    set search [lindex [split [stripcodes bcu $arg]] 0]

    foreach name {name1 name2 name3 name4 name5} {
        # Launch the subprocess
        set pipe [open |[list sh search.sh $name $search]]
        # Set up a handler for when the subprocess produces *any* output *or* finishes
        fconfigure $pipe readable [list handle:search:output $channel $pipe $name]
    }
    putnow "PRIVMSG $channel processing..."
}
proc handle:search:output {channel pipe name} {
    set line [gets $pipe]
    if {[eof $pipe]} {
        close $pipe
        putnow "PRIVMSG $channel search for $name done"
        return
    }
    putnow "PRIVMSG $channel :result($name): $line"
}

Note that this launches all the searches in parallel. This might load your system up quite a bit! This may also deliver results in an arbitrary order. Doing things in order is possible, but requires either more complicated code with manual continuation passing, or coroutines (Tcl 8.6 or later). Or you can hand off the doing things in sequence to a subprocess: that's easy.

Upvotes: 2

glenn jackman
glenn jackman

Reputation: 246774

See https://tcl.tk/man/tcl8.6/TclCmd/exec.htm

If the last arg is & then the pipeline will be executed in background. In this case the exec command will return a list whose elements are the process identifiers for all of the subprocesses in the pipeline. The standard output from the last command in the pipeline will go to the application's standard output if it has not been redirected, and error output from all of the commands in the pipeline will go to the application's standard error file unless redirected.

Upvotes: 0

Related Questions