linux 進程通信子mmap

  1. mmap 文件–內存映射
    函數原型
 #include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
參數介紹:
add 傳 NULL
length 映射區的長度
protPROT_READ 可讀PROT_WRITE可寫
flagsMAP_SHARED 共享的,對內存的修改會影響源文件MAP_PRIVATE 私有的
fd 文件描述符,open一個文件
offset 偏移量返回值:成功:返回可用內存的首地址,失敗:返回MAP_FAILED

釋放映射區

 int munmap(void *addr, size_t length);
參數:
addr 傳mmap的返回值
length mmap創建的長度
返回值:成功返回0失敗返回-1

#include <unistd.h>
#include <sys/types.h>
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);

這兩個函數可以根據文件描述符,或者是文件名,修改文件的大小(字節)

  1. mmap函數注意事項
    在這里插入圖片描述
  2. 使用mmap進行父子進程之間的通信
    代碼示例:
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>int main(int argc, char *argv[]) {if(argc !=2) {printf("./a.out filename1");return -1;}int fd = open(argv[1], O_RDWR|O_CREAT, 0666);ftruncate(fd, 4);int *mem = mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_SHARED, fd , 0);pid_t pid = fork();if(pid == 0) {// son*mem = 100;sleep(3);printf("son mem = %d\n", *mem);} else if(pid>0){//fathersleep(1);printf("father mem = %d\n", *mem);*mem = 2;wait(NULL);}munmap(mem, 4);close(fd);return 0;
}
  1. 使用mmap,讓無血緣關系的進程之間進行通信代碼案例:

寫端:

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
typedef struct _student
{int sid;char sname[20];
}Student;
int main(int argc, char *argv[]) {if(argc!=2) {printf("./a.out filename\n");return -1;}int fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);int length = sizeof(Student);ftruncate(fd, length);Student *stu = mmap(NULL, length, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);int num = 0;while (1){stu->sid = num++;sprintf(stu->sname, "mynames_x%d", num); sleep(1);}munmap(stu, length);close(fd);return 0;
}

讀端:

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/wait.h>
typedef struct _student
{int sid;char sname[20];
}Student;
int main(int argc, char *argv[]) {if(argc!=2) {printf("./a.out filename\n");return -1;}int fd = open(argv[1], O_RDONLY, 0666);int length = sizeof(Student);ftruncate(fd, length);Student *stu = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);int num = 0;while (1){printf("read sid= %d\n", stu->sid);printf("%s\n", stu->sname);sleep(1);}munmap(stu, length);close(fd);return 0;
}
  1. 利用mmap使用4個進程對一個文件進行拷貝
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>int main(int argc, char*argv[]) {if(argc!=3) {printf("./a.out filename_src filename_desc \n");return -1;}int srcfd = open(argv[1], O_RDWR);int desfd = open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0666);struct stat sb;stat(argv[1], &sb);int len = sb.st_size;truncate(argv[2], len);char *memsrc = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, srcfd, 0);if(memsrc == MAP_FAILED) {printf("mmaperror1\n");return -1;}char *memdes = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, desfd, 0);if(memdes == MAP_FAILED) {printf("mmaperror2\n");return -1;}int i=0;int one_size = len / 4;int remainder_size = len % 4;pid_t pid;for(; i<5; ++i) {pid = fork();if(pid==0) {break;}}if (i<5) {if(i==4) {memcpy(memdes + i*one_size, memsrc + i*one_size, one_size + remainder_size);} else {memcpy(memdes + i*one_size, memsrc + i*one_size, one_size);}} else {wait(NULL);printf("cp file end\n");}int unmemsrc = munmap(memsrc, len);int unmemdes = munmap(memdes, len);printf("%d unmemsrc --------- %d\n", getpid(), unmemsrc);printf("%d unmemdes %d\n", getpid(), unmemdes);close(desfd);close(srcfd); return 0;
}

ps:疑惑的地方 上面這端代碼最后釋放內存的這一部分,相當于多個進程對同一塊內存進行了重復釋放吧? 是這樣嗎?
ps2:疑惑的地方 mmap通過文件映射的內存位于哪塊內存區???

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382514.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382514.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382514.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

malloc和calloc的區別

是否對申請的區域進行初始化而已 但是我想你也知道我們寫程序的時候多用malloc而很少用calloc&#xff0c;何解&#xff1f; 因為calloc雖然對內存進行了初始化&#xff08;全部初始化為0&#xff09;&#xff0c;但是同樣也要降低效率的 calloc相當于 p malloc(); memset(p,…

linux信號學習02

未決信號集與阻塞信號集(信號屏蔽字) 阻塞信號集&#xff1a; 將某些信號加入集合&#xff0c;對他們設置屏蔽&#xff0c;當屏蔽x信號后&#xff0c;再收到該信號&#xff0c;該信號的處理將推后(解除屏蔽后) 未決信號集&#xff1a; a. 信號產生&#xff0c;未決信號集中描述…

task_struct 結構如何查看及分析

cd /find -name sched.hvim usr/src/kernels/3.10.0862.6.3.el7.x86_64/include/linux/sched.hhttps://www.cnblogs.com/zxc2man/p/6649771.html 進程是處于執行期的程序以及它所管理的資源&#xff08;如打開的文件、掛起的信號、進程狀態、地址空間等等&#xff09;的總稱。…

linux 與信號集操作相關的函數

與信號集操作相關的函數 #include <signal.h> 清空信號集 全都為0 int sigemptyset(sigset_t *set);填充信號集 全都為1 int sigfillset(sigset_t *set);添加某個信號到信號集 int sigaddset(sigset_t *set, int signum);從集合中刪除某個信號 int sigdelset(sigset_t *s…

軟件工程學習筆記《三》代碼優化和性能測試

文章目錄軟件工程學習筆記目錄如何在開源社區提問&#xff1f;代碼審查代碼優化運行結果參數解釋代碼優化原則對常見的數據結構排序算法進行測試關于冒泡排序優化的探討結果軟件工程學習筆記目錄 [https://blog.csdn.net/csdn_kou/article/details/83754356] 如何在開源社區提…

linux信號捕捉

信號捕捉&#xff0c;防止進程意外死亡 signal函數 man signal #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);參數介紹&#xff1b; signum 要捕捉的信號 handler 要執行的捕捉函數指針&#xff0c…

軟件工程學習筆記《目錄》

軟件工程學習筆記《目錄》 軟件工程學習筆記《一》什么是軟件工程 軟件工程學習筆記《二》代碼規范 軟件工程學習筆記《三》代碼優化和性能測試 軟件工程學習筆記《四》需求分析

linux進程利用SIGCHLD信號,來實現父進程回收子進程

子進程執行完畢后&#xff0c;會向父進程發出 SIGCHLD信號 &#xff0c; 這段代碼實現的就是i&#xff0c;父進程接受到子進程 發出的SIGCHLD信號&#xff0c;實現對子進程進行回收&#xff0c;從而避免僵尸進程 #include <stdio.h> #include <unistd.h> #include…

WWW軟件全球使用排名

https://w3techs.com/technologies/overview/web_server/all Apache份額一直下降呀&#xff01;

軟件工程學習筆記《四》需求分析

文章目錄軟件工程學習筆記《目錄》需求工程師當代的需求工程師需要具備的能力當代的需求工程師需要努力的方向當代的需求工程師需要注意的錯誤需求的定義需求目標需求分析的實質需求分析的關鍵應該涵蓋的內容&#xff1f;需求規約&#xff08;作為較客觀的參照&#xff09;單個…

linux守護進程

先了解 linux系統中 會話的概念 會話是進程組的更高一級&#xff0c;多個進程組對應一個會話。 會話是一個或多個進程組的集合 創建一個會話需要注意以下5點事項&#xff1a; a. 調用進程不能是進程組組長&#xff0c; 該進程變成新會話首進程&#xff08;session header&#…

python3爬蟲學習筆記

文章目錄python3的文本處理jieba庫的使用統計hamlet.txt文本中高頻詞的個數統計三國演義任務高頻次數爬蟲爬取百度首頁爬取京東某手機頁面BeautifulSoup使用request進行爬取&#xff0c;在使用 BeautifulSoup進行處理&#xff01;擁有一個更好的排版BeautifulSoup爬取百度首頁原…

linux 線程學習初步01

線程的概念 進程與線程內核實現 通過函數clone實現的 ps -Lf pidLinux內核線程實現原理 同一個進程下的線程&#xff0c;共享該進程的內存區&#xff0c; 但是只有stack區域不共享。 線程共享資源 a.文件描述符表 b.每種信號的處理方式 c.當前工作目錄 d.用戶id和組id 線程…

python3字符串處理,高效切片

高級技巧&#xff1a;切片&#xff0c;迭代&#xff0c;列表&#xff0c;生成器 切片 L [Hello, World, !]print("-------1.一個一個取-------") print(L[0]) print(L[1]) print(L[2])print("-------2.開辟一個新列表把內容存進去-------") r [] for i…

linux線程學習初步02

殺死線程的函數 int pthread_cancel(pthread_t thread); 參數介紹&#xff1a;需要輸入的tid 返回值&#xff1a;識別返回 errno成功返回 0 被殺死的線程&#xff0c;退出狀態值為一個 #define PTHREAD_CANCELED((void *)-1)代碼案例&#xff1a; #include <stdio.h> #…

python的文件基本操作和文件指針

讀寫模式的基本操作 https://www.cnblogs.com/c-x-m/articles/7756498.html r,w,a r只讀模式【默認模式&#xff0c;文件必須存在&#xff0c;不存在則拋出異常】w只寫模式【不可讀&#xff1b;不存在則創建&#xff1b;存在則清空內容】a之追加寫模式【不可讀&#xff1b;不…

python3 將unicode轉中文

decrypted_str.encode(utf-8).decode(unicode_escape)

HTTP菜鳥教程速查手冊

HTTP協議&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是因特網上應用最為廣泛的一種網絡傳輸協議&#xff0c;所有的WWW文件都必須遵守這個標準。 HTTP是一個基于TCP/IP通信協議來傳遞數據&#xff08;HTML 文件, 圖片文件, 查詢結果等&am…

mysql學習筆記01-創建數據庫

創建數據庫&#xff1a; 校驗規則&#xff1a;是指表的排序規則和查詢時候的規則 utf8_general_ci 支持中文&#xff0c; 且不區分大小寫 utf8_bin 支持中文&#xff0c; 區分大小寫 比如&#xff1a; create database db3 character set utf8 collate utf8_general_ci; &…

python的Web編程

首先看一下效果 完整代碼 import socket from multiprocessing import ProcessHTML_ROOT_DIR ""def handle_client(client_socket):request_data client_socket.recv(1024)print("request data:", request_data)response_start_line "HTTP/1.0 20…