Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env tclsh
- # Launches many processes and wait for them to finish.
- # This script will works on systems that has the ps command such as
- # BSD, Linux, and OS X
- package require Tclx; # For process-management utilities
- package require struct::set
- proc updatePidList {stat} {
- global pidList
- global allFinished
- # Parse the process ID of the just-finished process
- lassign $stat processId howProcessEnded exitCode
- # Remove this process ID from the list of process IDs
- #set pidList [lindex [intersect3 $pidList $processId] 0]
- struct::set exclude pidList $processId
- set processCount [llength $pidList]
- # Occasionally, a child process quits but the signal was lost. This
- # block of code will go through the list of remaining process IDs
- # and remove those that has finished
- set updatedPidList {}
- foreach pid $pidList {
- if {![catch {exec ps $pid} errmsg]} {
- lappend updatedPidList $pid
- }
- }
- set pidList $updatedPidList
- # Show the remaining processes
- if {$processCount > 0} {
- puts "Waiting for [struct::set size $pidList] processes"
- } else {
- set allFinished 1
- puts "All finished"
- }
- }
- # A signal handler that gets called when a child process finished.
- # This handler needs to exit quickly, so it delegates the real works to
- # the proc updatePidList
- proc childTerminated {} {
- # Restart the handler
- signal -restart trap SIGCHLD childTerminated
- # Update the list of process IDs
- while {![catch {wait -nohang} stat] && $stat ne {}} {
- after idle [list updatePidList $stat]
- }
- }
- #
- # Main starts here
- #
- puts "Main begins"
- set pidList {}
- set allFinished 0
- # When a child process exits, call proc childTerminated
- signal -restart trap SIGCHLD childTerminated
- # Spawn 3 processes
- set childId [exec tclsh child.tcl 1 7 &]; # #1 runs for 7 secs
- struct::set include pidList $childId
- set childId [exec tclsh child.tcl 2 5 &]; # #2 runs for 5 secs
- struct::set include pidList $childId
- set childId [exec tclsh child.tcl 3 20 &]; #3 runs for 20 secs
- struct::set include pidList $childId
- # Do some processing
- puts "list of processes: $pidList"
- puts "Waiting for child processes to finish"
- # Do some more processing if required
- # After all done, wait for all to finish before exiting
- # Will time out in 2 minutes
- after 120000 { set allFinished "timedout" }
- vwait allFinished
- if {$allFinished == "timedout"} {
- puts "Timed out"
- }
- puts "Main ends"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement