2010-02-12 43 views
3

我正在尝试在进程内使用命名管道进行通信。 下面是代码在单个进程中使用命名管道

#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; 
} 

我想是主阻塞,直到东西写入到管道。 问题是信号处理程序sigint()在打开管道后也会阻塞。考虑到管道已经打开以便在main()中更早的读取,这是否应该发生?

回答

1

从手册页:

打开FIFO读取正常 块,直到其他进程打开 写入相同的FIFO和副 反之亦然。

和:

进程可以在 非阻塞模式打开一个FIFO。在这种情况下,即使在写入 侧没有人打开的情况下, 只读的打开将成功 ;除非另一端已经打开 ,否则只能写入 会导致ENXIO失败(无此设备或地址为 )。

在Linux下,打开一个用于读取 的FIFO,并且在 阻塞和非阻塞模式下写入都会成功。 POSIX 使此行为未定义。这个 可用于打开一个FIFO,用于编写 ,而没有可用的阅读器。 使用 连接的两端为了与自己沟通 的过程应该非常小心,以避免死锁。

3

您在open()中封锁,打开读取块的fifo,直到有人打开它写入。

然后打开一个写入块的FIFO,直到有人打开它阅读。

信号处理程序与main()运行在同一个线程中,所以你会遇到死锁。也不能打开前锋队。

您可以通过在strace下运行程序来检查发生了什么。

+0

这是在正确的轨道上 - 只是在“在同一个线程中运行”部分扩展,'SIGINT'导致'O_RDONLY'的'open'失败(“中断系统调用”),然后*然后*执行信号处理程序(在“open”调用返回之前)。 – caf 2010-02-13 07:14:15