读取后如何刷新 FIFO?

How do I flush a FIFO after reading it?

我有两个可执行文件,senderreceiverreceiver 将 fork 4 sender (在 fork() 之后立即调用 exec('sender') )并等待从每个 sender 接收数据。 (接收数据的顺序无关紧要。)

sender:

// executed by four different processes, forked from the `receiver`
fifo_write = fopen(fifo_name, "w"); 
setbuf(fifo_write, NULL); // make it unbuffered
fprintf( fifo_write, "%c %d %d\n", player_index, data1, data2 );

fprintf(stderr, "Sender(%d): send to receiver: %d %d\n", player_index, data1, data2);

fclose( fifo_out );

receiver:

/* fork and exec 4 senders here */

fifo_read = fopen( fifo_name, "r" );
setbuf(fifo_read, NULL); // make it unbuffered
for( i = 0; i < 4; ++i ){
    fscanf( fifo_read, "%c %d %d ", &index, &data1, &data2 );
    fprintf(stderr, "Receive from sender(%c): %d %d\n", index, data1, data2);
}

大多数时候,receiver 正确接收所有四组数据。但有时,receiver 会多次读取同一组数据。也就是说,我们可以观察到以下调试信息:

Sender(A): send to receiver: 1 2
Receive from sender(A): 1 2
Receive from sender(A): 1 2         # duplicate!
Sender(B): send to receiver: 3 4
Receive from sender(A): 1 2         # duplicate!
Receive from sender(B): 3 4

我怀疑缓冲 IO(fprintffscanf)可能是罪魁祸首,所以我将所有 IO 都变成无缓冲。

另一个可能的罪魁祸首可能是调用 fclose 的时间。我不太确定这是否是真正的问题,但 man 页面表明在另一端之前关闭 FIFO 可能会导致一些麻烦。

你怎么看?

您必须检查 fscanf 的 return 值。 fscanf 可以读取的令牌少于订购的令牌。在这种情况下,您可能会得到以前的值。

顺便说一句。您只能刷新输出流,不能刷新输入。