1 mmap无血缘进程间通信
1)写文件:
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
typedef struct Student{
int id;
char name[64];
int age;
}student;
void sys_err(cost char *str){
perror(std);
exit(1);
}
int main(void)
{
struct student stu = {1, "xiaoming", 18};
struct student *p = NULL;
int fd;
fd = open("test_map", O_RDWR | O_CREAT | O_TRUNC, 0664);
if(fd == -1){
sys_err("open failed.");
}
ftruncate(fd, sizeof(stu));
p = mmap(NULL, sizeof(stu), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
sys_err("mmap error");
}
close(fd);
while (1){
memcpy(p, &stu, sizeof(stu));
stu.id++;
}
munmap(p, sizeof(stu));
return 0;
}
2)读文件:
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
typedef struct Student{
int id;
char name[64];
int age;
}student;
void sys_err(cost char *str){
perror(std);
exit(1);
}
int main(void)
{
struct student stu;
struct student *p = NULL;
int fd;
fd = open("test_map", O_RDONLY, 0664);
if(fd == -1){
sys_err("open failed.");
}
//ftruncate(fd, sizeof(stu));
p = mmap(NULL, sizeof(stu), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) {
sys_err("mmap error");
}
close(fd);
while (1){
//memcpy(p, &stu, sizeof(stu));
//stu.id++;
printf("id=%d, name=&s, age=%d\n", p->id, p->name, p->age);
}
munmap(p, sizeof(stu));
return 0;
}
结果如下,注意,由于我们开辟的映射区刚好是一个stu的大小,所以前面可能因为读得慢导致被覆盖掉几个student类型的数据。
2 多个读写mmap
首先:将上面的写程序的open,去掉O_TRUNC截断标志,保证多个进程写时文件可以追加。
1)多个写,一个读,可以看到,mmap是可以重复读取内容的,因为文件内容不变,而管道pipe,fifo只能读取一次,读走就没有了。
3 总结
- 1)mmap的数据可以重复读取,而pipe,fifo只能读取一次。
- 2)mmap能在无血缘的进程间通信根本原因是因为有共同的映射区。pipe,fifo因为有共同的管道。当然有血缘关系的mmap和匹配,fifo也可以这样解释。