進程間的通信(三)

看了看之後的內容,信號量和共享內存。這兩個都不太熟,算不上再次。

相對共享內存熟悉一點,從它開始吧。


void *mmap(void *addr, size_t len, int prot, int flag, int fd, off_t offset);
mmap函數將一個文件或者一個Posix共享內存區對象映射到調用進程的地址空間
addr指定被映射到的進程空間的起始地址(非強制狀態下由內核指定,這個值只是“建議”)。該函數返回地址通常爲映射到的內存區的起始地址


len是映射長度,offset爲距離文件開頭的偏移

prot參數:

PROT_READ 數據可讀

PROT_WRITE 可寫

PROT_EXEC 執行

PROT_NONE 不可訪問

flag參數:

MAP_SHARED 進程對被映射數據所作的修改對於共享該對象的所有進程可見

MAP_PRIVATE 進程對被映射數據所作的修改只對該進程可見

MAP_FIXED 強制採用addr參數的地址

MAP_ANON 匿名映射

MAP_SHARED和MAP_PRIVATE必須指定一個

父子進程之間共享內存的方法之一是在調用fork之前指定MAP_SHARED調用mmap,Posix.1保證父進程內存映射保存到子進程。


int munmap(void *addr, size_t len);
解除映射,再次訪問將導致一個錯誤信號。如果被映射區使用的是MAP_PRIVATE,則解除映射後進程對它所作的變動都會被丟棄


int msync(void *addr, size_t len, int flag);
內核的虛擬內存算法保持內存映射文件(一般在硬盤上)與內存映射區同步,前提是一個MAP_SHARED映射區。

msync函數可以用來確保同步

flag參數:

MS_ASYNC 執行異步寫

MS_SYNC 執行同步寫

MS_INVALIDATE 使高速緩存數據失效

MS_ASYNC和MS_SYNC二選一。當寫操作已由內核排入隊列,MS_ASYNC返回,MS_SYNC要等到寫操作完成後才返回。

MS_INVALIDATE 使所有與最終副本不一致的文件數據的所有內存中的副本失效。


BSD提供匿名映射避免文件的創建和打開。將flag設爲MAP_SHARED | MAP_ANON,將fd設爲-1,offset爲0

如下

mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);


Posix內存共享區

Posix.1提供了兩種在無親緣關係的進程間共享內存區的方法

內存映射文件:由open函數打開,進行映射

共享內存區對象:有shm_open打開一個Posix.1 IPC名字,返回的描述符進行映射

這兩種合稱爲內存區對象


int shm_open(const char *name, int oflag, mode_t mode);
int shm_unlink(const char *name);
oflag必須包含O_RDONLY(只讀)或者O_RDWR(讀寫)標誌,還可以指定如下標誌O_CREAT、O_EXCL或O_TRUNC

O_CREAT和O_EXCL與消息隊列當中相同,O_TRUNC如果隨O_RDWR指定則若對象已存在,那麼長度將被截短成0

mode參數指定權限位,內容與Posix消息隊列一致,必須指定,如果沒有指定O_CREAT可以指定爲0。

shm_unlink函數刪除一個對象的名字。


int ftruncate(int fd, off_t length);
ftruncate函數可以修改普通文件或共享內存區對象的大小


當打開一個已存在的共享內存區對象,可以調用fstat來獲取有關該對象的信息

int fstat(int fd, struct stat *buf);
stat結構有12個或以上成員,然而當fd指代一個共享內存對象時,只有四個成員含有信息

struct stat{
    ...
    mode_t    st_mode;//mode: S_I{RW}{USR, GRP, OTH}
    uid_t        st_uid;   //user ID
    gid_t        st_gid;   //group ID
    off_t        st_size;  //size in byte
    ...
};







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章