Итак (1) ваши рассуждения о синхронизации FIFO верны;(2) есть вероятность того, что linux испортится;Итак (3) у вас есть ошибка.
Трудно сказать, но, поскольку вы изначально открываете сервер fifo как O_RDWR, возможно, вы не закрываете то, что думаете?Возможно, у вас работает второй клиент, у которого уже есть этот fifo, открытый как считыватель, и когда вы снова открываете его как O_WRONLY, он не блокируется?
В любом случае вашей реальной проблемой является разработанный вами протокол.Я не вижу необходимости в замках или в том, чтобы держать их открытыми и закрывать ящики.Вам действительно нужен разумный протокол связи.
Обычно это что-то вроде:
(1) на сервере есть хорошо известная fifo, которую клиенты открывают и пишут в нее.
(2) клиенты передают код транзакции или что-то, указывающее, что это начальный запрос.Включен некоторый метод установления сервером обратного соединения с клиентом.Это может быть полное имя пути или просто pid, который и клиент, и сервер используют с предопределенным путем для создания второго fifo (например, оба открывают "/ tmp / myfifo_pid" или что-то подобное).
(3) После того, как клиент и сервер откроют второй fifo, все дальнейшие клиентские запросы к серверу включают pid (или любой другой), чтобы сервер знал, куда выводить запрос.
(4) После того, как все сделано,клиент отправляет транзакцию с указанием так, что сервер может закрыть 2-е число.Клиент делает то же самое.
(5) Повторите для всех клиентов.
Обратите внимание, что вам необходимо указать формат для ваших сообщений.Проверенными временем методами являются использование длинного кода (кажется, что вы пытаетесь) или какой-либо разделитель конца сообщения (например, новая строка).
Редактировать
Возможный формат сообщения:
length | trancode || data |
где length указывает, сколько последующих байтов составляют все сообщение, транскод указывает и операцию (например, открыть мой вывод fifo, закрытьотправьте данные, что угодно), а данные - это то, что подходит для транзакции.