读取后如何刷新FIFO?

时间:2015-11-19 14:33:47

标签: c fork fifo

我有两个可执行文件senderreceiverreceiver将分叉4 sender(在exec('sender')之后立即调用fork())并等待接收来自每个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可能会造成一些麻烦。

您怎么看?

1 个答案:

答案 0 :(得分:1)

您必须检查fscanf的返回值。 fscanf可以读取比订购的更少的令牌。在这种情况下,您可能会获得以前的值。

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