Threads spawning more threads

Please support our Ruby advertiser: SELL YOUR PRODUCT TODAY !
Stylish Stylish is offline Offline May 9th, 2007, 10:41 pm |
0
I needed a way to spawn multiple threads, have them monitored, and restarted if an error occured. I came up with the following.

This snippet is from a larger program, so if there is a problem please let me know. This is for command line and tested on Linux (well, the larger program).
Quick reply to this message  
Ruby Syntax
  1. <%
  2.  
  3. #!/usr/bin/env ruby
  4. ## kill some warnings about writable directories
  5. $VERBOSE=nil
  6.  
  7. # we want to parse input, right?
  8. require 'optparse'
  9.  
  10. ## global options (which can and will be changed)
  11. @@options = {
  12. :runtime => "01:00:00",
  13. :total_time => 0,
  14. :threadlist => [],
  15. }
  16.  
  17.  
  18. def parse_input()
  19. ARGV.options do |opts|
  20. opts.banner = "Usage: #{$0} [options] <thread names>"
  21. opts.separator "Threadeds spawning threads, oh my!"
  22. opts.separator ""
  23. opts.separator "Options:"
  24.  
  25. opts.on("-h", "--help", "show this message") {
  26. puts opts
  27. exit
  28. }
  29.  
  30. opts.on("-v", "--version", "show version details") {
  31. version = `grep -m 1 "#(@)" #{$0} | awk '{printf("version: %s (%s)",$3,$2)}'`
  32. puts version
  33. exit
  34. }
  35.  
  36. opts.on("--duration=HH:MM:SS", String, "specify how long to run test (default: #{@@options[:runtime]})") { |@@options[:runtime]| }
  37.  
  38. opts.parse!
  39. end
  40.  
  41. ## validate time
  42. hours, mins, secs = @@options[:runtime].to_s.split(":")
  43. if hours.nil? or mins.nil? or secs.nil?
  44. puts "ERROR -- Invalid time format!"
  45. exit 1
  46. end
  47.  
  48. @@options[:total_time] = (hours.to_i * 60 * 60) + (mins.to_i * 60) + secs.to_i
  49.  
  50. ## thread list, anyone?
  51. if ARGV.length < 1
  52. puts "ERROR! No thread names specified!"
  53. exit 1
  54. else
  55. @@options[:threadlist] = ARGV
  56. end
  57. end
  58.  
  59. @threads = []
  60. @start_time = Time.now
  61.  
  62. ## trap ctrl-c
  63. trap("INT") { threadDestroyAll() }
  64.  
  65. def newPass(threadname)
  66. ## create a new thread and add it to @threads
  67. @threads << Thread.new(threadname) { |myThread|
  68. ## trap that CTRL-C
  69. trap("INT") { threadDestroyAll() }
  70. ## name thread to that of name given. easier management
  71. Thread.current[:name] = "#{myThread}"
  72.  
  73. ## Stuff for thread to do goes here.
  74. }
  75. end
  76.  
  77. ## this is triggered via CTRL-C trap above
  78. # kill all threads and exit
  79. def threadDestroyAll()
  80. puts "***************************"
  81. puts "** Killing all processes **"
  82. puts "***************************"
  83. @threads.each { |thread| thread.kill }
  84. sleep 2
  85. Thread.main.kill
  86. end
  87.  
  88. ## needed a way to watch over all the baby threads
  89. # this will cycle through all threads, gathering a list of
  90. #+ those that are still running (and their names, which are that of the client)
  91. #+ any missing clients are then restarted.
  92. def threadOverlord(threads)
  93. threadList = activeThreads = deadThreads = []
  94. threadList = @@options[:threadlist]
  95. threads.each { |thread| activeThreads << thread[:name] if thread.alive? and keepGoing() }
  96. ## restart baby threads that have died?
  97. # if time limit has been reached, that is a no
  98. if keepGoing()
  99. deadThreads = threadList - activeThreads
  100. deadThreads.each { |threadname| newPass(threadname) }
  101. end
  102. activeThreads = deadThreads = threadList = nil
  103. end
  104.  
  105. ## parent thread
  106. # this is just to trigger threadOverlord every X seconds
  107. #+ and check on the health of client threads
  108. def statusThread()
  109. statusT = Thread.new {
  110. Thread.current[:name] = "Overlord"
  111. loop do
  112. threadOverlord(@threads)
  113. sleep 15
  114. break if !keepGoing()
  115. end
  116. }
  117. statusT.join
  118. end
  119.  
  120. ## returns true if there is still time remaining
  121. def keepGoing()
  122. return true if Time.now.to_i - @start_time.to_i < @@options[:total_time].to_i
  123. false
  124. end
  125.  
  126. parse_input()
  127. statusThread
  128.  
  129. %>

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC