Контроль готовности файловых дескрипторов - PullRequest
0 голосов
/ 19 января 2011

У меня есть случай, когда у меня есть входящий поток сложных сообщений, которые требуют некоторой обработки, прежде чем они будут переданы в упрощенном формате фактическому обработчику.

Я хотел бы использовать дескриптор файла FIFO,одна нить заполняет его с одного конца, а другая нить читает с другого.Теперь такое поведение, которое я хотел бы иметь: поток чтения ожидает с select(), и я хотел бы гарантировать, что после пробуждения будет полный пакет, который можно прочитать с вызовом read(), т.е.хочу избежать повторной сборки пакетов из-за фрагментации из-за размеров буфера (пакеты гарантированно будут ниже предела пропускания буфера ядро-пользовательское пространство).

Я хочу знать, есть ли способ настройкиFIFO таким образом, чтобы я мог вручную определить, когда дескриптор файла готов, то есть, когда производитель успешно записал полный пакет, я хотел бы иметь способ сообщить конечному элементу чтения (через дескриптор файла), что чтениеготов.Есть ли способ достичь этого через ioctl() или есть какая-то абстракция, кроме FIFO, которая предлагает такое поведение (в мире Linux)?(Я знаю о pthread и условных переменных, но я бы хотел, чтобы связь между производителем и потребителем была ограничена дескриптором общего файла.)

Ответы [ 2 ]

2 голосов
/ 19 января 2011

Попробуйте socketpair () вместо pipe () / mknod (S_IFIFO) .

В домене можно создать пару сокетовAF_UNIX с типом SOCK_STREAM (на основе потока, для вашего использования потребуется кадрирование / повторная сборка), SOCK_DGRAM (на основе дейтаграмм, не будет фрагментировано или объединено) или SOCK_SEQPACKET (на основе записи, может быть фрагментированоно не объединены).

1 голос
/ 19 января 2011

Я хочу знать, есть ли способ настроить FIFO таким образом, чтобы я мог вручную определить, когда дескриптор файла готов

Такого пути нет.

Вы должны.

  • Определите какую-то структуру сообщения. например добавьте длину сообщения к сообщению или разделите их новой строкой (если в сообщении не может быть новой строки). В случае сообщений, разделенных символом новой строки, вы можете обернуть файловый дескриптор в файл FILE * и fgets () из этого, если только вы не зависите от select () для мультиплексирования нескольких потоков или предоставления времени ожидания.
  • Будьте готовы обработать read() или подобное сообщение чтения 1, менее 1 сообщения или более 1 сообщения - fifo - это просто поток байтов, поэтому на этом уровне нет границ сообщений.
  • Разбирайте прочитанные сообщения в зависимости от того, как вы решили их разделить.

Еще одна альтернатива - всегда отправлять сообщение фиксированной длины, чтобы вы всегда знали, сколько нужно прочитать, чтобы получить 1 сообщение, или, возможно, используйте гнезда дейтаграммы AF_UNIX - если вы можете определить разумный максимальный размер сообщения. 1018 *

...