共享對映區
(一).通訊方式:
程序間通訊又稱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 為了在程序間交換訊息,核心專門留出了一塊記憶體區,可以由需要訪問的程序將其對映 到自己...