Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Given <a href="https://stackoverflow.com/questions/2939065/unix-fifo-how-to-allow-only-one-writer-reader-pair-to-use-a-fifo/2942937#2942937">the code you posted in a separate answer</a>, here is a modified version that fixes the problems you were having. See the comments for details, but in a nutshell:</p> <ul> <li>The writer checks the return value of <code>mkfifo</code> is checked to see if another writer already created the pipe.</li> <li>The reader gets an exclusive advisory lock on the pipe (via <code>flock</code>) after opening it, to avoid the race condition where a second reader could have opened the pipe before the first reader deleted it.</li> </ul> <p>Writer:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/stat.h&gt; /* needed for mkfifo */ #include &lt;sys/types.h&gt; #include &lt;sys/wait.h&gt; #include &lt;fcntl.h&gt; #define BUFFERSIZE 50 #define CHMOD 0777 int main (int argc, char **argv) { char outbuf[BUFFERSIZE]; int fifo, j, anzahl; if (argc != 2) { printf("Ungültiger Parameter! Bsp.: ./fifow 10\n"); return 1; } anzahl=atoi(argv[1]); /* mkfifo fails if the file already exists, which means there's a * writer waiting for a reader. This assures that only one writer * will write to the pipe, since it only opens the pipe if it was * the one who created it. */ if (mkfifo("namedpipe4", CHMOD) == -1) { printf("namedpipe4 already exists\n"); return 1; } fifo = open("namedpipe4", O_WRONLY); for (j = 0; j &lt; anzahl; j++) { printf("Writer PID: %d writes record nr. %6d\n", getpid(), j + 1); sprintf(outbuf, "Writer PID: %d writes record nr. %6d\n", getpid(), j + 1); write(fifo, outbuf, BUFFERSIZE); remove("namedpipe4"); sleep(1); } close(fifo); exit(0); } </code></pre> <p>Reader:</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/file.h&gt; /* for flock */ #include &lt;sys/types.h&gt; #include &lt;sys/wait.h&gt; #include &lt;fcntl.h&gt; #define BUFFERSIZE 50 int main (int argc, char **argv) { char inbuf[BUFFERSIZE]; int fifo, var; printf("\n Waiting for a Pipe....\n"); /* There are *two* ways the open can fail: the pipe doesn't exist * yet, *or* it succeeded, but a different writer already opened * it but didn't yet remove it. */ while (1) { while ((fifo = open("namedpipe4", O_RDONLY)) == -1) { /* Since you didn't specify O_CREAT in the call to open, there * is no way that namedpipe4 would have been created by the * reader. If there *is* now a namedpipe4, a remove here * would delete the one the writer created! */ sleep(1); } /* Get an exclusive lock on the file, failing if we can't get * it immediately. Only one reader will succeed. */ if (flock (fifo, LOCK_EX | LOCK_NB) == 0) break; /* We lost the race to another reader. Give up and wait for * the next writer. */ close (fifo); } /* We are definitely the only reader. */ /* *Here* we delete the pipe, now that we've locked it and thus * know that we "own" the pipe. If we delete before locking, * there's a race where after we opened the pipe, a different * reader also opened, deleted, and locked the file, and a new * writer created a new pipe; in that case, we'd be deleting the * wrong pipe. */ remove("namedpipe4"); while ((var = read(fifo, inbuf, BUFFERSIZE)) &gt; 0) { printf("Reader PID: %d reads record: %s\n", getpid(), inbuf); /* No need to sleep; we'll consume input as it becomes * available. */ } close(fifo); printf("\n EOF..\n"); exit(0); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload