具体mmap的细节可参考这篇博客, 下面举例示范在Linux环境下两个线程(进程同理)通过将同一个文件映射至各自进程地址空间中, 从而实现进程间通信。
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int chil_fun(char *path) {//子线程执行的函数
const char *filepath = path;
int fd = open(filepath, O_RDWR);
if (fd < 0) {
printf("\n\"%s \" could not open\n", filepath);
exit(1);
}
struct stat statbuf;
int err = fstat(fd, &statbuf);
if (err < 0) {
printf("\n\"%s \" could not open\n", filepath);
exit(2);
}
char *ptr = (char *) mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
printf("Mapping Failed\n");
return 1;
}
close(fd);
// ssize_t n = write(1, ptr, statbuf.st_size);
// if (n != statbuf.st_size) {
// printf("Write failed\n");
// }
printf("init text: %s\n", ptr);
for (size_t i = 0; i < statbuf.st_size / 2; i++) {//翻转文件里的内容
int j = statbuf.st_size - i - 1;
int t = ptr[i];
ptr[i] = ptr[j];
ptr[j] = t;
}
err = munmap(ptr, statbuf.st_size);
if (err != 0) {
printf("UnMapping Failed\n");
return 1;
}
return 0;
}
int par_fun(char *path) {//父线程执行的函数
const char *filepath = path;
int fd = open(filepath, O_RDWR);
if (fd < 0) {
printf("\n\"%s \" could not open\n", filepath);
exit(1);
}
struct stat statbuf;
int err = fstat(fd, &statbuf);
if (err < 0) {
printf("\n\"%s \" could not open\n", filepath);
exit(2);
}
char *ptr = (char *) mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED) {
printf("Mapping Failed\n");
return 1;
}
close(fd);
// ssize_t n = write(1, ptr, statbuf.st_size);
// if (n != statbuf.st_size) {
// printf("Write failed\n");
// }
printf("text after reverse: %s\n", ptr);
err = munmap(ptr, statbuf.st_size);
if (err != 0) {
printf("UnMapping Failed\n");
return 1;
}
return 0;
}
int main(int argc, char *argv[]) {// 命令行传入文本文件路径, 子线程翻转文件里的内容, 父线程输出文件翻转后的内容
pid_t child_pid = fork();
if (child_pid == 0) {//child
chil_fun(argv[1]);
} else {//parent
waitpid(child_pid, NULL, 0);
par_fun(argv[1]);
}
return 0;
}