Advertisement
haiv

Processes-main.tcl

Jan 22nd, 2013
284
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 2.52 KB | None | 0 0
  1. #!/usr/bin/env tclsh
  2.  
  3. # Launches many processes and wait for them to finish.
  4. # This script will works on systems that has the ps command such as
  5. # BSD, Linux, and OS X
  6.  
  7. package require Tclx; # For process-management utilities
  8. package require struct::set
  9.  
  10. proc updatePidList {stat} {
  11.     global pidList
  12.     global allFinished
  13.  
  14.     # Parse the process ID of the just-finished process
  15.     lassign $stat processId howProcessEnded exitCode
  16.  
  17.     # Remove this process ID from the list of process IDs
  18.     #set pidList [lindex [intersect3 $pidList $processId] 0]
  19.     struct::set exclude pidList $processId
  20.     set processCount [llength $pidList]
  21.  
  22.     # Occasionally, a child process quits but the signal was lost. This
  23.     # block of code will go through the list of remaining process IDs
  24.     # and remove those that has finished
  25.     set updatedPidList {}
  26.     foreach pid $pidList {
  27.         if {![catch {exec ps $pid} errmsg]} {
  28.             lappend updatedPidList $pid
  29.         }
  30.     }
  31.  
  32.     set pidList $updatedPidList
  33.  
  34.     # Show the remaining processes
  35.     if {$processCount > 0} {
  36.         puts "Waiting for [struct::set size $pidList] processes"
  37.     } else {
  38.         set allFinished 1
  39.         puts "All finished"
  40.     }
  41. }
  42.  
  43. # A signal handler that gets called when a child process finished.
  44. # This handler needs to exit quickly, so it delegates the real works to
  45. # the proc updatePidList
  46. proc childTerminated {} {
  47.     # Restart the handler
  48.     signal -restart trap SIGCHLD childTerminated
  49.  
  50.     # Update the list of process IDs
  51.     while {![catch {wait -nohang} stat] && $stat ne {}} {
  52.         after idle [list updatePidList $stat]
  53.     }
  54. }
  55.  
  56. #
  57. # Main starts here
  58. #
  59.  
  60. puts "Main begins"
  61. set pidList {}
  62. set allFinished 0
  63.  
  64. # When a child process exits, call proc childTerminated
  65. signal -restart trap SIGCHLD childTerminated
  66.  
  67. # Spawn 3 processes
  68. set childId [exec tclsh child.tcl 1 7 &]; #  #1 runs for 7 secs
  69. struct::set include pidList $childId
  70.  
  71. set childId [exec tclsh child.tcl 2 5 &]; # #2 runs for 5 secs
  72. struct::set include pidList $childId
  73.  
  74. set childId [exec tclsh child.tcl 3 20 &]; #3 runs for 20 secs
  75. struct::set include pidList $childId
  76.  
  77. # Do some processing
  78. puts "list of processes: $pidList"
  79. puts "Waiting for child processes to finish"
  80. # Do some more processing if required
  81.  
  82. # After all done, wait for all to finish before exiting
  83. # Will time out in 2 minutes
  84. after 120000 { set allFinished "timedout" }
  85. vwait allFinished
  86.  
  87. if {$allFinished == "timedout"} {
  88.     puts "Timed out"
  89. }
  90. puts "Main ends"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement