一、程序間通訊(ipc):unix / linux 系統基於多程序,程序和程序之間資料的互動。
1.常見的ipc:1)檔案 2)訊號 3)管道(fifo) 4)共享記憶體 5)訊息佇列 6)訊號量集 7)網路程式設計(socket)
2.共享記憶體、訊息佇列和訊號量集遵循相同的規範,統稱為 xsi ipc。
------------------------------------------
二、管道:一種僅做為互動媒介的ipc的特殊的檔案,不儲存任何的資料,檔名字尾.p,只有在有讀且有寫操作時才能暢通,否則阻塞。
1.管道有兩種用法:有名管道和無名管道。
1)有名管道:可用於所有程序之間的互動。無名管道:只能用於fork()建立的父子程序之間的互動。
2)有名管道:程式設計師建立管道檔案進行ipc。無名管道:系統建立和維護管道檔案進行ipc。
2.使用有名管道的步驟:
a.建立管道檔案:mkfifo命令|||mkfifo("...")函式 【touch 命令和 open()函式都無法建立管道檔案】。
b.像讀寫普通檔案一樣操作管道檔案。
c.可以刪除管道檔案。
注意:open 乙個管道檔案,許可權不要用 o_rdwr。
------------------------------------------
三、xsi ipc 的通用規範:每個 ipc 都由乙個內部的id做唯一的標識。內部id的獲取,需要借助與之對應外部key(型別 key_t)。
1. key 獲取的三種方式:
a 使用巨集 ipc_private 做 key,但外部無法獲取,基本不用。
b 使用ftok()獲取乙個 key。
c 在標頭檔案中為每個ipc統一分配唯一的 key。
2.通過key 獲取內部 id:msgget(2)、semget(2)、shmget(2)
//int msgget(key_t key, int msg***);
3.每種ipc 結構都提供了乙個 ***ctl()函式(查詢、修改和刪除)。
4.所有ipc 結構都是核心管理,不使用時需要手工刪除。
5.ipc 結構的相關命令:
ipcs - 查詢當前的 ipc 結構
ipcrm - 刪除當前的 ipc 結構 (用 id 刪除)
選項:-a 所有 ipc 結構
-m 共享記憶體 shared memory segments
-q 訊息佇列 semaphore arrays(更常用)
-s 訊號量集 message queues
------------------------------------------
四、共享記憶體:以一塊共享的物理記憶體做媒介。共享記憶體雖然速度最快(效率最高的ipc),但當多個程序同時寫資料時,資料會互相覆蓋,導致混亂。
1.共享的實現(通常情況下,兩個程序無法直接對映相同的記憶體。):
a)核心先拿出一塊物理記憶體,核心 負責管理。
b)允許所有程序對這塊記憶體進行對映。則兩個不同的程序,就可以對映到相同的物理記憶體上,從而實現資訊的互動。
2.程式設計步驟:
a)獲取 key。
b)使用 shmget()函式用key建立 / 獲取內部的 id。
c)使用 shmat()掛接共享記憶體(對映)- shm_nattch; /* no. of current attaches */可以像正常操作一樣使用共享記憶體。
d)使用 shmdt()脫接共享記憶體(解除對映)。
e)如果確定已經不再使用,可以使用shmctl()刪除共享記憶體。
3.相關函式:
1)獲取key:key_t ftok(const char *pathname, int proj_id);
/*ftok()函式使用給定的檔名(必須存在,可訪問的檔案)和proj_id的低8位(必須非零)來生成key_t型別system v ipc的key,適用於msgget(2), semget(2)或者shmget(2)。
*/
2)獲取(建立)內部id,並設定共享記憶體大小:int/*
id*/ shmget(key_t key, size_t size/*
共享記憶體的大小
*/, int shm***/*
flag獲取時:0;新建時:ipc_creat|0666(許可權)
*/);
3)掛載記憶體:void *shmat(int shmid, const void *shmaddr, int shm***);(和mmap相似)如:void *shmat(int shmid, 0, 0);/*if shmaddr is null, the system chooses a suitable (unused) address at which to attach the segment. */ /*return:on success shmat() returns the address of the attached shared memory segment; on error (void *) -1 is returned。*/
4)脫接記憶體:int shmdt(const void *shmaddr);//shmaddr 是shmat()的返回值,首位址(虛擬)。
5)查詢、修改和刪除共享記憶體:int shmctl(int shmid, int cmd, struct shmid_ds *buf /*
結構體指標
*/ );
cmd 引數:1)ipc_stat - 查詢 2)ipc_set - 修改 3)ipc_rmid - 按id 刪除ipc 結構
查詢時:會把共享記憶體的資訊放入第三個引數。
修改時:只有使用者id、組id和許可權可以修改,大小不可修改。
刪除時:第三個引數給 0 即可。刪除共享記憶體時,掛接數必須為 0 ,才能真正刪除,否則刪除只是做乙個標記,等掛接數為 0 時,才能真正刪除。
------------------------------------------
五、訊息佇列(fifo):存放訊息的佇列。
1.訊息佇列實現:資料先封入訊息中,然後再把訊息存入佇列。一般情況下,佇列有滿有空。可以解決多個程序同時寫資料的問題。
2.程式設計步驟:
a)得到外部的 key。
b)使用msgget()函式用key 建立 / 獲取乙個訊息佇列id。
c)把資料 / 訊息 存入佇列 或 從佇列中取出。//函式msgsnd()存入 / msgrcv()取出/* ipc_nowait 無等待,直接返回 */
d)如果不再使用訊息佇列,可以msgctl()刪除。
3.相關函式:
int msgsnd(int msqid/*
訊息佇列的id
*/, const void *msgp, size_t msgsz, int msg***);
a)msgp:訊息的首位址,其中訊息分為有型別訊息(更規範)和無型別訊息。
b)有型別訊息結構:
struct msg
c)size:是資料區域的大小,不包括 mtype的大小(有些時候也包括,規範情況下,不包括)。
d)flag:選項,可以是 0 代表阻塞(佇列滿了),也可以是ipc_nowait 代表非阻塞(佇列滿了直接返回錯誤)。
e)成功返回 0,失敗返回 -1。
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msg***);
a)msgtyp 可以讓接收者有選擇的接收訊息,值可能是:
0 - 接收任意型別的訊息(第乙個,先入先出)。
>0 - 接收型別為 mtype 的特定訊息。
<0 - 接收型別 小於等於 mtype 絕對值的訊息,從小到大接收。
b)成功返回接收到的資料大小,失敗返回 -1。
程序間通訊IPC
這兩天學習了 unix 的程序間通訊 ipc,這裡面有幾個很重要的基本概念,特別是訊息佇列和我的畢設很有關係,因此多說幾句。以前學習的程序間通訊方式,一般都是經由 fork 或exec 開啟檔案,或經過檔案系統。而 ipc是程序間通訊方式的統稱。下面一一道來。一 管道 管道是最老的 ipc形式。管道...
程序間通訊 IPC
part2 index1.html part2 index2.html linux至少支援如下ipc機制 同時支援posix和system v方式 streams ipc機制,linux本身不支援,有乙個單獨的安裝包 可以跨pc的程序通訊 互斥鎖或條件變數 動態初始化 不能使靜態分配 在共享記憶體中...
程序間通訊IPC
乙個大型的應用系統,往往需要眾多程序協作,程序間通訊的重要性顯而易見。首先,程序間通訊至少可以通過傳送開啟檔案來實現,不同的程序通過乙個或多個檔案來傳遞資訊,事實上,在很多應用系統裡,都使用了這種方法。但一般說來,程序間通訊 ipc interprocess communication 不包括這種似...