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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux进程间通信六 Posix 共享内存简介与示例

發布時間:2025/4/5 linux 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux进程间通信六 Posix 共享内存简介与示例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 共享內存簡介

共享內存主要用于不同進程之間相互通信,因為操作的是同一塊地址,不需要內核和用戶層之間數據拷貝,屬于最快的進程間通信方式,不過,為了防止讀寫沖突,一般需要額外的同步手段。之前介紹了SystemV共享內存的使用方式,今天介紹下Posix共享內存。Posix 共享內存API主要有這幾個,shm_open,用于獲取或者創建一個共享內存文件描述符,ftruncate,用于設置共享內存的大小,新建的共享內存大小為0,mmap,用于將共享內存文件映射到進程的虛擬地址空間,其實共享內存真正核心的工作主要在于mmap,不過mmap是另外一個話題,暫時不討論。munmap,和mmap作用相反。shm_unlink,移除共享內存。close關閉shm_open獲取的文件描述符,通常mmap之后就可以關閉了。fstat獲取共享內存的信息,比如大小。下面介紹下相關API接口

2. API接口

2.1 創建共享內存

#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants *//** * @brief 創建或獲取已存在的共享內存 * * @params name 共享內存名字,以斜杠開頭'/',不超過NAME_MAX(255)字符 * @params oflag O_RDONLY| O_RDWR| O_CREAT| O_EXCL| O_TRUNC * @params mode 設置一些權限,通常使用0即可 * * @returns 成功返回文件描述符,失敗返回-1 **/int shm_open(const char *name, int oflag, mode_t mode);

2.2 設置共享內存大小

#include <unistd.h> #include <sys/types.h>/** * @brief 修改fd的大小 * * @returns 成功返回0,失敗返回-1 **/int ftruncate(int fd, off_t length);

2.3 查詢共享內存文件大小

#include <unistd.h> #include <sys/types.h>/** * @brief 查詢fd的信息 * @param fd 要查詢的文件描述符 * @param buf 用于保存查詢結果的buffer * @returns 成功返回0,失敗返回-1 **/struct stat {dev_t st_dev; /* ID of device containing file */ino_t st_ino; /* inode number */mode_t st_mode; /* protection */nlink_t st_nlink; /* number of hard links */uid_t st_uid; /* user ID of owner */gid_t st_gid; /* group ID of owner */dev_t st_rdev; /* device ID (if special file) */off_t st_size; /* total size, in bytes */blksize_t st_blksize; /* blocksize for file system I/O */blkcnt_t st_blocks; /* number of 512B blocks allocated */time_t st_atime; /* time of last access */time_t st_mtime; /* time of last modification */time_t st_ctime; /* time of last status change */ };int fstat(int fd, struct stat *buf);

2.4?映射共享內存

#include <sys/mman.h>/** * @brief 映射共享內存到進程自身虛擬地址空間 * * @params addr 映射到的地址,通常設置為NULL,表示內核自己選擇合適地址。 * @params length 映射的共享內存大小 * @params prot 保護標志位,可選PROT_EXEC| PROT_READ| PROT_WRITE| PROT_NONE * @params flags 可選 * MAP_SHARED,共享模式,修改對其它進程可見 * MAP_PRIVATE 私有映射,對共享內存的修改對其它進程不可見。 * @params fd 被映射的共享內存文件描述符 * @params offset 文件偏移值,通常填0 * @returns 成功返回共享內存地址,失敗返回-1 **/void *mmap(void *addr, size_t length,int prot, int flags ,int fd, off_t offset);/** * @brief 刪除mmap的映射 * * @params addr 映射到的地址 * @params length 映射的共享內存大小 * @returns 成功返回0址,失敗返回-1 **/int munmap(void *addr, size_t length);

2.5 刪除共享內存

#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants *//** * @brief 刪除共享內存,只有當所有進程都取消映射后才銷毀它 * * @params name 共享內存名字 * * @returns 成功返回0,失敗返回-1 **/int shm_unlink(const char *name);# 編譯加上 -lrt選項 Link with -lrt.

3. 共享內存示例

這里僅簡單讀寫,沒有考慮同步。

3.1 寫共享內存

#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ #include <error.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <string.h>#define SHM_NAME "/shm0" #define SHM_SIZE 4096int main(int argc, char** argv) {if (argc < 2){printf("Usage: ./shm_write msg\n");return -1;}// 創建或打開已存在的共享內存int shm_fd = shm_open(SHM_NAME, O_RDWR|O_CREAT, 0);if (shm_fd == -1){perror("shm_open error");return -1;}// 設置共享內存大小if (ftruncate(shm_fd, SHM_SIZE)){perror("ftruncate error");return -1;}// 映射共享內存char* buffer = (char *)mmap(NULL, SHM_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);if (buffer == (char *)MAP_FAILED){perror("mmap error");return -1;}// 關閉共享內存文件描述符,并不影響映射close(shm_fd);// 寫共享內存strncpy(buffer, argv[1], strlen(argv[1]));// 刪除共享內存//shm_unlink(shm_fd);return 0; }

3.2 讀共享內存

#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ #include <error.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>#define SHM_NAME "/shm0" #define SHM_SIZE 4096int main() {// 創建或打開共享內存int shm_fd = shm_open(SHM_NAME, O_RDWR|O_CREAT, 0);if (shm_fd == -1){perror("shm_open error");return -1;}// 獲取共享內存大小,讀取的時候要用struct stat stat={0};if (fstat(shm_fd, &stat)){perror("fstat error");return -1;}// 映射共享內存,大小為上一步獲取的大小char* buffer = (char*)mmap(NULL, stat.st_size, PROT_READ, MAP_SHARED, shm_fd, 0);if (buffer == (char *)MAP_FAILED){perror("mmap error");return -1;}// 關閉文件描述符close(shm_fd);// 讀取共享內存printf("Read Msg:%s\n", buffer);// 刪除共享內存shm_unlink(SHM_NAME);return 0; }

3.3 編譯&運行

default:gcc -o shm_read shm_read.c -lrtgcc -o shm_write shm_write.c -lrt clean:rm -rf shm_write shm_read

4. 參考文檔

https://www.man7.org/linux/man-pages/man7/mq_overview.7.html

================================================================================================

Linux應用程序、內核、驅動、后臺開發交流討論群(745510310),感興趣的同學可以加群討論、交流、資料查找等,前進的道路上,你不是一個人奧^_^。...
?

?

總結

以上是生活随笔為你收集整理的Linux进程间通信六 Posix 共享内存简介与示例的全部內容,希望文章能夠幫你解決所遇到的問題。

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