多程序通訊 IPC

2021-10-08 19:10:17 字數 4143 閱讀 8679

ipc:inter process communication

1、特點

2、主要api

1)建立管道

原型:int pipe(int pipefd[2]);

引數:pipefd  做輸出引數使用,存放是管道的讀,寫檔案描述符。pipefd[0]  存放讀,pipefd[1]存放寫

2)讀寫

把將管道當作檔案,使用read、write進行讀寫,檔案描述符即上面建立成功返回的引數

1、特點

2、主要api

1)建立fifo檔案

int mkfifo(const char *pathname, mode_t mode);

2)操作fifo檔案

對 fifo 型別的檔案的開啟/關閉跟普通檔案一樣,都是使用 open 和 close 函式。如果開啟時使用 o_wronly選項,則開啟 fifo 的寫入端,如果使用 o_rdonly 選項,則開啟 fifo 的讀取端

另外:1)可用命令mkfifo建立fifo檔案、用rm、unlink刪除fifo檔案

2)fifo檔案不能在windows共享目錄下存在。

1、特點

2、主要api

1)int msgget(key_t key, int msg***);

功能:建立/獲取訊息佇列,如果指定的 key 已經存在乙個訊息佇列,則是獲取,否則是建立。

引數:key 關鍵字,可以是 ipc_private(父子程序通訊)。非 ipc_private 值,可以使用 ftok 函式獲得或者直接寫乙個非0值。

2)int msgsnd(int msqid, struct msgbuf * msgp, size_t msgsz, int msg***);

3)ssize_t msgrcv(int msqid, struct msgbuf * msgp, size_t msgsz, long msgtyp, int msg***);

4)int msgctl(int msqid, int cmd, struct msqid_ds * buf);

共享記憶體也是程序間(程序間不需要有繼承關係)通訊的一種常用手段。

system v ipc 機制下的共享記憶體本質是一段特殊的記憶體區域,程序間需要共享的資料被放在該共享記憶體區域中,所有需要訪問該共享區域的程序都要把該共享區域對映到本程序的位址空間中去。

程序物件對於共享記憶體的訪問通過 key(鍵)來控制,同時通過 key 進行訪問許可權的檢查。

1、特點

1)共享記憶體是程序間通訊最快的方式。

2)共享記憶體沒有保護機制,需要訊號量控制。

3)共享記憶體的基本單位是頁,即大小最小是 4k,且是向上取整數頁的。

4)共享記憶體的生命週期是隨核心的:如果建立了共享記憶體,系統沒有死,它一直存在,除非你刪除它。 

2、主要api

1) 建立共享記憶體關鍵字

原型:key_t ftok( char * fname, int id );    

功能:ftok 用於建立乙個關鍵字,可以用該關鍵字關聯乙個共享記憶體段,後面建立共享記憶體時 shmget 需要使用到。

2)獲得/建立共享記憶體

原型:int shmget(key_t key, size_t size, int shm***)

返回:成功:返回共享記憶體的識別符號shmid,用於關聯

出錯:-1,錯誤原因存於 error 中。

3)關聯共享記憶體到程序

原型:void *shmat(int shmid, const void *shmaddr, int shm***);

返回:成功:返回乙個指向共享記憶體第乙個位元組的指標,後面就可直接對區域資料進行操作;

失敗:返回-1

4)分離

原型:int shmdt(const void *shmaddr);

5)刪除,查詢,配置共享記憶體

原型:int shmctl(int shmid, int cmd, struct shmid_ds *buf)

3、示例

//寫資料程式

key =ftok (「/etc/profile」,1);

int id = shmget(key, 4096, ipc_creat | 0666);

char*addr = shmat(id, null, 0);

memcpy(addr,」hello」,5);

shmdt(addr);

//讀資料程式

key =ftok (「/etc/profile」,1);

int id = shmget(key, 4096, ipc_creat | 0666);

char*addr = shmat(id, null, 0);

char buf

memcpy(buf,addr,5);

shmdt(addr);

shmctl(id,ipc_rmid,null)

沒有讀取資料前不要刪除共享記憶體。        

1、概念

訊號量用於實現對共享資源的保護。

訊號量是乙個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待(即 p(訊號變數))和傳送(即v(訊號變數))資訊操作。

最簡單的訊號量是只能取 0 和 1 的變數,這也是訊號量最常見的一種形式,叫做二進位制訊號量(二元燈)。而可以取多個正整數的訊號量被稱為通用訊號量(多元燈)。

2、主要api

1)建立訊號量

原型:int semget(key_t key, int nsems, int sem***);

功能:建立/獲得訊號集,當訊號量不存在時建立,存在時返回訊號集合id.

引數:key:關鍵字,可以是ipc_private  和非 ipc_private。規則和前面的共享記憶體,訊息佇列相同。

nsems:訊號集合中的訊號量數量

2)改變訊號量

原型: int semop(int semid, struct sembuf *sops, unsigned nsops)

功能:修改訊號集合中的訊號量值,實現 pv 操作,有可能阻塞。

引數: semid 訊號集合 id

控制訊號量資訊

原型: int semctl(int semid, int semnum, int cmd); 三個引數版本

int semctl(int semid, int semnum, int cmd, union semun arg);四個引數版本

引數:cmd 控制命令

常用命令:

ipc_rmid 刪除訊號集, 呼叫的是 3 個引數版本

getall 查詢集合中的所有的訊號量值,存放在 arg.array 陣列中,呼叫的是 4 個引數版本

getval 查詢集合中的第 semnum 個訊號量值, 通過 semctl 函式的返回值得到。

setall 設定集合中的每個訊號量, 訊號值存放在 arg.array 陣列中

setval 設定集合中的第 semnum 個訊號量值為 arg.val

1、概念

軟中斷訊號(signal,又簡稱為訊號)用來通知程序發生了非同步事件。在軟體層次上是對中斷機制的一種模擬,在原理上,乙個程序收到乙個訊號與處理器收到乙個中斷請求可以說是一樣的。訊號是程序間通訊機制中唯一的非同步通訊機制,

收到訊號的程序對各種訊號有不同的處理方法。處理方法可以分為三類:

2、主要api

1)訊號安裝

原型: sighandler_t signal(int signum, sighandler_t handler);

功能: 指定 signum 訊號對應的處理函式為 handler,當發生 signum 訊號時候會執行 handler 指向的函式。這個函式註冊乙個, handler 永久有效,除非你重新修改。

2)kill 訊號傳送系統呼叫

原型: int kill(pid_t pid, int sig);

功能: 傳送訊號給程序

3)raise 訊號傳送系統函式

原型: int raise(int sig);

功能: 給本程序傳送訊號

4)傳送訊號並附帶資訊

原型: int sigqueue(pid_t pid, int sig, const union si**al value);

功能:傳送訊號給指定的程序,並且可以給程序附加額外的資訊(value)

可用於網路中不同機器之間的程序間通訊,應用非常廣泛。

多程序通訊(IPC) 共享記憶體

1 共享記憶體介紹 共享記憶體可以說是最有用的程序間通訊方式,也是最快的ipc形式。兩個不同程序a b共享記憶體的意思是,同一塊物理記憶體被對映到程序a b各自的程序位址空間。程序a可以即時看到程序b對共享記憶體中資料的更新,反之亦然。由於多個程序共享同一塊記憶體區域,必然需要某種同步機制,互斥鎖和...

程序通訊 IPC

訊號 管道 訊息佇列 共享記憶體 定義 程序間的軟體中斷通知和處理機制 訊號的接收處理 捕獲 catch 忽略 ignore 遮蔽 mask 不足 傳遞的資訊量小,只有乙個訊號型別 程序間基於記憶體檔案的通訊機制 匿名管道只能在父子程序間進行通訊,不能再網路間進行通訊,而且資料傳輸是單向的,只能一端...

linux程序通訊(ipc)

1 管道 半雙工管道是最常用的ipc 只能在有關係的程序間才能使用,shell上常用 2 命名管道 在檔案系統中命名管道式以特殊檔案的形式存在的。不在同一程序組的兩個程序通訊可以使用命名管道。3 訊息佇列 核心空間中的內部鍊錶,通過linux核心在各個程序之間傳遞內容 4 訊號 用於在乙個或多個程序...