Использование именованных каналов в одном процессе

Я пытаюсь использовать именованный канал для связи внутри процесса. Вот код

#include <stdio.h>
#include <fcntl.h>
#include <signal.h>

void sigint(int num)
{
    int fd = open("np", O_WRONLY);
    write(fd, "y", 1);
    close(fd);
}

main()
{
    char ch[1];
    int fd;

    mkfifo("np", 0666);

    signal(SIGINT, sigint);

    fd = open("np", O_RDONLY);

    read(fd, ch, 1);

    close(fd);

    printf("%c\n", ch[0]);
    return;
}

Я хочу, чтобы main блокировался до тех пор, пока что-то не будет записано в канал. Проблема в том, что обработчик сигнала sigint() также блокируется после открытия канала. Должно ли это произойти, учитывая, что канал уже открыт для чтения ранее в main() ?


person confused    schedule 12.02.2010    source источник


Ответы (2)


Вы блокируете в open() , открывая fifo для чтения блоков, пока кто-то не откроет его для записи.

И открытие fifo для записи блоков, пока кто-нибудь не откроет его для чтения.

обработчик сигнала работает в том же потоке, что и ваш main(), поэтому вы получите тупик. Ни один из них не сможет открыть fifo.

Вы можете проверить, что происходит, запустив вашу программу под strace.

person Anonym    schedule 12.02.2010
comment
Это на правильном пути - просто расширяя прогоны в той же части потока, SIGINT вызывает сбой open для O_RDONLY (прерванный системный вызов), а затем выполняет обработчик сигнала (до open звонок возвращается). - person caf; 13.02.2010

Со страницы руководства:

Открытие FIFO для чтения обычно блокируется до тех пор, пока какой-либо другой процесс не откроет тот же FIFO для записи, и наоборот.

а также:

Процесс может открыть FIFO в неблокирующем режиме. В этом случае открытие только для чтения завершится успешно, даже если еще никто не открывал на стороне записи; открытие только для записи не удастся с ENXIO (нет такого устройства или адреса), если другой конец уже не был открыт.

В Linux открытие FIFO для чтения и записи будет успешным как в блокирующем, так и в неблокирующем режиме. POSIX оставляет это поведение неопределенным. Это можно использовать для открытия FIFO для записи, когда нет доступных считывателей. Процесс, который использует оба конца соединения для связи с самим собой, должен быть очень осторожным, чтобы избежать взаимоблокировок.

person user231967    schedule 12.02.2010