help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FIFO read by Octave does not block as desired


From: John W. Eaton
Subject: FIFO read by Octave does not block as desired
Date: Fri, 28 Aug 1998 14:17:16 -0500 (CDT)

On 28-Aug-1998, Marco Bravi <address@hidden> wrote:

|       I would like to use Octave as the control environment for a
| simulation environment, and the two should communicate over two FIFOs.
| 
| I am experiencing a misbehaviour of this type: once the input FIFO has
| been read once (blocking read, as expected), all subsequent reads return
| immediately, even if the other program is not blocked in the corresponding
| write. No data is actually input by this read.
| 
| This is the infinite loop I use on the Octave part:
| 
| fid1 = -1;
| fid2 = -1;
| 
| 
| times = 10;
| 
| while (times)
|      times--;
|      if (fid1 < 0)
|         fprintf(stderr, "Open gPROMS.pipe...");
|         fid1 = fopen("../gproms/gPROMS.pipe", "r");
|         fprintf(stderr, "done.\n");
|      end
|      fprintf(stderr, "I am about to read...");
|      [a, b, c, d, e, f] = fscanf(fid1, "%g %g %g %g %g %g\n", "C")
|      fprintf(stderr, "done.\n");
|      fprintf(stderr, "Going to sleep...");
|      sleep(15);
|      fprintf(stderr, "awaken.\n");
|      if (fid2 < 0)
|         fprintf(stderr, "Opening Matlab.pipe...");
|         fid2 = fopen("../gproms/Matlab.pipe", "w+");
|         fprintf(stderr, "done.\n");
|      end
|      fprintf(stderr, "About to send Wf...");
|      fwrite(fid2, "4\n");
|      fflush(fid2);
|      fprintf(stderr, "done.\n");
| endwhile
| 
| The other side has been implemented in several ways. For test purposes, a
| small C program using stdin/stdout and talking to the FIFOS is what I use
| for debugging all my programs uising FIFOS.
| 
| What's most puzzling, is that once the first read has been performed
| correctly (i. e., with blocking behaviour) the fscanf call returns *even
| if the other program is terminated*, i. e., no other program is writing
| the FIFO. This appears rather strange to me since I did not open the FIFO
| for read/write (as it is often seen in order to avoid blocking on open).
| 
| Could you please suggest an explanation for this and a workaround for
| correctly syncyng the two concurrent processes with this FIFO read/write
| system?

What does the other process do in between writes to the FIFO?  Does it
exit or close the FIFO and then open it again before the next write?

I believe the behavior you are seeing is correct, but I can't be
absolutely sure, since you haven't provided all the details.

If you open a FIFO for reading only (i.e., mode == "r"), and no other
process has the FIFO open for writing, the open blocks.  Then once
another process opens the FIFO for writing, the reader of the FIFO
will be able to read from its end until the number of processes that
have the FIFO open for writing drops to 0.

If you open a FIFO for reading and writing (i.e., mode == "r+"), and
no other process has the FIFO open for writing, the open doesn't
block, but reading will.  Then your FIFO will stay open until you
close it, even if there are no writers on the other end.

I tried this with Octave 2.0.13 on a Linux system using the following
script:

  fid = -1;
  times = 10;

  mode = "r";  # or "r+", to keep the FIFO open even if no other
               # process is writing to it

  while (times)
    times--;
    if (fid < 0)
      fprintf(stderr, "Open foo.pipe...");
      fid = fopen("foo.pipe", mode);
      fprintf(stderr, "done.\n");
    endif
    fprintf(stderr, "I am about to read...");
    s = fgetl(fid);
    fprintf(stderr, "done.\n");
    if (isstr (s))
      fprintf (stderr, "read: %s\n", s);
    else
      fprintf (stderr, "read on pipe failed\n");
    endif
    fprintf (stderr, "sleeping...");
    sleep (1);
    fprintf (stderr, "done\n");
  endwhile

Running this script with mode = "r" when no other processes have the
FIFO open for writing results in the open blocking.  Then when another
process opens the FIFO and starts writing, the script echos data
returned by the call to fgetl.  If there are fewer than 10 writes
before the other process exits, fgetl sees EOF on the FIFO and quits
reading.  Even if another process later opens the FIFO for writing,
Octave will still see EOF unless it closes and reopens the FIFO.

Running this script with mode = "r+" when no other processes have the
FIFO open for writing causes Octave to *not* block at the open, but
instead to block at the first call to fgetl.  Then when another
process opens the FIFO and starts writing, the script echos data
returned by the call to fgetl.  If there are fewer than 10 writes
before the other process exits, fgetl blocks until another process
writes to the FIFO.

In my tests, I just used

  echo foo > foo.pipe

or

  for i in 0 1 2 3 4 ; do echo $i ; done > foo.pipe

to write to the FIFO.

Based on what I've just read about FIFOs in "Advanced Programming in
the Unix Environment" by Stevens, I believe this is the correct
behavior, but please correct me if I'm getting something wrong here.

Thanks,

jwe



reply via email to

[Prev in Thread] Current Thread [Next in Thread]