работа с FIFO

Модератор: Модераторы разделов

chuk
Сообщения: 27

работа с FIFO

Сообщение chuk »

Имеется два потока.
поток 1:

Код: Выделить всё

   запускает поток 2,
   открывает FIFO (Read only),
   читает FIFO,
   закрывает FIFO.


поток 2:

Код: Выделить всё

   открывает FIFO (Write only),
   пишет в FIFO,
   закрывает FIFO.


Работа происходит в блокирующем режиме.
Проблема возникает при обмене маленьким обьемом данных.
В этом случае может возникнуть ситуация, когда поток1 блокируется на открытии FIFO, а поток 2 быстро выполняет всю работу и завершается, при этом поток 1 остается заблокированым на открытии.
Как побороть?
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

пусть поток 1 открывает FIFO не дожидаясь открытия его на запись, а потом блокируется при попытки чтения.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

nesk писал(а):
22.04.2009 12:44
пусть поток 1 открывает FIFO не дожидаясь открытия его на запись, а потом блокируется при попытки чтения.

А как открыть файл FIFO без блокирования? Если open("FifoFile", O_RDWR), то функция read не вернет 0, когда поток 2 закончит работу, т.к. FIFO еще будет открыт для записи.
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

chuk писал(а):
22.04.2009 12:51
А как открыть файл FIFO без блокирования? Если open("FifoFile", O_RDWR),

O.o
Конечно не так. man open
O_NONBLOCK или O_NDELAY
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

nesk писал(а):
22.04.2009 12:44
пусть поток 1 открывает FIFO не дожидаясь открытия его на запись, а потом блокируется при попытки чтения.


Я подумал, так точно не получиться. Не будет блокироваться при чтении, так как FIDO окажется пустым и не открытым на запись, и read вроде как сразу вернет 0 :unsure:


PS Вообще странно, Ваш код вроде как должен работать нормально, так как блокировка с открытия на чтения, должна сниматься прямо в момент открытия FIFO на запись (и наоборот). Вы уверены, что open во втором потоке срабатывает без ошибки?
Давайте ваш код целиком.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
svary
Сообщения: 49
ОС: Linux FC-9

Re: работа с FIFO

Сообщение svary »

chuk писал(а):
22.04.2009 12:39
Имеется два потока.

Мне кажется. что для такой простой задачи гораздо лучше подходит использование pipe канала.
Типа такого :

Код: Выделить всё

int main(int argc, char *argv[])
{
        int  fd[2];  // Это файловые дескрипторы канала

        if (pipe(fd) < 0)   // Создаем канал
                err_sys("pipe error");
         // Создаем дочерний процесс
         if ( (pid = fork()) < 0)     err_sys("fork error");
        else if (pid > 0) {  // Родитель
                close(fd[0]);  // Закрываем ненужный канал на чтение
                write(fd[1], ...): // Пишем в канал
                 . . .
                close(fd[1]);   // Писанину закончили
                if (waitpid(pid, NULL, 0) < 0) // Ждем дочку
                        err_sys("waitpid error");
                exit(0); // Честно помираем
         } else {  // Дочка
                close(fd[1]);   // Закрываем ненужный канал на запись
                if (execl(MyProg,...) < 0) // Запускаем нужную программу и передаем ей файловый дескриптор.
                        err_sys("execl error for %s", pager);
                // А если оказались здесь, значит execl не отработал...
        }
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

похоже что помогло, большое спасибо.
А тут не возникнет обратной ситуации, когда поток 1 быстренько открывает, читает 0 байт (т.к. еще поток2 не открыл) и закрывает FIFO,
а только после этого поток2 пытается открыть FIFO?
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

chuk писал(а):
22.04.2009 13:26
похоже что помогло, большое спасибо.
А тут не возникнет обратной ситуации, когда поток 1 быстренько открывает, читает 0 байт (т.к. еще поток2 не открыл) и закрывает FIFO,
а только после этого поток2 пытается открыть FIFO?


:(
возникает
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

svary писал(а):
22.04.2009 13:22
Мне кажется. что для такой простой задачи гораздо лучше подходит использование pipe канала.

к сожелению pipe не желателен, т.к. код производящий чтение может читать и из файла.
А писать 2 разные функции которые деляю одно и тоже - очень не хочется
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

Вы проверяете ошибки open и write ?
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

nesk писал(а):
22.04.2009 13:48
Вы проверяете ошибки open и write ?

Вроде как проверяю.
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

nesk писал(а):
22.04.2009 13:11
Давайте ваш код целиком.

Сразу не заметил это сообщения, прошу прощщения.
Код у меня большой слишком, там примешена и работа с сокетами и работа и БД и много еще чего. Думаю не стоит выкладывать.
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

все должно работать.
вы уверены, что никто больше не держит этот FIFO открытым на чтение?
набросал маленькую программку, все работает нормально, правда с процессами.

Код:

$mkfifo fifo.my $ ./pfifo fifo.my 5 1 + Son PID=12221: I am sleeping....1 = Parent PID=12220: I am sleeping....5 + Son: I am open FIFO for write !!...T=1240398630 ==== Parent: I am open FIFO for read !!!...T=1240398634 ==== Parent: I am read !!!...T=1240398634 + Son: I am write !!...T=1240398634 ==== Parent: reading nbytes=6 ==== Received string in parent: Hello + Son: writing in pipe nbytes=6 + Son: Message to parent: Hello + Son: END !!!....T=1240398634 = Parent: END ...T=1240398634 --------------------------------------------------------- $ ./pfifo fifo.my 1 5 + Son PID=12223: I am sleeping....5 = Parent PID=12222: I am sleeping....1 ==== Parent: I am open FIFO for read !!!...T=1240398660 + Son: I am open FIFO for write !!...T=1240398664 + Son: I am write !!...T=1240398664 + Son: writing in pipe nbytes=6 + Son: Message to parent: Hello + Son: END !!!....T=1240398664 ==== Parent: I am read !!!...T=1240398664 ==== Parent: reading nbytes=6 ==== Received string in parent: Hello = Parent: END ...T=1240398664


попробуйте с разными задержками. ничего не должно виснуть
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

nesk писал(а):
22.04.2009 15:12
все должно работать.
вы уверены, что никто больше не держит этот FIFO открытым на чтение?
набросал маленькую программку, все работает нормально, правда с процессами.


Спасибо уважаемый nesk :-). С задержками - работает. Правда я ставил sleep(n) перед close(fd), чтобы гарантировать переключение контекcта с писателя на читателя.
Только жалко их ставить, получается сознательно снижается быстродействие.
И возникает подозрение: если в системе будет некий процесс потребляющий много процесороного времени sleep может и не помочь....
Наверное все-таки попробую вместо fifo - pipe.
FIFO создается и используется только моим процессом, уверен что больше некому его держать открытым.
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

chuk, я в примере использовал sleep до open (а не до close) что бы сымитировать ситуации когда первым канал открывает читатель, а писатель работает медленно и долго не открывает канал; и противоположную ситуацию, когда писатель первым открывает канал.

короче говоря, слипы я пытался использовать не для синхранизации, а наоборот, для того, что рассинхронизировать процессы и показать, что ничего виснуть не должно!

можете убрать все слипы и программа будет работать и не будет виснуть! :crazy:

Попробуйте сымитировать на примере моей программы, Ваше зависание
. Если сложно работать с Вашим большим кодом, давайте разберёмся с ошибкой на примере моего простого маленького кода.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
chuk
Сообщения: 27

Re: работа с FIFO

Сообщение chuk »

nesk писал(а):
23.04.2009 11:06
chuk, я в примере использовал sleep до open (а не до close) что бы сымитировать ситуации когда первым канал открывает читатель, а писатель работает медленно и долго не открывает канал; и противоположную ситуацию, когда писатель первым открывает канал.

короче говоря, слипы я пытался использовать не для синхранизации, а наоборот, для того, что рассинхронизировать процессы и показать, что ничего виснуть не должно!

можете убрать все слипы и программа будет работать и не будет виснуть! :crazy:

Попробуйте сымитировать на примере моей программы, Ваше зависание
. Если сложно работать с Вашим большим кодом, давайте разберёмся с ошибкой на примере моего простого маленького кода.

Пример - работает, модернизировал для потоков - тоже все работает устойчиво.
Очень похоже, что действительно где-то еще это FIFO читается.
Надо подумать....
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3

Re: работа с FIFO

Сообщение nesk »

chuk писал(а):
23.04.2009 12:09
Пример - работает, модернизировал для потоков - тоже все работает устойчиво.
Очень похоже, что действительно где-то еще это FIFO читается.
Надо подумать....


Я вот подумал, когда файл открывается потоком, он же открывается для процесса целиком? или нет?
Открыт Ваш FIFO или нет можно посмотреть командой lsof
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали: