считайте не блокирование на именованном канале

у меня есть следующий бит кода C, который читает из канала и затем должен заблокироваться, но он никогда блоки

int pipe_fd;
int res;
int open_mode = O_RDONLY;
char buf[100];
int bytes_read = 0;

memset (buf, '\0', sizeof(buf));
pipe_fd = open(FIFO_NAME, open_mode);

if (access(FIFO_NAME, F_OK) == -1)
{
    res = mkfifo(FIFO_NAME, 0777);
    if (res != 0)
    {
            fprintf (stderr, "Could not create fifo %s\n", FIFO_NAME);  
            exit (EXIT_FAILURE);
    }
}

for(;;)
{        
    do     
    {     
        res = read(pipe_fd, buf, sizeof(buf));
        bytes_read += res;
    }while (res > 0);

    // process data then go back and block
    ............
}

Это отправляется простой буфер некоторым кодом в сценарии удара как этот './test 1'

#!/bin/bash

pipe=/tmp/pipe

if [[ ! -p $pipe ]]; then
    echo "Reader not running"
    exit 1
fi

if [[ "$1" ]]; then
     echo "some string" >$pipe
else
     echo "q" >$pipe
fi

Я запускаю программу кода C в gdb, и первоначально это действительно блокируется на чтении, но как только я звоню, удар не пишут сценарий кода C больше блоки, это действительно успешно считывает данные с буфера и затем каждый раз, когда это читает существует 0-байтовое чтение, таким образом, не уверенное почему его больше блокирование. 'Некоторая строка' данные правильно получена в другой стороне.

Мне просто нужен он для нахождения, там ожидая данных, обрабатывают его и затем возвращаются и ожидают больше

11
задан tech74 12 August 2010 в 11:13
поделиться

2 ответа

Я запускаю программу на C-коде в gdb и сначала она блокируется при чтении, но как только я вызываю bash-скрипт, C-код больше не блокируется, он успешно считывает данные из буфера, а затем при каждом чтении считывается 0 байт, так что не уверен, почему он больше не блокируется. Данные 'some string' правильно получены на другой стороне.

0 означает EOF. FIFO может быть прочитан или записан только тогда, когда есть процессы, подключенные к нему как для чтения, так и для записи. Когда писателей больше нет (ваши shell-скрипты завершены), читатели уведомляются об этом через read(), возвращающую EOF.

FIFO ведут себя таким образом, чтобы быть совместимыми с логикой shell pipe, например:

$ mkfifo ./tmp1
$ cat < input > ./tmp1 &
$ cat < ./tmp1 > /dev/null

Если read() не вернет EOF, то второй cat будет блокироваться вечно.

Мне нужно, чтобы он просто сидел и ждал данных, обрабатывал их, а затем возвращался и ждал еще

В вашей программе на C вы должны повторно открыть() FIFO после того, как read() вернул EOF в первый раз.

P.S. Нашел неплохую сводку по FIFO для вас. Посмотрите таблицу на второй странице.

17
ответ дан 3 December 2019 в 07:10
поделиться

ваш сценарий bash закрывает канал, поэтому C получает условие "eof"

0
ответ дан 3 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: