[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Nonblocking IO read

S. Robert James

10/31/2006 10:52:00 PM

How can I perform a nonblocking IO read? That is, read whatever is
there to read and return. If there's nothing yet, just return.

Failing that, is there a way to manually check if there's anything to
read or the read will block?

(Note that I'm developing for both 'nix and Windows.)

30 Answers

Ara.T.Howard

10/31/2006 11:23:00 PM

0

Tom Pollard

11/1/2006 12:08:00 AM

0


On Oct 31, 2006, at 6:23 PM, ara.t.howard@noaa.gov wrote:
> On Wed, 1 Nov 2006 srobertjames@gmail.com wrote:
>> How can I perform a nonblocking IO read? That is, read whatever
>> is there to read and return. If there's nothing yet, just return.

That's what the Unix read() function does ("man 2 read"), available
in Ruby as IO#sysread(). The ri documentation doesn't explain much
about how to use Ruby's sysread, unfortunately.

>> Failing that, is there a way to manually check if there's anything
>> to read or the read will block?
>>
>> (Note that I'm developing for both 'nix and Windows.)

The select() function (Kernel#select, in Ruby) is the standard way to
do IO multiplexing under Unix. You give it a list of file handles on
which you're waiting to be able to read or write, and it returns when
one or more of them is ready. Windows provides a select() function,
too, but it only supports sockets (not pipes or ordinary file IO.)
The Win32 API generally doesn't provide non-blocking IO methods,
because it's assumed you'll use threads if you want to do something
else while waiting for IO.

> it can't be done. search the archives, this sort of thing almost
> always
> indicates a design flaw. for instance - what will your program do
> if there is
> no input?

Check other IO channels, wait for other sorts of events, do work -
whatever. Where do come from asserting that the use of non-blocking
IO represents a "design flaw"?

Tom


S. Robert James

11/1/2006 12:12:00 AM

0


ara.t.howard@noaa.gov wrote:
> On Wed, 1 Nov 2006 srobertjames@gmail.com wrote:
>
> > How can I perform a nonblocking IO read? That is, read whatever is
> > there to read and return. If there's nothing yet, just return.
> >
> > Failing that, is there a way to manually check if there's anything to
> > read or the read will block?
> >
> > (Note that I'm developing for both 'nix and Windows.)
>
> it can't be done. search the archives, this sort of thing almost always
> indicates a design flaw. for instance - what will your program do if there is
> no input?

I'm running an external command (using popen4 - yes, it is available on
Windows also). I capture stdout and stderr. "what will your program do
if there is no input?" - I assume you mean output - Well, I hope there
is no stderr output. If there is, I'd like to capture it and feed it
to Logger.

Likewise, if there is a problem, and there's no stdout, then I don't
want to wait for ever - I want to throw an exception.

S. Robert James

11/1/2006 12:17:00 AM

0

In the interests of promoting creativity, I'll ask the question without
any prior assumptions:

I'm using popen4 (great gem, btw) to run an external command and
capture stdout and stderr. If one (or both) of those is empty, I don't
want to hang. Just keep on moving. In fact, stderr will normally be
empty.

How could I do this?

(I'm supporting 'nix and Windows)

Ara.T.Howard

11/1/2006 12:33:00 AM

0

Ara.T.Howard

11/1/2006 12:35:00 AM

0

S. Robert James

11/1/2006 1:29:00 AM

0

Not very attractive...

Back to the original question: there is no simple way to read
nonblocking, or see if any output is available ?!?!


ara.t.howard@noaa.gov wrote:
> On Wed, 1 Nov 2006 srobertjames@gmail.com wrote:
>
> > I'm running an external command (using popen4 - yes, it is available on
> > Windows also). I capture stdout and stderr. "what will your program do if
> > there is no input?" - I assume you mean output - Well, I hope there is no
> > stderr output. If there is, I'd like to capture it and feed it to Logger.
> >
> > Likewise, if there is a problem, and there's no stdout, then I don't want to
> > wait for ever - I want to throw an exception.
>
> so, basically you want to timeout on a read right? in unix you can just use
>
> require 'timeout'
>
> Timeout::timeout(n) do
> Open4.popen4 ...
> ...
> ...
> end
>
> but, this is implimented via a thread so i think the read is going to block
> your entire process in windows... you might try it.
>
> -a
> --
> my religion is very simple. my religion is kindness. -- the dalai lama

Ryan Davis

11/1/2006 2:21:00 AM

0


On Oct 31, 2006, at 5:30 PM, S. Robert James wrote:

> Not very attractive...
>
> Back to the original question: there is no simple way to read
> nonblocking, or see if any output is available ?!?!

in io/wait:

--- IO#ready?
returns non-nil if input available without blocking, or nil.

also: ri IO.read_nonblock



Bjorn Borud

11/1/2006 2:27:00 AM

0

[ara.t.howard@noaa.gov]
|
| it can't be done. search the archives, this sort of thing almost
| always indicates a design flaw. for instance - what will your
| program do if there is no input?

nonblocking IO is not a design-flaw; it is something that is in common
use and is supported by most languages with a decent socket API. on
some OS'es this is even available for file IO (although widespread
language support seems to lag behind).

Java for example got proper nonblocking socket IO in 1.4 (see
JSR-000051 "New I/O APIs for the JavaTM Platform").

for examples of use you might want to check out the Reactor pattern
and other patterns for concurrent programming.

-Bjørn

Tom Pollard

11/1/2006 2:37:00 AM

0


On Oct 31, 2006, at 7:20 PM, srobertjames@gmail.com wrote:
> In the interests of promoting creativity, I'll ask the question
> without
> any prior assumptions:
>
> I'm using popen4 (great gem, btw) to run an external command and
> capture stdout and stderr. If one (or both) of those is empty, I
> don't
> want to hang. Just keep on moving. In fact, stderr will normally be
> empty.
>
> How could I do this?

Have you tried simply reading from them? When the command
terminates, that should close those pipes on the command's end. At
that point, a simple read on the stdout handle, for instance, will
return whatever output there was and then eof. If there's no output,
the read should return immediately. Did you try that yet? Did you
try the (Windows-oriented) example from the 'ri Open4' page? If
you're working in Unix you could try

status = POpen4::poen4('cat -') do |stdout, stderr, stdin|
stdin.puts 'hello world'
stdin.close
puts "stdout: #{stdout.read.strip}"
puts "stderr: #{stderr.read.strip}"
end

Anyway, you would only need nonblocking IO if you wanted to read bits
of the stderr stream before the command exited, but that doesn't
sound like what you're want.

Tom