Если вы выполняете open () в правильном порядке, условия гонки отсутствуют. (единственно возможная гонка - это третий процесс, мешающий тем же самым фифо) Из прекрасного руководства:
"Тем не менее, он должен быть открыт с обоих концов одновременно, прежде чем вы сможете приступить к выполнению каких-либо операций ввода или вывода на нем. Открытие FIFO для обычного чтения блоков, пока какой-либо другой процесс не откроет тот же FIFO
для письма и наоборот. "
Это означает, что заказ
{процесс 1: открытый (fifo1, RO); процесс2: открытый (fifo1, WO); }
...
{процесс 1: открытый (fifo2, WO); процесс2: открытый (fifo2, RO); }
всегда будет успешным (без остановки процесса). Порядок операций на каждой пятерке не важен; для fifo1 первым может идти процесс1 или процесс2 (и он будет заблокирован, пока другая сторона не добьется успеха).
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define FIFO1 "fifo1"
#define FIFO2 "fifo2"
void do_master(void);
void do_slave(void);
void randsleep(unsigned max);
/************************************/
void do_master(void)
{
int in,out, rc;
char buff[20];
randsleep(5);
mkfifo(FIFO1, 0644);
randsleep(7);
mkfifo(FIFO2, 0644);
out = open(FIFO2, O_WRONLY);
if (out == -1) {
fprintf(stderr, "[Master]: failed opening output\n" );
return;
}
fprintf(stderr, "[Master]: opened output\n" );
in = open(FIFO1, O_RDONLY);
if (in == -1) {
fprintf(stderr, "[Master]: failed opening input\n" );
close(out);
return;
}
fprintf(stderr, "[Master]: opened input\n" );
rc = write( out, "M2S\n\0" , 5);
fprintf(stderr, "[Master]: wrote %d\n", rc );
rc = read( in, buff , sizeof buff);
fprintf(stderr, "[Master]: read %d: %s\n", rc, buff );
unlink(FIFO1);
unlink(FIFO2);
}
/***********************************/
void do_slave(void)
{
int in,out, rc;
unsigned iter=0;
char buff[20];
loop1:
in = open(FIFO2, O_RDONLY);
if (in == -1) {
fprintf(stderr, "[Slave%u]: failed opening input\n", ++iter );
randsleep(2);
goto loop1;
}
fprintf(stderr, "[Slave]: opened input\n" );
loop2:
out = open(FIFO1, O_WRONLY);
if (out == -1) {
fprintf(stderr, "[Slave%u]: failed opening output\n", ++iter );
randsleep(3);
goto loop2;
}
fprintf(stderr, "[Slave]: opened output\n" );
rc = write( out, "S2M\n\0" , 5);
fprintf(stderr, "[Slave]: wrote %d\n", rc );
rc = read( in, buff , sizeof buff);
fprintf(stderr, "[Slave]: read %d:%s\n", rc, buff );
}
/*************************************/
void randsleep(unsigned max)
{
unsigned val;
val = rand();
val %= max;
sleep(val);
return;
}
/*************************************/
int main(void)
{
int rc;
switch (rc=fork()) {
case -1: exit(1); break;
case 0: do_slave(); break;
default: do_master(); break;
}
exit (0);
}