Linux系统【五】进程间通信-共享内存mmap
生活随笔
收集整理的這篇文章主要介紹了
Linux系统【五】进程间通信-共享内存mmap
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
mmap函數
#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);參數:
- void *addr建立映射區的首地址,由Linux內核指定,所以我們直接傳遞NULL。也就是說雖然這是一個參宿但是并不需要我們傳遞,當建立好映射區以后映射區的首地址將以返回值返回。
- size_t length建立映射區的大小,一般由創建映射區的文件的大小
- int prot用來表示映射區的權限(讀,寫,讀寫,執行,對于執行一般是操作系統調用)。PROT_READ PORT_WRITE PROT_READ | PROT_WRITE
- int flags標志位參數,可以通過設置標志位來決定對映射區的修改是否反應到磁盤上。
- MAP_SHEARD會將映射區所做的修改反映到物理設備上
- MAP_PRIVATE映射區所做的修改不會反映到物理設備
- int fd用來建立映射區的文件描述符
- off_t offset映射文件的偏移,用于截取文件的一部分建立映射區(4K的整數倍)
返回值:
成功返回創建映射區的首地址。失敗返回MAP_FAILED
ftruncate用來擴展文件大小
關閉映射區:
第一個參數必須是映射區的首地址,長度可以變化
成功返回0,失敗返回-1
例如:
#include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #include<fcntl.h> #include<sys/mman.h> #include<string.h>int main() {int fd = open("mmap1file",O_CREAT | O_RDWR | O_TRUNC ,0644);if(-1 == fd){perror("open error");exit(1);}if(-1 == ftruncate(fd, 128)) {perror("ftruncate error:");exit(1);}char *p = mmap(NULL, lseek(fd,0,SEEK_END), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if(MAP_FAILED == p){perror("mmap error:");exit(1);}strcpy(p,"Hello mmap!");close(fd); //關閉文件if(-1 == munmap(p,128)){perror("munmap error:");exit(1);}return 0; }注意事項
- 可以用malloc創建大小為0 的堆空間,并且可以free, 不可以創建大小為0 的映射區
- 如果文件是以只讀方式打開的就不能改變文件大小
- 如果文件是以只讀方式打開,那么不能將映射區設置為MAP_SHARED,但是可以將映射區設置為MAP_PRIVATE
- 如果文件以只寫方式打開,將無法建立映射區,錯誤信息為Permission denied,因為創建映射區的過程中其實有一次隱含的讀操作
- 創建映射區的權限要小于等與文件的權限
- 偏移量必須是頁(4K)的整數倍
- 因為mmap容易出錯,所以一定要保留mmap的返回值,并通過perror輸出錯誤信息
- 關閉映射區的時候munmap的第一個參數必須是映射區的首地址
- 建立映射區以后文件即使關閉也不影響,如果是MAP_SHARED的話仍舊會修改磁盤文件
利用共享內存在父子進程之間通信
用于通信的時候我們創建一個臨時文件,成功創建映射區以后將文件關閉不再使用。
具體的方法是:
在父子進程間通信時MAP_SHARED指的是共享同一個映射區,MAP_PRIVATE指的是不共享映射區,父子進程分別占用
匿名映射
因為正常mmap函數必須依賴一個文件,雖然這個文件沒有存在的必要,因此我們需要open、ftruncate、unlink、close比較麻煩。因此我們可以使用匿名映射較為方便地創建映射區。
int *p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);len可以根據我們的需要修改大小。
MAP_ANONYMOUS表示匿名通信,可以簡寫為MAP_ANON
需要注意的是MAP_ANONYMOUS只能夠在Linux系統中使用,在其他類Unix系統中不可以使用,在其他系統中使用字符設備文件/dev/zero
int fd = open("/dev/zero", O_RDWR); p = (int*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);mmap無血緣關系進程通信
同一個文件創建的是一個映射區,因此如果我們想要在沒有血緣關系,就需要通過同一個文件來建立映射區
strace 可執行文件追蹤程序里面所使用的系統調用有哪些
其實Linux系統對文件的操作是通過mmap進行的
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Linux系统【五】进程间通信-共享内存mmap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 睾丸功能异常会引起男性不育吗
- 下一篇: Linux多进程拷贝文件