程序之間的通訊 有名管道和無名管道

2021-10-09 22:21:38 字數 3669 閱讀 9986

四、程序之間的通訊。

1、 為什麼要學習程序之間的通訊?

例如:./1  -> 開啟了乙個名字為1的程序。

./2  -> 開啟了乙個名字為2的程序。

通過學習程序之間的通訊,使得不同的程序之間都是可以實現資料的交換。例如程序1傳送資料給程序2,程序2收到資料之後,根據資料來做不同的事情。(間接地實現程序1控制程序2)

2、在linux下,程序之間的通訊方式有哪些,都有什麼特點?

1)管道通訊。

管道通訊分為有名管道與無名管道,管道是一種特殊的檔案,程序通過將資料寫入到管道中,另外乙個程序從管道中讀取資料出來。

2)訊號。

在linux下,有非常多訊號,例如:暫停,繼續,停止..,某乙個程序通過傳送訊號給另外乙個程序,從而控制另外乙個程序。

3)訊息佇列。

某乙個程序把訊息傳送到佇列上,另外乙個程序就可以讀取佇列上的資料,訊息佇列好處:程序可以讀取佇列上某乙個特定的資料。

4)共享記憶體。(訊號量)

多個程序訪問同一片記憶體區域。

五、學習程序之間的通訊。 --- 無名管道

1、 什麼是無名管道?作用機制如何?

無名管道只能作用於親緣關係之間的程序,例如父子程序。

無名管道其實就是乙個陣列來的,這個陣列有兩個端,分別是讀端與寫端,程序想寫入資料到管道中,就往寫端中寫,如果程序想讀取管道中的資料,就讀取讀端上的資料。

2、使用無名管道步驟:

1)申請陣列。

int fd[2];  -> 裡面並不是讀端與寫端。

2)使用函式初始化陣列。  -> pipe()   -> man 2 pipe

初始化陣列  -> 初始化陣列中讀端與寫端的值。

功能: pipe, - create pipe

//建立一條管道

標頭檔案:#include

原型:int pipe(int pipefd[2]);

引數:pipefd: 乙個具有2個int型別資料的陣列。

返回值:

成功:0

失敗:-1

3)初始化成功

pipefd[0]  -> 讀端

pipefd[1]  -> 寫端

例子1: 寫乙個**測試無名管道中讀端與寫端的值是多少。

#include

#include

#include

#include

int main(int argc,char *ar**)

;printf("fd[0] = %d\n",fd[0]);

printf("fd[1] = %d\n",fd[1]);

//2、 使用pipe()去初始化這個陣列

int ret;

ret = pipe(fd);

printf("ret = %d\n",ret);

if(ret == 0)

//4、 列印讀端與寫端的值。

printf("fd[0] = %d\n",fd[0]);

printf("fd[1] = %d\n",fd[1]);

return 0;

}結果:

fd[0] = 0

fd[1] = 0

ret = 0

init pipe success!

fd[0] = 3    -> 讀端

fd[1] = 4    -> 寫端

例子2: 嘗試使用無名管道,讓父子程序之間進行通訊。

#include

#include

#include

#include

#include

int main(int argc,char *ar**)

;pipe(fd);

//2、 帶著這條無名管道去建立乙個新的程序。

pid_t x;

x = fork();

//3、 通過fork()函式的返回值去判斷。

if(x > 0)

;//2) 把需要寫入的資料放在緩衝區中。

fgets(buf,sizeof(buf),stdin);

//3) 將緩衝區中的資料寫入到無名管道中的寫端即可。

write(fd[1],buf,strlen(buf));

//4) 主動**子程序的資源。

wait(null);

//5) 父程序正常退出

exit(0);

}if(x == 0)

;//2) 直接讀取無名管道中的讀端,將資料讀取到緩衝區中。

read(fd[0],buf,sizeof(buf));

//3) 列印一下讀取出來的資料。

printf("from pipe:%s",buf);

//4) 子程序正常退出

exit(0);

}return 0;

}結果:

gec@ubuntu:/mnt/hgfs/gz2057/09 系統程式設計/02/code$ ./pipe_test2

nihao

from pipe:nihao

六、學習程序之間通訊。 -- 有名管道

1、什麼是有名管道?機制如何?

無名管道是乙個陣列來的,只能作用於同乙個檔案中。  -> 只能作用於親緣關係之間的程序。

有名管道是乙個檔案來的,檔案存在於檔案系統中,所以所有的程序都可以看到這個檔案。

機制:有名管道的機制.jpg

2、如何建立有名管道?  -> mkfifo()  -> man 3 mkfifo

功能: make a fifo special file (a named pipe)

//建立乙個特殊的管道檔案(命名管道)

標頭檔案:#include

#include

原型:int mkfifo(const char *pathname, mode_t mode);

引數:pathname: 需要建立的管道檔案的路徑  絕對路徑/相對路徑   "/home/gec/fifo_test"

mode:八進位制許可權   呼叫mkfifo之前,要先呼叫umask(0000)設定掩碼

例如: 0777

返回值:

成功:0

失敗:-1

例子1: 嘗試在家目錄建立乙個有名管道,名字為fifo_test。

#include

#include

#include

int main(int argc,char *ar**)

return 0;

}結果:

建立成功,並且在家目錄下看到fifo_test這個檔案。

gec@ubuntu:~$ ls -l fifo_test 

prwxrwxrwx 1 gec gec 0 sep 21 02:21 fifo_test

例子2: 嘗試使用有名管道,讓兩個陌生的程序進行通訊。

傳送端:

#include

#include

#include

#include

#include

#include

int main(int argc,char *ar**)

;while(1)

}//8. 關閉檔案。

close(fd);

return 0;

}作業1:完成有名管道接收端。

參考: 有名管道的機制.jpg 

傳送端**  -> fifo/

程序之間通訊 無名管道

程序之間常用的通訊方式有 1 無名管道 具有親緣關係的父子程序 2 有名管道 任意兩個程序 3 訊號 4 訊息佇列 5 記憶體共享 6 訊號量 一般是程序之間同步的手段,一般配合互斥鎖 條件變數一起使用 7 socket套接字 現在介紹最簡單的無名管道,用到的api函式如下 比較簡單,我們可以定義乙...

程序間通訊 有名管道 無名管道

顧名思義,管道就像是將資料放入到乙個長長的管子中一樣,肯定會有一端寫入資料,稱為寫端,有一段讀出資料,稱為讀端。既然是說像管子一樣那麼它肯定有大小吧,資源不是無窮無盡的,預設下管道的大小是64k,用ulimit a 可以檢視。1 無名管道 管道是半雙工的,資料只能向乙個方向流動 需要雙方通訊時,需要...

C 程序間通訊 有名管道,無名管道

1 管道的概念 管道是單向的 先進先出 的,它把乙個程序的輸出和另乙個程序的輸入連線在一起。乙個程序 寫程序 在管道的 尾部寫入 資料,另乙個程序 讀程序 從管道的 頭部讀出 資料。資料被乙個程序讀出後,將被從管道中刪除,其它讀程序將不能再讀到這些資料。管道提供了簡單的流控制機制,程序試圖讀空管道時...