Linux系統程式設計—共享記憶體之mmap
共享記憶體概念
共享記憶體是通訊效率最高的IPC方式,因為程序可以直接讀寫記憶體,而無需進行資料的拷備。但是它沒有自帶同步機制,需要配合訊號量等方式來進行同步。
共享記憶體被建立以後,同一塊實體記憶體被對映到了多個程序地址空間,當有一個程序修改了共享記憶體的資料,其餘的程序均可看見所修改的內容,反之亦然。
mmap函式
函式原型:
void *mmap(void *adrr, size_t length, int prot, int flags, int fd, off_t offset);
返回值:
成功:返回建立的對映區首地址;
失敗:返回MAP_FAILED
具體引數含義:
addr: 指向對映區的首地址,這是由系統核心所決定的,一般設為NULL;
length: 欲建立的對映區大小;
prot: 對映區的許可權,一般有如下幾種:
PROT_EXEC 對映區域可被執行
PROT_READ 對映區域可被讀取
PROT_WRITE 對映區域可被寫入
PROT_NONE 對映區域不能存取
flags: 指對映區的標誌位,MAP_FIXED與MAP_PRIVATE必須選擇一個:
MAP_FIXED: 對對映區所作的修改會反映到物理裝置,但需要呼叫msync()或者munmap();
MAP_PRIVATE: 對對映區所作的修改不會反映到物理裝置。
fd: 建立的對映區的檔案描述符;
offset: 被對映檔案的偏移量,一般設為0,表示從頭開始對映。
mumap函式
函式原型:
int munmap(void *addr, size_t length);
函式作用:
如同malloc之後需要free一樣,mmap呼叫建立的對映區使用完畢之後,需要呼叫munmap去釋放。
例程
寫程序:
1#include <stdio.h> 2#include <sys/mman.h> 3#include <sys/types.h> 4#include <sys/stat.h> 5#include <fcntl.h> 6#include <unistd.h> 7#include <string.h> 8 9typedef struct 10{ 11int id; 12char name[20]; 13char gender; 14}stu; 15 16int main(int argc, char *argv[]) 17{ 18stu *p = NULL; 19int fd = 0; 20stu student = {10, "harry", 'm'}; 21 22if (argc < 2) { 23printf("useage: ./a.out file\n"); 24return -1; 25} 26 27fd = open(argv[1], O_RDWR | O_CREAT, 0664); 28if (fd == -1) { 29printf("ERROR: open failed!\n"); 30return -1; 31} 32ftruncate(fd, sizeof(stu)); 33 34p = mmap(NULL, sizeof(stu), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 35if (p == MAP_FAILED) { 36printf("ERROR: mmap failed!\n"); 37return -1; 38} 39 40close(fd); 41 42while (1) { 43memcpy(p, &student, sizeof(stu)); 44student.id++; 45sleep(2); 46} 47munmap(p, sizeof(stu)); 48 49return 0; 50} 複製程式碼
讀程序:
1#include <stdio.h> 2#include <sys/mman.h> 3#include <sys/types.h> 4#include <sys/stat.h> 5#include <fcntl.h> 6#include <unistd.h> 7 8typedef struct 9{ 10int id; 11char name[20]; 12char gender; 13}stu; 14 15int main(int argc, char *argv[]) 16{ 17stu *p = NULL; 18int fd = 0; 19 20if (argc < 2) { 21printf("useage: ./a.out file\n"); 22return -1; 23} 24 25fd = open(argv[1], O_RDONLY); 26if (fd == -1) { 27printf("ERROR: open failed!\n"); 28return -1; 29} 30 31p = mmap(NULL, sizeof(stu), PROT_READ, MAP_SHARED, fd, 0); 32if (p == MAP_FAILED) { 33printf("ERROR: mmap failed!\n"); 34return -1; 35} 36 37close(fd); 38 39while (1) { 40printf("id = %d, name = %s, gender = %c\n", p->id, p->name, p->gender); 41sleep(2); 42} 43 44munmap(p, sizeof(stu)); 45 46return 0; 47} 複製程式碼
更多精彩內容,請關注公眾號 良許Linux ,公眾內回覆 1024 可免費獲得5T技術資料,包括: Linux,C/C++,Python,樹莓派,嵌入式,Java,人工智慧 ,等等。公眾號內回覆 進群 ,邀請您進高手如雲技術交流群。
Line"/>