天天看點

系統程式設計-程序間通信-無名管道

管道檔案是一個特殊的檔案,是由核心環形隊列來實作的。

函數形式: int pipe(int fd[2]) ,無需額外調用open,但需手動調用close來關閉fd[0]和fd[1]。

功能: 該系統調用,用于建立無名管道。無名管道作用于有血緣關系的程序之間,完成資料傳遞。

頭檔案:#include <unistd.h>

參數:兩個檔案描述符,fd[0]是讀端,fd[1]是寫端。

傳回值: 成功傳回0,出錯傳回-1。

特點:

** 管道是建立在記憶體中的,程序結束,空間釋放,管道就不存在了。

** 管道中的資料,讀完後就被删除了。

** 如果管道中沒有資料可讀,則會阻塞。

** 如果管道被寫滿了,也會阻塞。

局限性:

**資料一旦被讀走,便不在管道中存在,不可反複讀取。

**由于管道采用半雙工通信方式。是以,資料隻能在一個方向上流動。

**隻能在有公共祖先的程序間使用管道。

實驗1 -  實作父子程序間通信

實驗思路:

1. 父程序調用pipe函數建立無名管道,得到兩個檔案描述符fd[0]、fd[1]指向管道的讀端和寫端。

2. 父程序調用fork建立子程序,那麼子程序也有兩個檔案描述符指向同一管道。

3. 父程序關閉管道讀端,子程序關閉管道寫端。(這才是正确操作,隻留一個入口,一個出口,這樣才能保證資料隻在一個方向上流動)

 父程序可以向管道中寫入資料,子程序将管道中的資料讀出。

    由于管道是利用環形隊列實作的,資料從寫端流入管道,從讀端流出,這樣就實作了程序間通信。

實驗代碼:

#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>
 
void sys_err(const char *str)
{
    perror(str);
    exit(1); 
}
 
int main(void)
{
    pid_t pid;
    char buf[1024];
    int fd[2];
     
    char *p = "test for pipe\n";
 
    if (pipe(fd) == -1)
        sys_err("pipe");
 
    pid = fork();
    if (pid < 0) {
        sys_err("fork err");
     
    }else if (pid == 0) {
        close(fd[1]);
        int len = read(fd[0], buf, sizeof(buf));
        write(STDOUT_FILENO, buf, len);
        close(fd[0]);
     
    }else {
        close(fd[0]);
        write(fd[1], p, strlen(p));
        wait(NULL); // 不擷取子程序死因,傳入NULL即可。
            // 父程序一旦調用了wait就立即阻塞自己,由wait自動分析是否目前程序的某個子程序已經退出。
        close(fd[1]);
    }

    return 0;
}      

.

/************* 社會的有色眼光是:博士生、研究所學生、大學生、工廠中的房間勞工; 重點大學高材生、普通院校、二流院校、野雞大學; 年薪百萬、五十萬、五萬; 這些都隻是帽子,可以失敗千百次,但我和社會都覺得,人隻要成功一次,就能換一頂帽子,隻是社會看不見你之前的失敗的帽子。 當然,換帽子決不是最終目的,走好自己的路就行。 杭州.大話西遊 *******/