看了看之後的內容,信號量和共享內存。這兩個都不太熟,算不上再次。
相對共享內存熟悉一點,從它開始吧。
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.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
...
};