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

歡迎訪問 生活随笔!

生活随笔

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

linux

Linux IPC实践(10) --Posix共享内存

發布時間:2025/3/17 linux 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux IPC实践(10) --Posix共享内存 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.?創建/獲取一個共享內存

#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ int shm_open(const char *name, int oflag, mode_t mode);

參數:

? ?name:? 共享內存名字;

? ?oflag: 與open函數類型,?可以是O_RDONLY,?O_WRONLY,?O_RDWR,?還可以按位或上O_CREAT,?O_EXCL,?O_TRUNC.

? ?mode: 此參數總是需要設置,?如果oflag沒有指定O_CREAT,?則mode可以設置為0;

返回值:

? ?成功:?返回一個文件描述符;

? ?失敗:?返回-1;

注意-Posix?IPC名字限制:

? ?1.?必須以”/”開頭,?并且后面不能還有”/”,?形如:/file-name;

? ?2.?名字長度不能超過NAME_MAX

? ?3.?鏈接時:Link?with?-lrt.

/** 示例: 共享內存的打開與關閉 **/ int main(int argc,char *argv[]) {int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");cout << "share memory open success" << endl;close(shmid); }

2.?修改共享內存大小

int ftruncate(int fd, off_t length);

該函數不僅可用于修改共享內存大小,?而且可以用于修改文件大小

/** 示例: 修改共享內存大小 將其修改為一個Student結構體的大小 **/ struct Student {char name[32];int age; }; int main(int argc,char *argv[]) {int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");if (ftruncate(shmid, sizeof(Student)) == -1)err_exit("ftruncate error");cout << "share memory change size success" << endl;close(shmid); }

3.?獲取共享內存狀態

int fstat(int fd, struct stat *buf);

該函數不僅可用于獲取共享內存狀態,?而且可以用于獲取文件狀態,?與前面曾經講述過的stat,?lstat類型;

//stat結構體 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 filesystem 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 */ }; /** 示例: 獲取共享內存的mode和size **/ int main(int argc,char *argv[]) {int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666);if (shmid == -1)err_exit("shmget error");if (ftruncate(shmid, sizeof(Student)) == -1)err_exit("ftruncate error");struct stat buf;if (fstat(shmid, &buf) == -1)err_exit("lstat error");// 注意: 獲取權限時, 需要&上0777, 而且要以%o, 八進制方式打印printf("mode: %o\n", buf.st_mode&0777);printf("size: %ld\n", buf.st_size);close(shmid); }

4.?刪除一個共享內存對象

int shm_unlink(const char *name); //示例: int main(int argc,char *argv[]) {shm_unlink("/xyz"); }

5.?共享內存的映射/卸載

#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length);

參數:

? ?addr:? 要映射的起始地址,?通常指定為NULL,?讓內核自動選擇;

? ?length: 映射到進程地址空間的字節數,?通常是先前已經創建的共享內存的大小;

? ?prot: 映射區保護方式(見下);

? ?flags: 標志(通常指定為MAP_SHARED,?用于進程間通信);

? ?fd: 文件描述符(填為shm_open返回的共享內存ID);

? ?offset: 從文件頭開始的偏移量(一般填為0);

?

prot

說明

PROT_READ

頁面可讀

PROT_WRITE

頁面可寫

PROC_EXEC

頁面可執行

PROC_NONE

頁面不可訪問

?

flags

說明

MAP_SHARED

變動是共享的

MAP_PRIVATE

變動是私有的

MAP_FIXED

準確解釋addr參數,?如果不指定該參數,?則會以4K大小的內存進行對齊

MAP_ANONYMOUS

建立匿名映射區,?不涉及文件

?

mmap返回值:

? ?成功:?返回映射到的內存區的起始地址;

? ?失敗:?返回MAP_FAILED;

注意:mmap失敗返回EACCES錯誤的原因:

? ?EACCES?A?file?descriptor?refers?to?a?non-regular?file.??

Or?MAP_PRIVATE?was?requested,?but?fd??is??not??open?for?reading.??

Or?MAP_SHARED?was?requested?and?PROT_WRITE?is?set,?but?fd?is?not?open?

in?read/write?(O_RDWR)?mode.??Or?PROT_WRITE??is??set,??but??the?file?is?append-only.

/** 示例: 向共享內存寫入數據 **/ int main(int argc,char *argv[]) {int shmid = shm_open("/xyz", O_RDWR, 0);if (shmid == -1)err_exit("shm_open error");struct stat buf;if (fstat(shmid, &buf) == -1)err_exit("fstat error");Student *p = (Student *)mmap(NULL, buf.st_size,PROT_WRITE, MAP_SHARED, shmid, 0);if (p == MAP_FAILED)err_exit("mmap error");strcpy(p->name, "Hadoop");p->age = 5;munmap(p, buf.st_size);close(shmid); } /** 從共享內存讀出數據 **/ int main(int argc,char *argv[]) {int shmid = shm_open("/xyz", O_RDONLY, 0);if (shmid == -1)err_exit("shm_open error");struct stat buf;if (fstat(shmid, &buf) == -1)err_exit("fstat error");Student *p = (Student *)mmap(NULL, buf.st_size,PROT_READ, MAP_SHARED, shmid, 0);if (p == MAP_FAILED)err_exit("mmap error");cout << "name: " << p->name << ", age: " << p->age << endl;munmap(p, buf.st_size);close(shmid); }

[附]

? ?-Posix共享內存默認創建在/dev/shm目錄下

? ?-可以使用od命令查看共享內存的內容

od?-c?/dev/shm/xyz

總結

以上是生活随笔為你收集整理的Linux IPC实践(10) --Posix共享内存的全部內容,希望文章能夠幫你解決所遇到的問題。

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