進程間通信
有血緣關系的
父子進程共享內存映射區
沒有血緣關系的進程間通信
如何通信?
Mmap 實現內存映射:
必須有一個文件
文件數據什么時候有用:
單純文件映射
進程間通信:
文件數據是沒有用的
Mmap - 創建內存映射
作用:將磁盤文件的數據映射到內存,用戶通過修改內存就能修改磁盤文件
函數原型:
void *mmap(
void *addr, //映射區首地址,傳NULL
size_t length, //映射區的大小
100byte - 4k
不能為0
一般文件多大,length就指定多大

int prot, //映射區的權限
PROT_READ -- 映射區必須要有讀權限
PROT_WRITE
PROT_READ | PROT_WRITE
int flags,//標志位參數
MAP_SHARED
修改了內存數據會同步到磁盤
MAP_PRIVATE
修改了內存數據不會同步到磁盤
int fd, //文件描述符
干嘛的文件描述符?
要映射的文件對應fd
要么得到?
Open()
off_t offset//映射文件的偏移量
映射的時候文件指針的偏移量
必須是4k的整數倍
0
);
返回值:
映射區的首地址 - 調用成功
調用失敗:MAP_FAILED
Munmap - 釋放內存映射區
函數原型:
int munmap(void *addr, size_t length);
Addr -- mmap 的返回值,映射區的首地址
Length -- mmap的第二個參數,映射區的長度
思考問題:
如果對mmap的返回值(ptr) 做++操作(ptr++),munmap是否能夠成功?
不能
Char *pt = ptr;
如果open是O_RDONLY,mmap時port參數指定PROT_READ | PROT_WRITE會怎樣?
mmap調用失敗
open文件指定的權限應該大于等于mmap第三個參數prot指定的權限
如果文件偏移量為1000會怎樣?
必須是4096的整數倍
如果不檢測mmap的返回值會怎樣?
Mmap 什么情況下會調用失敗?
第二個參數length = 0
第三個參數必須指定PROT_READ
Fd 對應的打開權限必須大于等于prot權限
偏移量:必須是4096的整數倍
可以open的時候O_CREAT一個新文件來創建映射區嗎?
可以,需要做文件拓展
Lseek
Truncate(fd, length)
mmap后關閉文件描述符,對mmap映射有沒有影響?
沒有影響
對ptr越界操作會怎樣?
段錯誤
進程間通信
有血緣關系的
父子進程共享內存映射區
沒有血緣關系的進程間通信
如何通信?
不能使用匿名映射的方式
只能借助磁盤文件創建映射區 -- temp
不阻塞
a進程(a.c) b進程(b.c)
A.c
Int fd = open("temp");
Void *ptr = mmap(,,,fd,0);
對映射區進行讀寫操作
B.c
Int fd1 = open("temp");
Void *ptr1 = mmap(,,,,fd, 0);
對映射區做讀寫操作
mmap實現內存映射:
必須有一個文件
文件數據什么時候有用:
單純文件映射
進程間通信:
文件數據是沒有用的
父子進程永遠共享的東西?
文件描述符
內存映射區
#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDWR); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
如果對mmap的返回值(ptr) 做++操作(ptr++),munmap是否能夠成功?
#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDWR); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); ptr++; // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
如果open是O_RDONLY,mmap時port參數指定PROT_READ | PROT_WRITE會怎樣?
#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDONLY); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
如果文件偏移量為1000會怎樣?
#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDWR); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 1000); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
mmap后關閉文件描述符,對mmap映射有沒有影響?
#include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; char *pt; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDWR); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } close(fd); printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
父子進程間通信mmap
#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len, ret; pid_t pid; char *pt; void *ptr; // 1、打開一個文件 fd = open("temp.txt", O_RDWR); // 計算文件的大小 len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 創建子進程 pid = fork(); if (pid == -1) { perror("fork error"); exit(1); } if (pid > 0) { /* 父進程寫數據 */ strcpy((char *)ptr, "愛你美麗,想你美麗!\n"); // 回收子進程 wait(NULL); } if (pid == 0) { /* 子進程讀數據 */ sleep(1); printf("%s", (char *)ptr); } /* printf("%s", (char *)ptr); // ptr++; pt = ptr; pt++; */ // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0;
想使有血緣關系之間的進程進行通信,可以使用匿名內存映射的方式進行通信。
#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int len = 4096; int ret; pid_t pid; char *pt; void *ptr; // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 創建子進程 pid = fork(); if (pid == -1) { perror("fork error"); exit(1); } if (pid > 0) { /* 父進程寫數據 */ strcpy((char *)ptr, "愛你美麗,想你美麗!\n"); // 回收子進程 wait(NULL); } if (pid == 0) { /* 子進程讀數據 */ sleep(1); printf("%s", (char *)ptr); } // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } return 0; }
內存映射使用在沒有血緣關系的兩個進程間的通信
write.c
#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len; int ret; pid_t pid; char *pt; void *ptr; // 打開文件 fd = open("temp.txt", O_RDWR | O_CREAT, 0664); ftruncate(fd, 4096); len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 操作共享內存映射區寫數據 while (1) { char *p = (char *)ptr; p += 1024; strcpy(p, "meili i love you ,you go to where?\n"); sleep(2); } // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0; }
read.c
#include #include #include #include #include #include #include #include #include int main(int argc, char argv[]) { int fd, len; int ret; pid_t pid; char *pt; void *ptr; // 1、打開文件 fd = open("temp.txt", O_RDWR | O_CREAT, 0664); ftruncate(fd, 4096); len = lseek(fd, 0, SEEK_END); // 2、創建內存映射區 ptr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { perror("mmap error\n"); exit(1); } // 操作內存處理數據 while (1) { sleep(1); printf("%s", (char *)ptr + 1024); } // 3、釋放內存映射區 ret = munmap(ptr, len); if (ret == -1) { perror("munmap error\n"); exit(1); } close(fd); return 0; }
任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。