利用 mmap 实现进程之间的通信

1.mmap 使用的注意事项

(1)当 open 一个文件时,如果指定了 O_CREAT 标志并且文件不存在,就会新创建一个文件作为映射文件,此时必须调用 ftruncate 或者 lseek+write 设置文件长度,否则任然可以调用 mmap,但是对存储映射区的引用会产生 SIGBUS。另外,如果映射的长度超过了文件长度,访问超过文件长度的映射区也会出错。

(2)munmap 释放映射区时传入的指针必须指向最初分配的位置,否则将会出错(中途可移动映射区指针,但是必须从最开始分配的位置开始释放)。

(3)mmap 指定对映射区的访问权限时不能超过 open 对文件指定的访问权限。

(4)mmap 建立映射区时隐含一次对文件的读,因此打开文件时读权限是必须有的,即使你只进行写操作。

2.使用存储映射区实现父子进程间通信

注意:父子进程的内存空间遵循 读时共享、写时复制,但打开的文件和 mmap 建立的存储映射区在父子进程之间是一直共享的,因此可通过 mmap 建立存储映射区实现父子进程之间的通信。通过以下代码可说明:

#include <stdio.h>                                                                      
#include <stdlib.h>                                                                     
#include <unistd.h>                                                                     
#include <fcntl.h>                                                                      
#include <sys/mman.h>                                                                   
                                                                                        
int var = 10;                                                                           
                                                                                                                                                                                            
int main() {                                                                            
    int* p;                                                                             
    int fd;                                                                             
    pid_t pid;                                                                          
                                                                                        
    if ((fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {                 
        perror("open tmpfile");                                                         
        exit(1);                                                                        
    }                                                                                           
    unlink("tmpfile");      //解除硬链接,即删除了临时文件唯一的目录项,使之具备被删除的条件,但此时并未删除
    ftruncate(fd, 4);       //创建文件大小                                              
                                                                                        
    p = (int*)mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);                 
               
    if (p == MAP_FAILED) {                                                              
        perror("mmap failed");                                                          
        exit(1);                                                                        
    }                                                                                   
    close(fd);                                                                          
                                                                                        
    if ((pid = fork()) == 0) {      //child                                             
        sleep(1);                                                                       
        printf("In child: *p = %d, var = %d\n", *p, var);                               
    }                                                                                   
    else if (pid > 0) {     //parent                                                    
        *p = 2000;          //修改映射区                                                
        var = 1000;         //修改全局变量                                              
                                                                                        
        printf("In parent: *p = %d, var = %d\n", *p, var);                              
        wait(NUL
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值