管道通訊
管道是單向、先進先出的,他把乙個程序的輸出和另乙個程序的輸入連在一起。
兩個程式之間傳遞資料的一種簡單方法是使用popen和pclose。
#include
file *popen(const
char *command, const
char *type);
int pclose(file *stream);
popen函式允許乙個程式將另乙個程式作為新程序來啟動,並可以傳遞資料給它或者通過它接收資料。command字串是要執行的程式名和相應的引數。type必須是」r」或」w」。
如果type是」r」,被調程式的輸出就可以被呼叫程式使用,呼叫程式利用popen函式返回的file *檔案流指標,可以讀取被調程式的輸出;如果type是」w」,呼叫程式就可以向被調程式傳送資料,而被調程式可以在自己的標準輸入上讀取這些資料。
pclose函式只在popen啟動的程序結束後才返回。如果呼叫pclose時它仍在執行,pclose將等待該程序的結束。
管道型別
無名管道:用於父子程序之間的通訊。
無名管道由pipe()函式建立:int pipe(int filedis[2]);
當乙個管道建立時,它會建立兩個檔案描述符:
filedis[0]用於讀管道,filedis[1]用於寫管道。
順序不能顛倒。
//**例子
#include
#include
#include
#include
int main()
else
close(pipe_fd[0]);
close(pipe_fd[1]);
return
0;}
管道用於不同程序間通訊,通常先建立乙個管道,再用fork()函式建立乙個子程序,該子程序會繼承父程序所建立的管道描述符。必須在fork()前呼叫pipe(),否則子程序將不會繼承檔案描述符
#include
#include
#define size 1024*100
int main()
ret = write (fd[1], "hello", 5);
printf ("寫入 %d 個位元組\n", ret);
char ch;
while (1)
printf ("讀到 %d 個位元組: %c\n", ret, ch);
}close (fd[0]);
close (fd[1]);
return
0;}
#include
#include
int mkfifo(const
char *pathname, mode_t mode);
int mkfifo(const char *pathname, mode_t mode);
pathname: fifo檔名
mode:屬性(同檔案操作)
一旦建立了乙個fifo,就可用open開啟它,一般的檔案訪問函式(close、read、write等)都可用於fifo。
當開啟fifo時,非阻塞標識(o_nonblock)將對以後的讀寫產生影響:
1、沒有使用o_nonblock:訪問要求無法滿足時程序將阻塞。如果試圖讀取空的fifo,將導致程序阻塞。
2、使用o_nonblock:訪問要求無法滿足時不阻塞,立刻出錯返回。errno是enxio。
共享記憶體
共享記憶體實現分兩個步驟:
1、建立共享記憶體,使用shmget函式
2、對映共享記憶體,將這段建立的共享記憶體對映到具體的程序空間去,使用shmat函式。
int shmget(key_t key, int size, int shm***)key:
1、0/ipc_private:當key的取值為ipc_private,則函式shmget()將建立一塊新的共享記憶體;如果key取值為0,而引數shm***中又設定ipc_private這個標誌,則同樣會建立一塊新的共享記憶體。
2、大於0的32位整數:視引數shm***來確定操作。
size:
1、大於0的整數:新建的共享記憶體大小,以位元組為單位0:
2、只獲取共享記憶體時指定為0
shm***:模式標誌引數,使用時需要與ipc物件訪問許可權(如0600)進行|運算來確定共享記憶體的訪問許可權
1、0:取共享記憶體識別符號,若不存在則函式會報錯
2、ipc_creat:當shm***&ipc_creat為真時,如果核心中不存在鍵值與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體,返回此共享記憶體的識別符號
3、ipc_creat|ipc_excl:如果核心中不存在鍵值 與key相等的共享記憶體,則新建乙個共享記憶體;如果存在這樣的共享記憶體則報錯
返回值:如果成功,返回共享記憶體識別符號;如果失敗,返回-1。
void* shmat(int shmid, char *shmaddr, int flag)引數:
第乙個引數,shm_id是由shmget函式返回的共享記憶體標識。
第二個引數,shm_addr指定共享記憶體連線到當前程序中的位址位置,通常為空,表示讓系統來選擇共享記憶體的位址。
第三個引數,shm_***是一組標誌位,通常為0。
返回值:
如果成功,則返回共享記憶體對映到程序中的位址;如果失敗,則返回-1。
當乙個程序不再需要共享記憶體時,需要把它從程序位址空間中脫離int shmdt(char *shmaddr);引數shmaddr是shmat函式返回的位址指標,呼叫成功時返回0,失敗時返回-1.
該函式用於將共享記憶體從當前程序中分離。注意,將共享記憶體分離並不是刪除它,只是使該共享記憶體對當前程序不再可用。
int shmctl(int shm_id, int command, struct shmid_ds *buf);**例子第乙個引數,shm_id是shmget函式返回的共享記憶體識別符號。
第二個引數,command是要採取的操作,它可以取下面的三個值 :
ipc_stat:把shmid_ds結構中的資料設定為共享記憶體的當前關聯值,即用共享記憶體的當前關聯值覆蓋shmid_ds的值。
ipc_set:如果程序有足夠的許可權,就把共享記憶體的當前關聯值設定為shmid_ds結構中給出的值
ipc_rmid:刪除共享記憶體段
第三個引數,buf是乙個結構指標,它指向共享記憶體模式和訪問許可權的結構。
shmid_ds結構至少包括以下成員:
struct shmid_ds
;
#include
#include
#include
#include
#include
typedef
struct _shm
shm;
int main()
//2.將共享記憶體對映到當前的程序中
shm *pshm = (shm*)shmat(shmid, null, 0);
if (pshm == -1)
strcpy (pshm->msg, "hello");
//解除共享記憶體對映,解除的是當前程序不再使用共享記憶體
shmdt(pshm);
shmctl(shmid, ipc_rmid, struct null);
return
0;}
程序間通訊1
管道由於傳遞資料只能單向傳遞,因此又稱半雙工管道,它是一種兩個程序間進行單向通訊的機制 侷限性 資料只能由乙個程序流向另乙個程序,若要進行全雙工通訊,則需建立兩個管道 管道只能用於具有親緣關係的程序間通訊 管道無名字 管道的緩衝區大小受限制 管道所傳遞的是無格式的位元組流,這就要求管道的輸入和輸出事...
程序間的通訊(1)
根據程序間通訊資訊量的不同,劃分為兩個類別 控制資訊的通訊 低階通訊 和大批量資料資訊的通訊 高階通訊 常見的通訊介面有 用於實現低階通訊的有軟中斷訊號 訊號量集,實現高階通訊的有管道 訊息佇列 共享記憶體等。軟中斷訊號 是作業系統用來通知程序有事件發生的一種訊號機制,用於實現簡單的非同步通訊的一些...
程序間通訊(1) 管道
linux下一切皆檔案,我們可以建立乙個管道檔案進行通訊,實際上是呼叫pipe函式在核心中開闢一塊緩衝區 稱為管道 用於通訊,管道是一種最基本的ipc機制,由pipe函式建立 include int pipe int filedes 2 它有乙個讀端乙個寫端,然後通過filedes引數傳出給使用者程...