2010-02-12 100 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