2015-11-19 2 views
1

У меня есть два исполняемых файла, sender и receiver. receiver будет развиваться 4 sender (звонок exec('sender') сразу после fork()) и ждать получения данных от каждого sender s. (Порядок приема данных не имеет значения.)Как очистить FIFO после прочтения?

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 (fprintf, fscanf) может быть виновником, поэтому я включаю все IO в небуферизован.

Другим возможным виновником может быть время, которое вызывается fclose. Я не совсем уверен, что это настоящая проблема, но страница man указывает, что закрытие FIFO до другого конца может вызвать некоторые проблемы.

Как вы думаете?

+1

Вы не читаете повторяющиеся данные, если не записаны повторяющиеся данные. Я склонен думать, что @ el.pescado имеет это право: там, где вы, по-видимому, читаете дубликаты данных, вы на самом деле не читаете никаких данных вообще. –

ответ

1

Необходимо проверить возвращаемое значение fscanf. fscanf может читать меньше токенов, чем указано. В этом случае вы можете получить предыдущие значения.

BTW. Вы можете очищать только выходные потоки, а не ввод.

+0

Вы можете * сливать * большинство входных потоков, хотя, читая и отбрасывая данные, пока не будет доступно больше данных. Однако это не решит проблему ОП, о которой я подозреваю, что вы правильно определили. –

Смежные вопросы