進程間通訊(IPC,InterProcess Communication)是指在不一樣進程之間傳播或交換信息。進程間通訊的方式有以下幾種:html
特色:node
管道只容許具備血緣關係的進程間通訊,如父子進程間的通訊。ios
管道並不是是進程全部的資源,而是和套接字同樣,歸操做系統全部。能夠將它當作文件系統,但該文件系統只存在於內存當中。c++
原型數組
#include <unistd.h> /* Create a one-way communication channel (pipe). If successful, two file descriptors are stored in PIPEDES; bytes written on PIPEDES[1] can be read from PIPEDES[0]. Returns 0 if successful, -1 if not. */ extern int pipe (int fd[2]) __THROW __wur;
參數的說明:函數
字符數組fd是管道傳輸或者接收時用到的文件描述符,其中fd[0]
是接收的時候使用的文件描述符,即管道出口;而fd[1]
是傳輸的時候用到的文件描述符,即管道入口。測試
爲了使數據能夠雙向傳遞,可使用兩個管道,一個管道負責進程1的寫和進程2的讀,另外一個管道負責一個進程1的讀和進程2的寫。測試程序以下:spa
#include <iostream> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> #define BUF_SIZE 30 int main(){ int fds1[2], fds2[2]; /* *注意: * 此處不能寫char* str1 = "Who are you?"; * 獲得的sizeof(str1)等於8,該值其實是指針的大小,並非字符串數組的大小 * 這個時候要用strlen()函數(strlen的惟一標準是找‘\0’) * 系統函數返回值是char *(#include <string.h>)類型的每每會在末尾加上'\0'。 * 要注意的是未初始化的狀況下,用strlen是不可行的 **/ char str1[] = "Who are you?"; char str2[] = "Thank you for your message."; char buf[BUF_SIZE]; pipe(fds1); //建立兩個管道 pipe(fds2); pid_t pid = fork(); if(pid == 0){ write(fds1[1], str1, sizeof(str1)); read(fds2[0], buf, BUF_SIZE); printf("Child process copy the message: %s\n", buf); }else { read(fds1[0], buf, BUF_SIZE); printf("Parent Process copy the message: %s\n", buf); write(fds2[1], str2, sizeof(str2)); } return 0; }
2.FIFO操作系統
FIFO即命名管道,在磁盤上有對應的節點,但沒有數據塊—換言之,只是擁有一個名字和相應的訪問權限,經過mknode()
系統調用或者mkfifo()
函數來創建的。一旦創建,任何進程均可以經過文件名將其打開和進行讀寫,而不侷限於父子進程,固然前提是進程對FIFO有適當的訪問權。當再也不被進程使用時,FIFO在內存中釋放,但磁盤節點仍然存在。線程
/* Create a new FIFO named PATH, with permission bits MODE. */ extern int mkfifo (const char *__path, __mode_t __mode) __THROW __nonnull ((1));
其中的 mode 參數與open
函數中的 mode 相同。一旦建立了一個 FIFO,就能夠用通常的文件I/O函數操做它。
當 open 一個FIFO時,是否設置非阻塞標誌(O_NONBLOCK
)的區別:
O_NONBLOCK
(默認),以只讀方式打開的FIFO要阻塞到其餘的某個程序以寫打開這個FIFO。一樣以只寫方式打開的FIFO要阻塞到其餘某個進程以讀方式打開該FIFO。O_NONBLOCK
,則以只讀方式打開會馬上返回而不阻塞(不是出錯返回)。而以只寫方式打開,若以前沒有進程以讀方式打開這個FIFO則馬上出錯返回。示例代碼:一個進程發送消息給另外一個進程
writefifo.cpp
#include <iostream> #include <stdio.h> #include <errno.h> #include <stdlib.h> #include <sys/stat.h> #include <fcntl.h> // O_WRONLY #include <time.h> //time #include <unistd.h> using namespace std; int main(){ int fd; int n; char buf[1024]; time_t tp; if( mkfifo("fifo1", 0666) < 0 && errno != EEXIST) //建立FIFO管道 { perror("Create FIFO Faileed"); } printf("I am %d process.\n", getpt()); //說明進程的ID if((fd = open("fifo1",O_WRONLY )) < 0){ //以只寫方式打開FIFO perror("Open FIFO failed"); exit(1); } for (int i = 0; i < 10; ++i) { time(&tp); //獲取當前系統時間 n = sprintf(buf, "Process %d's time is %s",getpid(), ctime(&tp)); printf("send message: %s", buf); if(write(fd, buf, n+1) < 0) { perror("write FIFO Failed"); close(fd); exit(1); } sleep(1); } close(fd); return 0; }
readfifo.cpp
#include <stdio.h> #include <iostream> #include <stdlib.h> #include <errno.h> #include <sys/stat.h> #include <fcntl.h> // O_WRONLY #include <time.h> //time #include <unistd.h> using namespace std; int main(){ int fd; int len; char buf[1024]; if((fd = open("fifo1", O_RDONLY)) < 0){ //以只讀方式打開FIFO perror("Open FIFO failed"); exit(1); } while ((len = read(fd, buf ,1024)) > 0) //讀取FIFO管道 { printf("Read message: %s", buf); } close(fd); return 0; }
若是在writefifo.cpp
中修改以下,設置非阻塞標誌:
if((fd = open("fifo1",O_WRONLY | O_NONBLOCK)) < 0){ //以只寫方式打開FIFO
若是先運行writefifo,在運行readfifo,則會出錯。
3. 消息隊列
消息隊列,就是一個消息的鏈表,是一系列保存在內核的列表。用戶進程能夠向消息隊列添加消息,也能夠向消息隊列讀取消息。
特色:
4.共享內存
共享內存(Shared Memory),指兩個或多個進程共享一個給定的存儲區。
5. 信號量
信號量是一個計數器,能夠用來控制多個進程對共享資源的訪問。它常做爲一種鎖機制,防止某進程正在訪問共享資源時,其餘進程也訪問該資源。所以,主要做爲進程間以及同一進程內不一樣線程之間的同步手段。
6.套接字
套解口也是一種進程間通訊機制,與其餘通訊機制不一樣的是,它可用於不一樣及其間的進程通訊。