日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统【五】进程间通信-共享内存mmap

發布時間:2023/11/30 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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用來擴展文件大小
關閉映射區:

int munmap(void *addr, size_t length);

第一個參數必須是映射區的首地址,長度可以變化
成功返回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的話仍舊會修改磁盤文件

利用共享內存在父子進程之間通信

用于通信的時候我們創建一個臨時文件,成功創建映射區以后將文件關閉不再使用。

具體的方法是:

  • 創建一個文件
  • 使用ftruncate函數改變文件大小
  • 使用unlink函數刪除目錄項(創建臨時文件)
  • 建立映射區
  • 關閉文件
  • 在父子進程間通信時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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。