For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > October 2006 > Non-blocking write to FIFO









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Non-blocking write to FIFO
Peter Daum

2006-10-23, 7:57 am

Sorry, this probably really is more a general unix/linux problem than
a perl issue but I couldn't find any more suitable place to ask:

I am trying to figure out a way to write data to a fifo without
knowing whether there is a reader available and without ever blocking.
What I'd like is somthing like this:

sysopen(FIFO, $fifo, O_NONBLOCK|O_WRONLY)
or die "Can't open fifo $fifo: $!\n";
....;

while (my $bytes=sysread(IN,$buf,$block_size)) {
if ($fifo) {
# do other stuff:
...;
# write in case somebody cares to read:
syswrite(FIFO, $buf);
}
}

Unfortunately, the open fails unless there is somebody reading from
the fifo- It is possible to open a fifo for read without blocking, but
I couldn't find any way to do this for writing. For reading, it also
seems to be possible to ge a signal if data is available, but I can't
think of any way to get such a signal if the pipe is opened for
reading (so I could afterwards open it for writing).

Ainy ideas?

Regards,
Peter Daum


Jeff Pang

2006-10-23, 7:57 am


>Unfortunately, the open fails unless there is somebody reading from
>the fifo- It is possible to open a fifo for read without blocking, but
>I couldn't find any way to do this for writing. For reading, it also
>seems to be possible to ge a signal if data is available, but I can't
>think of any way to get such a signal if the pipe is opened for
>reading (so I could afterwards open it for writing).
>


Hello,

From the perlipc.pod,

A fifo is convenient when you want to connect a process to an unrelated one. When you open a fifo, the program will block until there's something on the other end.

For example, let's say you'd like to have your .signature file be a named pipe that has a Perl program on the other end. Now every time any program (like a mailer, news reader, finger program, etc.) tries to read from that file, the reading program will b
lock and your program will supply the new signature. We'll use the pipe-checking file test -p to find out whether anyone (or anything) has accidentally removed our fifo.


So I think there is no way but you just need to keep another program to be reading from the FIFO when you're writing to it.


--
Books below translated by me to Chinese.
Practical mod_perl: http://home.earthlink.net/~pangj/mod_perl/
Squid the Definitive Guide: http://home.earthlink.net/~pangj/squid/
Tom Phoenix

2006-10-23, 6:57 pm

On 10/23/06, Peter Daum <gator_ml@yahoo.de> wrote:

> I am trying to figure out a way to write data to a fifo without
> knowing whether there is a reader available and without ever blocking.


Although you could use the four-arg select() to detect ready-to-write,
there's no way to avoid filling the buffer and blocking without
checking select() again after each byte.

One solution, if it works in your situation, might be to fork a child
process which will write the data, blocking as needed, allowing the
main program to continue without blocking.

Good luck with it!

--Tom Phoenix
Uri Guttman

2006-10-23, 6:57 pm

>>>>> "TP" == Tom Phoenix <tom@stonehenge.com> writes:

TP> On 10/23/06, Peter Daum <gator_ml@yahoo.de> wrote:[color=darkred]

TP> Although you could use the four-arg select() to detect ready-to-write,
TP> there's no way to avoid filling the buffer and blocking without
TP> checking select() again after each byte.

why after each byte? a non-blocking write will return the number of
bytes written so you can try to write as much as you want each
time. then you either have to do other work and check again later. the
best way to do that is with an event loop. the OP should look into
Event.pm (my choice) or IO::Select

uri

--
Uri Guttman ------ uri@stemsystems.com -------- http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Peter Daum

2006-10-23, 6:57 pm

.... in the meantime, I discovered a solution, so let me answer
my own question in case somebody else stumbles on this.

Peter Daum wrote:
> I am trying to figure out a way to write data to a fifo without
> knowing whether there is a reader available and without ever blocking.
> What I'd like is somthing like this:
>
> sysopen(FIFO, $fifo, O_NONBLOCK|O_WRONLY)
> or die "Can't open fifo $fifo: $!\n";
> ...;
>
> while (my $bytes=sysread(IN,$buf,$block_size)) {
> if ($fifo) {
> # do other stuff:
> ...;
> # write in case somebody cares to read:
> syswrite(FIFO, $buf);
> }
> }
>
> Unfortunately, the open fails unless there is somebody reading from
> the fifo- It is possible to open a fifo for read without blocking, but
> I couldn't find any way to do this for writing. ...


I don't know whether this is linux-specific (the fifo man page doesn't
mention it) but with a tiny change the code above does what I want:
If you use "O_RDWR" instead of "O_WRONLY" the "open" call succeeds even
without anybody reading from the fifo. When the buffer is full it is
obviously overwritten again, so a client reads only the data that is
written after it has opened the fifo for reading, but for my porposes,
this is just what I need ...

Regards,
Peter Daum



Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com