From: Park Heesob Date: 2002-08-24T18:40:16+09:00 Subject: Re: thread control Hi, "Shashank Date" wrote in message news:q1599.19624$Hf.636502@twister.kc.rr.com... > Hi Park, > > > If you use command "ping 10.0.0.0 -n 90 -w 1000 > NUL", > > it creates two processes 'cmd.exe' and 'ping.exe'. > > I can get pid of 'cmd.exe', but not pid of 'ping.exe'. > > If you download pstools from: > > http://www.sysinternals.com/ntw2k/freeware/pstools.shtml > > and run "pslist -t" it shows you the process tree. > (There is also a Win2K ResourceKit utility "ptree" which I believe does the > same thing). > > Which tells me that there is Windows API which exposes the parent-child > relationship of processes. > May be that is what is needed to finish it off. > > > If you can find pid of 'ping.exe', there's no problem. > > It's your chance to finish this program perfectly. > > Assuming I get hold of the pid for "ping", I guess, I will have to replace > the following line of your modification: > > hProcess = OpenProcess.Call(0x100001, 1 , f.pid) > ^^^^ > with: > > hProcess = OpenProcess.Call(0x100001, 1 , ping_pid) > > Right ? > > I will try ... but I am not as comfortable with Windows API as you are ....so > I might call for help again ;-) > Thanks for your information. Here is my final version. #=========================================================================== ===== require 'Win32API' OpenProcess = Win32API.new("kernel32","OpenProcess",['L','L','L'],'L') TerminateProcess = Win32API.new("kernel32","TerminateProcess",['L','L'],'L') WaitForSingleObject = Win32API.new("kernel32","WaitForSingleObject",['L','L'],'L') RegCloseKey = Win32API.new("advapi32","RegCloseKey",['L'],'L') RegOpenKeyEx = Win32API.new("advapi32","RegOpenKeyEx",['L','P','L','L','P'],'L') RegQueryValueEx = Win32API.new("advapi32","RegQueryValueEx",['L','P','L','P','P','P'],'L') INITIAL_SIZE = 51200 EXTEND_SIZE = 25600 REGKEY_PERF = "software\\microsoft\\windows nt\\currentversion\\perflib\\009" REGSUBKEY_COUNTERS = "Counters" KEY_READ = 0x20019; ERROR_MORE_DATA = 234 HKEY_LOCAL_MACHINE = 0x80000002 HKEY_PERFORMANCE_DATA = 0x80000004 # return hash key : parent pids, value : array of child pids def getpids() result = Hash.new hKeyNames = "\0"*4 rc = RegOpenKeyEx.Call( HKEY_LOCAL_MACHINE,REGKEY_PERF,0,KEY_READ,hKeyNames) hKeyNames = hKeyNames.unpack('L')[0] dwSize = "\0"*4 rc = RegQueryValueEx.Call( hKeyNames,REGSUBKEY_COUNTERS,0,0,0,dwSize) dwSize2 = dwSize.unpack('L')[0] buf = "\0" * dwSize2 rc = RegQueryValueEx.Call( hKeyNames,REGSUBKEY_COUNTERS,0,0,buf,dwSize) buf2 = Hash[*buf.split("\0")] proidx = buf2.index("Process").to_i pididx = buf2.index("ID Process").to_i ppididx = buf2.index("Creating Process ID").to_i buf = "\0" * INITIAL_SIZE szSubKey = proidx.to_s dwSize = [INITIAL_SIZE] while true dwSize2 = dwSize.pack('L') rc = RegQueryValueEx.Call( HKEY_PERFORMANCE_DATA,szSubKey,0,0,buf,dwSize2) break if rc==0 if rc == ERROR_MORE_DATA dwSize[0] += EXTEND_SIZE; buf = "\0" * dwSize[0] else exit end end pObj = buf[buf[24,4].unpack('L')[0] .. -1] pCounterDef = pObj[pObj[8,4].unpack('L')[0] .. -1] numCounters = pObj[32,4].unpack('L')[0] for i in 0 .. numCounters counterNameTitleIndex = pCounterDef[4,4].unpack('L')[0] if counterNameTitleIndex == pididx pidcounter = pCounterDef[36,4].unpack('L')[0] end if counterNameTitleIndex == ppididx ppidcounter = pCounterDef[36,4].unpack('L')[0] end pCounterDef = pCounterDef[40..-1] end dwNumTasks = pObj[40,4].unpack('L')[0] pInst = pObj[pObj[4,4].unpack('L')[0] .. -1] for i in 0 .. dwNumTasks pCounter = pInst[pInst[0,4].unpack('L')[0] .. -1] pid = pCounter[pidcounter,4].unpack('L')[0] ppid = pCounter[ppidcounter,4].unpack('L')[0] if ppid>0 if result[ppid] == nil result[ppid] = [pid] else result[ppid].push(pid) end end pInst = pCounter[pCounter[0,4].unpack('L')[0] .. -1] end RegCloseKey.Call( hKeyNames ) RegCloseKey.Call( HKEY_PERFORMANCE_DATA ) result end puts 'Start: ' + `echo %TIME%` 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}" f = IO.popen(myCmd) hProcess = OpenProcess.Call(0x00100001, 0 ,f.pid) Thread.current['pid'] = f.pid Thread.current['hProcess'] = hProcess while true a = WaitForSingleObject.Call( hProcess, 0 ); break if a==0 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) pids = getpids puts 'Mid: ' + `echo %TIME%` threads.each { |t| if t.alive? pids[t['pid']].each {|pid| TerminateProcess.Call(OpenProcess.Call(0x00100001, 0 ,pid),0) } TerminateProcess.Call(t['hProcess'],0) end } puts 'Stop: ' + `echo %TIME%` puts out if $DEBUG #================================================================= Park Heesob