管道是進程間通訊中最古老的方式,全部UNIX都提供此種通訊機制。管道有如下兩種侷限性:服務器
FIFO沒有第二種侷限性。
儘管有這兩種侷限性,半雙工管道仍然是最經常使用的IPC形式。網絡
管道由pipe()函數建立:dom
#include <unistd.h> int pipe(int fd[2]); 返回值:若成功,返回0,若出錯,返回-1 參數fd返回兩個文件描述符:fd[0]爲讀而打開,fd[1]爲寫而打開。fd[1]的輸出是fd[0]的輸入。
一般,進程會先調用pipe,接着調用fork,從而建立從父進程到子進程的IPC通道,反之亦然。fork以後作什麼取決於咱們想要的數據流的方向。
對於從父進程到子進程的管道:父進程關閉管道的讀端(fd[0]),子進程關閉寫端(fd[1])。
對於從子進程到父進程的管道:父進程關閉管道的寫端(fd[1]),子進程關閉讀端(fd[0])。socket
FIFO有時被稱爲命名管道,經過FIFO,不相關的進程也能交換數據。
FIFO由mkfifo()函數建立:函數
#include <sys/stat.h> int mkfifo(const char *path, mode_t mode); 返回值:若成功,返回0,若出錯,返回-1
FIFO有以下兩種用途:測試
消息隊列是消息的連接表,存儲在內核中,由消息隊列標識符標識。
客戶進程和服務器進程之間的雙向數據流。操作系統
msgget用於建立一個新隊列或打開一個現有隊列,msgsnd將新消息添加到隊列尾端,每一個消息包含一個正的長整型類型的字段、一個非負的長度(nbytes)以及實際數據字節數(對應於長度),msgrcv用於從隊列中取消息。指針
#include <sys/msg.h> int msgget(key_t key, int flag); 返回值:若成功,返回消息隊列ID,若出錯,返回-1 int msgsnd(int msgid, const void *ptr, size_t nbytes, int flag); 返回值:若成功,返回0,若出錯,返回-1 ssize_t msgrcv(int msqid, void *ptr, size_t nbytes, long type, int flag); 返回值:若成功,返回消息數據部分的長度,若出錯,返回-1
本質上,信號量是一個計數器,用於爲多個進程提供對共享數據對象的訪問。
維護信號量狀態的是Linux內核操做系統而不是用戶進程。code
通常說來,爲了得到共享資源,進程須要執行下列操做:
共享存儲容許兩個或多個進程共享一個給定的存儲區。由於數據不須要在客戶進程和服務器進程之間複製,因此這是最快的一種IPC。
一般,信號量被用來實現對共享存儲數據存取的同步。(也能夠用記錄鎖或互斥量)
shmget得到一個共享存儲標識符,shmctl對共享存儲段執行多種操做,shmat將共享存儲段鏈接到它的地址空間。
#include<sys/shm.h> int shmget(key_t key, size_t size, int flag); 返回值:若成功,返回共享存儲ID;若出錯,返回-1 int shmctl(int shmid, int cmd, struct shmid_ds *buf); 返回值:若成功,返回0;若出錯,返回-1 void *shmat(int shmid, const void *addr, int flag); 返回值:若成功,返回指向共享存儲段的指針;若出錯,返回-1
不一樣計算機(經過網絡相連)上的進程相互通訊的機制:網絡進程間通訊(network IPC)。
套接字是通訊端點的抽象。正如使用文件描述符訪問文件,應用程序用套接字描述符訪問套接字。
socket建立一個套接字,shutdown禁止一個套接字的I/O。
#include <sys/socket.h> int socket(int domain, int type, int protocol); 返回值:若成功,返回文件(套接字)描述符,若出錯,返回-1 int shutdown(int sockfd, int how); 返回值:若成功,返回0,若出錯,返回-1