Hi Park,

Thanks again !

This comes very close to what I want since it not only kills the threads but
also the "ping" processes which were, in the earlier versions, still running
in the background.

Now my final stumbling block is that in the real case the "ping" commands
will be replaced by other commands which do not produce any output and hence
the control never transfers to the main thread. (Which is why I had "ping
10.0.0.0 -n 10 -w 1000 > NUL" in the first place to simulate long running
processes with no output.)

If only we could force control back to the main thread, we would be thru !
Very eager to hear from you ...
-- Shanko

"Park Heesob" <phasis / kornet.net> wrote in message
news:B6D89.2$J5.96 / news.hananet.net...
> Hi,
>
> "Shashank Date" <ADATE / kc.rr.com> wrote in message
> news:%zh89.14824$Hf.497645 / twister.kc.rr.com...
> > I am trying to write a ruby script (Ruby 1.7.2 mswin32) which does the
> > following:
> > 1. Spawn a few threads (say 3, for the time being) each of which invokes
> an
> > external program using the backquotes.
> > 2. Let the main thread continue till either all the threads are done
> > executing OR some external event occurs (like deletion of a file by
> another
> > program).
> >
> > I cannot seem to make it work (may be because thread implementation in
> Ruby
> > is not "native" ?).
> > Please help. TIA,
> > -- Shanko
> >
> > # Here is my broken script:
> > # ------------------------------------------------------
> > cmds = [
> >         "ping 10.0.0.0 -n 30 -w 1000 > NUL",
> >         "ping 10.0.0.0 -n 60 -w 1000 > NUL",
> >         "ping 10.0.0.0 -n 90 -w 1000 > NUL"
> >        ]
> >
> > out = []
> > threads = []
> >
> > for c in cmds
> >     threads << Thread.new(c) { |myCmd|
> >         puts "#{myCmd}"
> >         out << `#{myCmd}`
> >     }
> > end
> >
> > puts threads.length.to_s + ' threads running'
> >
> > begin
> >     i = 0
> >     threads.each { |t| i += 1 if t.stop? }
> >     puts `echo %TIME%`
> >     b = File.exists?("C:\\junk\\tmp_0.txt")
> >     puts i.to_s + ':' + File.mtime("C:\\junk\\tmp_0.txt").to_s if
$DEBUG
> > and b
> >     $stdout.flush
> > end until (i == threads.length) && (not b)
> > puts out if $DEBUG
> > # ------------------------------------------------------
> >
> >
> >
>
> Try this
>
> #=================================================
> require 'Win32API'
>
> OpenProcess = Win32API.new("kernel32","OpenProcess",['L','L','L'],'L')
> TerminateProcess =
Win32API.new("kernel32","TerminateProcess",['L','L'],'L')
>
> puts 'Start: ' + `echo %TIME%`
> cmds = [
>         "ping 10.0.0.0 -n 30 -w 1000 ",
>         "ping 10.0.0.0 -n 60 -w 1000 ",
>         "ping 10.0.0.0 -n 90 -w 1000 "
>        ]
>
> out = []
> threads = []
>
> for c in cmds
>     threads << Thread.new(c) { |myCmd|
>         puts "#{myCmd}"
>         f = IO.popen(myCmd)
>  Thread.current['pid'] = f.pid
>         while not f.eof?
>           out << f.gets
>         end
>     }
> end
>
> puts threads.length.to_s + ' threads running'
>
> begin
>     i = 0
>     threads.each { |t| i += 1 if t.stop? }
>     puts `echo %TIME%`
>     b = File.exists?("C:junkj0.txt")
>     puts i.to_s + ':' + File.mtime("C:junkj0.txt").to_s if $DEBUG and b
>     $stdout.flush
> end until (i == threads.length) || (not b)
>
> puts 'Mid: ' + `echo %TIME%`
> threads.each { |t|
>    TerminateProcess.Call(OpenProcess.Call(1,0,t['pid']),0) if t.alive?
> }
>
> puts 'Stop: ' + `echo %TIME%`
> puts out if $DEBUG
> #=============================================================
>
> Park Heesob.
>
>
>