這一次要記錄的是管線 (Pipe)的最後一個重點。在系統中程序與程序之間的溝通,有很多種方法,Pipe即是其中之一。
若是由fork()方式出來的父子程序,彼此之間的溝通,我們會選擇用pipe()函式─匿名管線 (Anonymous Pipe);若是要兩個彼此之間完全不相干的程序要溝通,則是使用mkfifo()─具名管線 (Named Pipe)。
課本的範例寫得還蠻簡單的,所以我自己又想了一個,剛好也把之前學過的東西融合進來。
※ 因為要建立兩者完全不相干的程序,所以我必須寫2支程式:procc.c (Process Client)和procd.c (Process Daemon)。
※ 為了要傳送不同型態的資料,我選擇建立一個struct (結構),裡面只有2個成員,一個是數值 (int flag),另一個則是字串 (char szTemp[])。
※ 從Process Client fork()出一個子程序 (Client-Child),要傳送的struct,初始值為flag = 0; szTemp[] = "Hello!! "; 以透過建立mkfifo()的方式,傳送給Daemon Process fork()出來的子程序 (Daemon-Child)。
※ Daemon-Child收到資料之後,把flag的值加一 (flag++),再透過pipe()傳送給原本的父程序 (Daemon-Parent);
※ Daemon-Parent收到資料之后,再串接上新的字串變成char szTemp[] = "Hello!! World!! "; 再透過建立管線的方式回傳給Client-Parent。
※ Client-Parent收到資料之後,就把結果印出來;結果應為:flag = 1; char szTemp[] = "Hello!! World!! ";
※ 為了要再加上dup(), dup2()的功能,會有一些Debug的訊息無法列印出來,所以我又另外獨立出procc_dup.c和procd_dup.c這兩支程式。
大致上就是如此,因為這4個程式碼實在是有點冗長,比較沒有辦法在Blogger中呈現;原本是想要放在GitHub,但發現好像連自己都不太會用,所以我把它們放在Google Drive,如下:
https://drive.google.com/file/d/0B4hMTvUWgd_gS2VuTzRDZnU0S2M/view?usp=sharing
對了,再提醒一下自己,mkfifo()也是可以做半雙工的溝通,但方法是一端開啟成fd = open("", "O_WRONLY")後,要先close(fd),再重新開啟成fd = open("", "O_RDONLY");反之亦然。
這種方法有一個難以Debug的問題─「就是mkfifo()兩端程序的Timing很難調適,一不小心就會變成兩端都是Read或是兩端都是Write,就會進入DeadLock (死結)。」
沒有留言:
張貼留言