使用文件也可以完成IPC,理论依据是,fork后,父子进程共享文件描述符。也就共享打开的文件。
//父子进程共享打开的文件。借助文件进行进程间通信(可先打开文件,再创建子进程)
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/wait.h>int main(void)
{int fd1, fd2;
pid_t pid;char buf[1024];char *str = "---------test for shared fd in parent child process-----\n";pid = fork();if (pid < 0) {perror("fork error");exit(1);} else if (pid == 0) {fd1 = open("test.txt", O_RDWR);if (fd1 < 0) {perror("open error");exit(1);}write(fd1, str, strlen(str));printf("child wrote over...\n");} else {fd2 = open("test.txt", O_RDWR);if (fd2 < 0) {perror("open error");exit(1);}sleep(1); //保证子进程写入数据int len = read(fd2, buf, sizeof(buf));write(STDOUT_FILENO, buf, len);wait(NULL);}return 0;
}
[root@localhost mmap]# ./fork_share_fd
child wrote over...
---------test for shared fd in parent child process-----
另外,无血缘关系的进程也可以打开同一个文件进行通信,方法一样,因为这些进程打开的是同一个进程。其实在打开文件时(调用open时),操作系统内核就调用了mmap。因为一个文件只有一个文件结构体(FILE),打开时位于内核,被打开这个文件的多个进程共享。
//进程1(先执行,将数据写入文件test.txt)
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>#define N 10int main(void)
{char buf[1024];char *str = "--------------secesuss-------------\n";int ret;int fd = open("test.txt", O_RDWR|O_TRUNC|O_CREAT, 0664);//直接打开文件写入数据write(fd, str, strlen(str));printf("test1 write into test.txt finish\n");sleep(N);lseek(fd, 0, SEEK_SET); //文件读写指针置于开始处ret = read(fd, buf, sizeof(buf));ret = write(STDOUT_FILENO, buf, ret);if (ret == -1) {perror("write second error");exit(1);}close(fd);return 0;
}
//进程2(后执行,尝试读取进程1写入文件的内容)
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>int main(void)
{char buf[1024];char *str = "----------test2 write secesuss--------\n";int ret;sleep(2); //睡眠2秒,保证test1将数据写入test.txt文件int fd = open("test.txt", O_RDWR); //打开文件,读写指针位于开头处ret = read(fd, buf, sizeof(buf)); //尝试读取test.txt文件中test1写入的数据write(STDOUT_FILENO, buf, ret); //将读到的数据打印至屏幕write(fd, str, strlen(str)); //写入数据到文件test.txt中, 未修改读写位置printf("test2 read/write finish\n");close(fd);return 0;
}
[root@localhost file_IPC]# ./test1
test1 write into test.txt finish
--------------secesuss-------------
----------test2 write secesuss--------
[root@localhost file_IPC]# ./test2
--------------secesuss-------------
test2 read/write finish //通过文件,进程1写入的数据,进程2可以获取;反之,一样。