Я использую именованные каналы POSIX (fifos) для отправки записей из одного или нескольких потоков для чтения другим потоком (только один поток выполняет чтение). Однако 83-я запись из 100 записей просто отбрасывается. Ядро клиента вызывает запись, и возвращаемое значение правильно указывается как длина записи (720 байт), поэтому ядро клиента (записывающего) подтверждает, что запись отправлена, но переключается на ядро считывателя в режиме отладки gdb с блокировкой планировщика. затем я читаю несколько предыдущих записей, а затем не могу прочитать - в канале нет записей, хотя ядро клиента (записывающего) подтвердило запись.
Емкость канала составляет 65 536 байт (по умолчанию в Linux). Я предполагаю, что содержимое канала уменьшается на 1 запись для каждого чтения записи, поэтому в момент, когда 83-я запись отбрасывается, у меня есть около 5 предыдущих записей в канале, или 3600 байт - недостаточно для заполнения канала.
Я открыл трубы в неблокирующем режиме, потому что, когда я открыл их в режиме блокировки, оба конца замерзли. Согласно справочным страницам в http://man7.org/linux/man-pages/man7/fifo.7.html, «FIFO должен быть открыт на обоих концах (чтение и запись), прежде чем данные могут быть переданы. Обычно, открытие блоков FIFO до открытия другого конца также. " Моя проблема заключается в том, что оба конца блока и не будет go дальше. В нем также говорится: «В Linux открытие FIFO для чтения и записи будет успешным как в режиме блокировки, так и в режиме неблокирования. POSIX оставляет это поведение неопределенным».
Код на каждом конце прост:
int64_t fifo_write(int fd, const void *buf, size_t count) {
int status_write = write(fd, buf, count);
return status_write; }
int64_t fifo_read(int fd, void *buf, size_t count) {
int status_read = read(fd, buf, count);
return status_read; }
Функции C вызываются из моей программы NASM:
mov rdi,[fifo_read_fd]
lea rsi,[fifo_buffer]
mov rdx,720
call fifo_read wrt ..plt
mov rdi,[fifo_write_fd]
mov rsi,[rbp-24]
mov rdx,720 ; bytes
push r11
push rcx
call fifo_write wrt ..plt
pop rcx
pop r11
Мои вопросы:
Что может вызвать удаление записи? Это не похоже на емкость канала, если канал не очищается при чтении каждой записи - даже все 83 записи будут занимать 59760 байт, что ниже пропускной способности канала 65 КБ в Linux. Это может быть связано с неблокирующим режимом, но если канал не заполнен, нет причин для блокировки.
Как я могу открыть оба конца в режиме блокировки (учитывая, что оба конца зависают, каждый ждет другого), и есть ли у меня какие-либо проблемы с режимом блокировки?
Я мог бы открыть оба конца в режиме чтения / записи, потому что мой код записывает только из одного или нескольких потоков на одном конце и читает из 1 потока (только) на другом конце. Хотя «POSIX оставляет это поведение неопределенным», есть ли причины не открывать оба конца в режиме чтения / записи в этой ситуации?
Я не разместил ни одного другого кода с этим вопросом (кроме как выше), потому что я только ищу идеи о лучшем способе решения проблемы пропущенной записи в случае Я описал.