程序間通訊的方式 二 共享對映區

2021-07-26 05:32:09 字數 3178 閱讀 1548

共享對映區

(一).通訊方式:

程序間通訊又稱ipc(inter process communication),它可以通過檔案 管道 有名管道 共享記憶體 訊息佇列 訊號量 套接字這幾個方式進行通訊,但是檔案這種以及訊息佇列基本已被淘汰。

所以常用的通訊方式有:

1.管道

2.訊號

3.共享對映區

4.本地套接字

(二).共享對映區基本概念:

通過mmap系統呼叫,把普通檔案對映到儲存空間的乙個緩衝區中,使得兩個或多個程序之間可以共享這一塊區域,就達到了程序間通訊的目的。這種通訊方式比通過檔案進行通訊更快,因為是直接操作緩衝區,而不是通過read以及write等函式進行操作。

這種方式可以用於父子間程序通訊,也可以用於無血緣關係的程序之間通訊。

當我們使用mmap建立了共享對映區之後,進行的操作就好比我們操作字元陣列一樣。

(三).使用共享對映區進行通訊:

函式原型:void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);

所需標頭檔案:#include

引數含義:

1.第乙個引數代表建立共享對映區在記憶體中的起始位址,由系統自動分配即可,所以傳入null就行了;

2.第二個引數代表建立的對映區的大小;

3.第三個引數代表對映區的訪問許可權,由幾個巨集確定,常用的有:prot_read(可讀),prot_write(可寫),prot_read | prot_write(可讀可寫);

4.第四個引數代表標誌位,常用的有:map_shared、map_private、map_anon,map_shared的意思是對這塊對映區內容的修改會影響到被對映的檔案 或者 多個程序間獨享該對映區,map_private的意思是對這塊對映區內容的修改不會影響到被對映的檔案 或者 多個程序間共享該對映區,map_anon用於匿名對映;

5.第五個引數代表要對映的檔案的檔案描述符;

6.最後乙個引數代表操作這塊對映區的起始偏移量,和對陣列的操作類似,不過必須是4k的整數倍。

返回值:

該函式成功呼叫會返回建立對映區的首位址,如果失敗會返回乙個巨集:map_failed

由於mmap函式其實涉及到記憶體的分配,有了分配,自然要有釋放。

釋放的函式原型:int munmap(void *addr, size_t length)

標頭檔案:#include

引數含義:

1.第乙個引數代表共享對映區的起始位址

2.第二個引數代表分配的大小

返回值:

成功返回0,失敗返回-1

例子1:

#include #include #include #include #include #include int main()

len = ftruncate(fd, 4); //擴充套件檔案大小

if(len == -1)

p = mmap(null, 4, prot_read | prot_write, map_shared, fd, 0); //以讀寫的方式建立對映區

if(p == map_failed)

strcpy(p, "abc"); //將字串abc賦給這塊對映區

ret = munmap(p, 4); //釋放

if(ret == -1)

close(fd);

return 0;

}

這個例子雖然簡單,但是其實有幾個需要注意的地方。

1.當我們開啟乙個檔案的時候,操作該檔案的許可權是不能小於通過該檔案建立對映區的許可權的,即如果檔案是唯讀的,那麼對映區這邊也不能進行寫操作。

2.建立對映區時,包含著一次對對映檔案的讀操作,因為要把內容都對映到緩衝區中。所以檔案的讀許可權應該要有才行。

3.偏移量必須是4k的整數倍。

4.munmap的第乙個引數必須是對映區的首位址。

例子2:

#include #include #include #include #include #include int main()

pid = fork();

if(pid == 0)

else

}

return 0;

}

注意事項:

map_anon引數只適合在linux系統中使用。

例子3:

/****************讀資料******************/

#include #include #include #include #include #include #include struct stu

;int main(int argc, char *argv) //argv[1]用於傳遞要對映的檔名

close(fd);

while(1) //讀出對映區的資料

munmap(mm, sizeof(student));

return 0;

}/***************寫端***************/

#include #include #include #include #include #include #include #include struct stu

;int main(int argc, char *argv)

; char *mm;

fd = open(argv[1], o_rdwr | o_creat, 0664);

ftruncate(fd, sizeof(student));

mm = mmap(null, sizeof(student), prot_read | prot_write, map_shared, fd, 0);

if(mm == map_failed)

close(fd);

while(1) //寫資料

munmap(mm, sizeof(student));

return 0;

}

注意兩個程序之間開啟對映區的標誌位必須是map_shared,而不是map_private,否則資料無法共享。兩個或多個無血緣關係的程序只要通過共享一塊對映區,就可以達到通訊的目的了。

程序間通訊方式 共享記憶體

所有的函式共用標頭檔案 include include include 3.1建立共享記憶體 shmget 函式 int shmget key t key,size t size,int shm 成功返回共享記憶體的id,出錯返回 1 1 第乙個引數key是長整型 唯一非零 系統建立ipc通訊 訊息...

程序間的通訊方式,執行緒間的通訊方式 程序

當時做筆記的時候 忘了在 看到的了,有時間我再研究研究 管道 pipe 管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。有名管道 namedpipe 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。訊號量 semo...

程序間通訊方式之(四)共享記憶體

物件 共享記憶體 share memory 訊息佇列 message quene 訊號燈 semaphore 共享記憶體 特點 1 是一種最為高效的程序間的通訊的方式,程序可以直接讀寫,而不需要任何資料的拷貝 2 為了在程序間交換訊息,核心專門留出了一塊記憶體區,可以由需要訪問的程序將其對映 到自己...