Using files to transfer data between processes

L

Larry

Hello everyone,

I hope one of you very knowledgeable perl gurus could shed some light
on a problem I am trying to solve. I have two processes (say process
A and process B) that need to talk to each other. Process A will
collect data that it needs to forward to process B. I want to put the
data onto disk so that I have a permanent record of the data in case
process A or B die. I'd like to have process B read the data from the
file. So A puts data in and B reads data out, similar to a named pipe
but using the disk so that we have a permanent record (as well as a
large storage area). I want process B to read the file but also be
able to handle input from a socket as well.

Doing some digging, I can have process B, do something like the
following :

use IO::Seekable;

chdir "/tmp";
$FIFO = "/tmp/fifo";
sub fhbits {
my @fhlist = @_;

my $bits;
for (@fhlist) {
vec($bits, fileno($_), 1) = 1;
}
return $bits;
}

open (FIFO, "<$FIFO") or die "can't open file $FIFO: $!";

my $rin = fhbits(qw(STDIN FIFO));
while (1) {
($nfound, $timeleft) = select($rout=$rin, undef, undef, undef);
if (($nfound != -1) && (vec($rout, fileno(FIFO), 1) == 1)) {
sysread FIFO, $data, 2000;
print "Just read from FIFO: $data\n";
if (eof(FIFO)) {
FIFO->clearerr();
}

} elsif (($nfound != -1) && (vec($rout, fileno(STDIN), 1) == 1)) {
sysread STDIN, $data, 2000;
print "Just read from STDIN: $data\n";
}
}

The problem with this code is that the FIFO file handle keeps firing
because of the end of file, i can clear it but it constantly fires off
if there is no data to process. I realize that I can force a wait by
doing something like :

$data = <FIFO>;

But this keeps the code from reading from the other file handle.

I'm thinking that there may be a way to stop the select from returning
on an eof condition but my feeling is that it will probably not help.

I hope that this isn't a new issue and that someone out there has done
something similar and can help me out.

As always, many thanks for taking the time to read and reply, your
help is much appreciated.
 
L

Larry

K,

Never mind as I think i have a solution for this. I guess we can't
get around resetting the eof marker and polling the file to read a
file that is growing. I'll just have the process that updates the
file send a signal (or communicate via a socket) to the reading
process that there is data available to read so that I can avoid
having to poll for updates.
 
S

Scott W Gifford

(e-mail address removed) (Larry) writes:

[...]
The problem with this code is that the FIFO file handle keeps firing
because of the end of file, i can clear it but it constantly fires off
if there is no data to process. I realize that I can force a wait by
doing something like :

AFAIK, there's no way to tell select "only return if the file has
grown". Essentially what you're doing is emulating "tail -f", which
leads to this FAQ:

http://www.perl.com/doc/FAQs/FAQ/oldfaq-html/Q5.22.html

The solution employed there, and the one I've used in similar
situations, is to simply sleep() after reaching EOF, then check after
that to see if the file has grown. Essentially you're polling, but
since you know how the programs work, you can time the sleep()s so
that you usually don't poll unless there's data waiting.

You could also use something like tee(1) to send the data from A to B
using a pipe, but record the results as they're sent, since pipes have
the behavior you want. Or just have A record the data in a file as
it's sent to a pipe or socket, or have B record the data as it reads
it.

-----ScottG.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top