[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Start a program, get it's output, then kill it. while "multithreading"...

Deadolus

1/18/2008 10:26:00 AM

Hi everybody,

i'd like to program a gui for iperf (http://sourceforge.net...
iperf), it should run under windows And *NIX and I'm using fox as my
gui toolkit, I'll use some extra calculations to get the parameters,
that's why I can't use an already existing gui for iperf.
I already designed the gui and I'm now moving to connect the different
widgets to it's functions.
After you set all your parameters (size of packet, bandwith,
time, ...) I want to press a button and it should start iperf and
parallely read the it's output, so I can display some statistics
(running time and, on server side, the packet loss, maybe more).
So what should I program to do this?
I read about multithreading, IO.popen would be perfect, but how can I
kill iperf when I want to quit, before iperf ran out of time?
I think threads could also work (especially because one can kill
threads, if no longer used so the program would be terminated), but
what do I do to start the iperf?
I'm new to this subject and would appreciate any help on this!

Thanks in advance,

Deadolus
6 Answers

Robert Klemme

1/18/2008 10:57:00 AM

0

2008/1/18, Deadolus <deadolus@gmail.com>:
> i'd like to program a gui for iperf (http://sourceforge.net...
> iperf), it should run under windows And *NIX and I'm using fox as my
> gui toolkit, I'll use some extra calculations to get the parameters,
> that's why I can't use an already existing gui for iperf.
> I already designed the gui and I'm now moving to connect the different
> widgets to it's functions.
> After you set all your parameters (size of packet, bandwith,
> time, ...) I want to press a button and it should start iperf and
> parallely read the it's output, so I can display some statistics
> (running time and, on server side, the packet loss, maybe more).
> So what should I program to do this?
> I read about multithreading, IO.popen would be perfect, but how can I
> kill iperf when I want to quit, before iperf ran out of time?
> I think threads could also work (especially because one can kill
> threads, if no longer used so the program would be terminated), but
> what do I do to start the iperf?

First of all killing a thread won't help because the process is in no
way attached to a Ruby thread (btw, this would also be true if Ruby
was using native threads).

You can however use a thread to read output from IO.popen. For
example, you could stuff lines into a Queue which is read from your UI
thread and displayed. Or whatever you want do do with it.

About the killing I am not sure. With a quick check I did not find a
proper way to get the PID of the child process with IO.popen. If
there is no way you could use popen with "-" as command (i.e. start a
child process), have that writ out the current PID (in $$) to stdout
and exec the process you want to start. The parent would then have to
read the child PID first and remember it somewhere.

Kind regards

robert


--
use.inject do |as, often| as.you_can - without end

Deadolus

1/18/2008 6:54:00 PM

0

On 18 Jan., 11:56, Robert Klemme <shortcut...@googlemail.com> wrote:
> 2008/1/18, Deadolus <deado...@gmail.com>:
>
>
>
> > i'd like to program a gui for iperf (http://sourceforge.net...
> > iperf), it should run under windows And *NIX and I'm using fox as my
> > gui toolkit, I'll use some extra calculations to get the parameters,
> > that's why I can't use an already existing gui for iperf.
> > I already designed the gui and I'm now moving to connect the different
> > widgets to it's functions.
> > After you set all your parameters (size of packet, bandwith,
> > time, ...) I want to press a button and it should start iperf and
> > parallely read the it's output, so I can display some statistics
> > (running time and, on server side, the packet loss, maybe more).
> > So what should I program to do this?
> > I read about multithreading, IO.popen would be perfect, but how can I
> > kill iperf when I want to quit, before iperf ran out of time?
> > I think threads could also work (especially because one can kill
> > threads, if no longer used so the program would be terminated), but
> > what do I do to start the iperf?
>
> First of all killing a thread won't help because the process is in no
> way attached to a Ruby thread (btw, this would also be true if Ruby
> was using native threads).
>
> You can however use a thread to read output from IO.popen. For
> example, you could stuff lines into a Queue which is read from your UI
> thread and displayed. Or whatever you want do do with it.
>
> About the killing I am not sure. With a quick check I did not find a
> proper way to get the PID of the child process with IO.popen. If
> there is no way you could use popen with "-" as command (i.e. start a
> child process), have that writ out the current PID (in $$) to stdout
> and exec the process you want to start. The parent would then have to
> read the child PID first and remember it somewhere.
>
> Kind regards
>
> robert
>
> --
> use.inject do |as, often| as.you_can - without end

I think I found the solution, this is a example script:

io = IO.popen("ping google.ch") #open a new io
thread = Thread.new(io) {while !io.closed? do Thread.current["line"] =
io.readline end}#ALWAYS read current line of io
i=0 #example code...
while i<10 do
puts thread["line"]
puts thread.status #puts out "sleep", so it's running...
i+=1
sleep(1)
end
io.close #close io
thread.status #puts out "nil" so it's terminated

Seems like you easily can close a io just by "close".
At least it isn't in my ps aux list any more...
But I just tested under linux so far, so I can't say if this also
works under windows (I currently have some problems with my windows
box).
What do you think about this solution?
If anyone has a better solution, I'm still interested....

Stephen Lewis

1/18/2008 8:18:00 PM

0

On Fri, Jan 18, 2008 at 07:56:34PM +0900, Robert Klemme wrote:
>2008/1/18, Deadolus <deadolus@gmail.com>:
>> ...
>> I read about multithreading, IO.popen would be perfect, but how can I
>> kill iperf when I want to quit, before iperf ran out of time?
> ...
>
> About the killing I am not sure. With a quick check I did not find
> a proper way to get the PID of the child process with IO.popen. If
> ...

It's a little hard to find until you already know where it is, but
IO#pid might come in handy here :)

--
Stephen Lewis

Robert Klemme

1/19/2008 10:42:00 AM

0

On 18.01.2008 21:18, Stephen Lewis wrote:
> On Fri, Jan 18, 2008 at 07:56:34PM +0900, Robert Klemme wrote:
>> 2008/1/18, Deadolus <deadolus@gmail.com>:
>>> ...
>>> I read about multithreading, IO.popen would be perfect, but how can I
>>> kill iperf when I want to quit, before iperf ran out of time?
>> ...
>>
>> About the killing I am not sure. With a quick check I did not find
>> a proper way to get the PID of the child process with IO.popen. If
>> ...
>
> It's a little hard to find until you already know where it is, but
> IO#pid might come in handy here :)

Thanks! I use #popen too infrequently and when I use it I do not
normally fiddle with the process directly.

Kind regards

robert

Deadolus

1/21/2008 10:00:00 PM

0

On 19 Jan., 11:42, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 18.01.2008 21:18, Stephen Lewis wrote:
>
> > On Fri, Jan 18, 2008 at 07:56:34PM +0900, Robert Klemme wrote:
> >> 2008/1/18, Deadolus <deado...@gmail.com>:
> >>> ...
> >>> I read about multithreading, IO.popen would be perfect, but how can I
> >>> kill iperf when I want to quit, before iperf ran out of time?
> >> ...
>
> >> About the killing I am not sure. With a quick check I did not find
> >> a proper way togetthe PID of the child process with IO.popen. If
> >> ...
>
> >It'sa little hard to find until you already know whereitis, but
> > IO#pid might come in handy here :)
>
> Thanks! I use #popen too infrequently and when I useitI do not
> normally fiddle with the process directly.
>
> Kind regards
>
> robert

I wasn't really happy about my solution, so I continued
experimenting.
I now have something, which I'm quite happy about, I'll post it here,
maybe some people have the same problems as I had.
I expanded the normal IO class:

#-------------------File
OwnIO.rb--------------------------------------
module OwnIO

def killed? #nil if not killed, pid of IO if killed
#I think we do not need this, please correct me, if I am wrong:
#if(self.class != IO) then raise "Wrong type of Input variable, is
#{self.class} but should be IO!" end
begin

Process.waitpid(self.pid,Process::WNOHANG)
rescue Errno::ECHILD #rescue if process is already terminated
self.pid
end
end

def kill #kill a IO (you still have to close it)
Process.kill("KILL",self.pid)
end

end

class IO #add my own IO module to the normal IO class
include OwnIO
end

#---------EOF----------------------------------------------

And here is a short example script (how I'll implement it in my GUI
more or less):

#-------------------test.rb---------------------------------
require "OwnIO.rb"
STDOUT.sync = true
old = nil #old output
i = 0
io = IO.popen("ping google.ch")
io.sync = true

t = Thread.new() {while !io.killed? do Thread.current["line"] =
io.readline end}#first doesn't output all lines (Thread creation too
slow?)
while !io.killed? do
if t["line"]!=old then#only react to changes of the line
old = t["line"]
puts t["line"]#puts the current line
if i==20 then ##kill the io after 20 lines have been received
io.kill
end
i+=1;
end
end
puts "Killed"
#----------------------------
EOF----------------------------------------

The two functions "killed?" and "kill" are self explanatory, and seem
to work nice.
But at least "killed?" could have some improvements...
So if anybody has some improvements/suggestions to the code: go ahead!

Regards, Deadolus

ara.t.howard

1/22/2008 3:36:00 AM

0


On Jan 21, 2008, at 2:59 PM, Deadolus wrote:

> So if anybody has some improvements/suggestions to the code: go ahead!

if you care about stderr this won't work on windows or nix. threads,
io, and guis will hang you on windows unless you really know what you
are doing. for a portable way to start a process, capture it's
stdout/stderr, and have a handle on the pid see my systemu lib - it's
the only thing that'll work afaikt (read archives)

regards.

a @ http://draw...
--
sleep is the best meditation.
h.h. the 14th dalai lama