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