[ale] Named Pipe

Christopher Fowler cfowler at outpostsentinel.com
Tue Mar 20 18:01:08 EDT 2007


Here it in in perl and works

#!/usr/bin/perl

use Fcntl;
use strict;


my $R= undef;
sysopen $R, "/tmp/fifo", O_RDONLY| O_NONBLOCK;

my $W = undef;
sysopen $W, "/tmp/fifo", O_WRONLY|O_NONBLOCK or die "$!\n";

close $R;

$SIG{'PIPE'} = sub { };

my $x = 1;
while(1) {
  my $data = sprintf "%05d
**************************************************\n", $x++;
  if(syswrite($W, $data, length($data)) <= 0) {
    next if $! =~ /Resource temporarily unavailable/;
    next if $! =~ m/Broken pipe/;
    die "$!\n";
  }

}


If you write to the pipe and no reader is there you get SIGPIPE.  I
simply do nothing with that signal and keep going.  If a reader does
show up they get data.  But no queued data.  They get data from where
the server is sending it from. 


On Tue, 2007-03-20 at 17:47 -0400, Christopher Fowler wrote:
> On Tue, 2007-03-20 at 14:54 -0600, JK wrote:
> > I think a series of UDP messages sent to a particular local
> > port would work almost as well.  When nothing's listening
> > on the port, you may get failed writes, but whenever something
> > *does* start listening, it will get the latest data, not
> > stuff that's been sitting there since a pipe filled.
> > 
> 
> Agreed.  But I think that pipes could still be used but there is a much
> better way.   
> 
> You need to implement a circular buffer in memory.  Write to that
> buffer.  When you get a reader on a pipe flush the buffer to the reader.
> Next write to reader.  When he closes go back to writing to the circular
> buffer.
> 
> Based on the email I would assume this data needs to be streamed and if
> you want to read it then you could read anywhere.  You do not want the
> master process blocking for a long period and not being able to process
> data.  You are just looking at a pipe as a way for processes to read
> that data whenever they want.
> 
> Unfortunately open() does not work like accept().  You can't place an
> open() operation in a select() queue.  You can accept().  This would
> work much better using a TCP socket on 127.0.0.1.  Create your buffer
> and use it.  Do a select() on accept() and when you get a client flush
> the buffer and start writing to that client instead of the buffer.  with
> this method you could have 100s of clients and only use the buffer when
> none are connected.
> 
> I used this method when writing an TCP -> serial app.  It would read
> serial and place data in a 1M buffer until client connected.  It would
> then dump to client and then feed client normal stuff.  The 1M was
> circular.
> 
> So maybe pipes would not be the best solution.  At least in UNIX there
> are many possible answers.  All good ones too!
> 
> 
> 
> _______________________________________________
> Ale mailing list
> Ale at ale.org
> http://www.ale.org/mailman/listinfo/ale




More information about the Ale mailing list