進程間通訊 IPC(Inter-Process Communication)

 

1、管道

管道是進程間通訊中最古老的方式,全部UNIX都提供此種通訊機制。管道有如下兩種侷限性:服務器

  1. 歷史上,他們是半雙工的(即數據只能在一個方向上流動)。
  2. 管道只能在具備公共祖先的兩個進程間使用。一般,一個管道由一個進程建立,在進程調用fork以後,這個管道就能在父進程和子進程之間使用了。

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

 

2、FIFO

FIFO有時被稱爲命名管道,經過FIFO,不相關的進程也能交換數據。
FIFO由mkfifo()函數建立:函數

#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);   返回值:若成功,返回0,若出錯,返回-1

FIFO有以下兩種用途:測試

  1. shell命令使用FIFO函數將數據從一條管道傳送到另外一條時,無需建立中間臨時文件。
  2. 客戶進程-服務器進程應用程序中,FIFO用做匯聚點,在客戶進程和服務器進程兩者之間傳遞數據。

 

3、消息隊列

消息隊列是消息的連接表,存儲在內核中,由消息隊列標識符標識。
客戶進程和服務器進程之間的雙向數據流。操作系統

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

 

4、信號量

本質上,信號量是一個計數器,用於爲多個進程提供對共享數據對象的訪問。
維護信號量狀態的是Linux內核操做系統而不是用戶進程。code

通常說來,爲了得到共享資源,進程須要執行下列操做:

  1. 測試控制該資源的信號量。
  2. 若此信號量的值爲正,則容許進行使用該資源。進程將信號量減1。
  3. 若此信號量爲0,則該資源目前不可用,進程進入睡眠狀態,直至信號量值大於0,進程被喚醒,轉入步驟(1)。
  4. 當進程再也不使用一個信號量控制的資源時,信號量值加1。若是此時有進程正在睡眠等待此信號量,則喚醒此進程。

 

5、共享存儲

共享存儲容許兩個或多個進程共享一個給定的存儲區。由於數據不須要在客戶進程和服務器進程之間複製,因此這是最快的一種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

 

6、網絡IPC:套接字

不一樣計算機(經過網絡相連)上的進程相互通訊的機制:網絡進程間通訊(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
相關文章
相關標籤/搜索