目录
1、非父子进程间通信
假设现在有两个毫无关联的进程A、B,要让这两个进程进行通信,其实就是让这两个进程跟同一个文件建立映射。相当于一个进程在向文件写内容,一个进程在从文件读内容。
(1) 进程 mmap_w:负责写文件
我们让进程mmap_w 每隔 1s向映射空间中写入一个字节。
int main(){
int fd = open("./log.txt", O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
int len = lseek(fd, 0, SEEK_END);
void* addr = mmap(NULL, len, PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED)
{
perror("mmap");
return -1;
}
close(fd);
int i = 0;
while(1){
memcpy(addr + i, "a", 1); // 每隔1s向 addr + i 的位置写入一个字节
i++;
sleep(1);
}
munmap(addr, len); // 释放映射
}
(2) 进程mmap_r:负责读文件
该进程每隔1s就打印映射空间里的内容。
int main(){
int fd = open("./log.txt", O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
int len = lseek(fd, 0, SEEK_END);
void* addr = mmap(NULL, len, PROT_WRITE, MAP_SHARED, fd, 0);
if(addr == MAP_FAILED)
{
perror("mmap");
return -1;
}
close(fd);
while(1){
printf("%s\n", (char*)addr); // 打印内存映射空间的内容
sleep(1);
}
munmap(addr, len); // 释放映射
}
2、父子间进程通信
mmap 的第四个参数flags,可以设置为匿名映射(MAP_ANONYMOUS),此时就可以实现父子间进程通信了。下面我们让父进程写入一串字符,子进程读取这串字符。
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
int main(){
int fd = open("./log.txt", O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
int len = lseek(fd, 0, SEEK_END);
void* addr = mmap(NULL, len, PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, fd, 0);
if(addr == MAP_FAILED)
{
perror("mmap");
return -1;
}
close(fd);
pid_t pid = fork();
if(pid < 0)
{
perror("fork");
return -1;
}
else if(pid > 0)
{
// 父进程
const char* str = "hello, world";
memcpy(addr, str, strlen(str));
wait(NULL);
}
else
{
// 子进程
sleep(1); // 因为不知道谁先执行完,这么做可以保证父进程先写,子进程后读
printf("%s\n",(char*)addr);
}
}