父子进程同时访问一个文件,实现文件共享的时候,会有哪些值得注意的情况。
主要目的是要看看父子进程到底有什么关联。
子进程继承父进程打开的文件
父进程先打开一个文件,然后fork一个子进程,则父子进程都可以操作这个文件。
经过实验,hello world说明父子进程是接续写入
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(void)
{
pid_t pid = -1;
int fd = -1;
fd = open("1.txt", O_TRUNC | O_RDWR);
if(fd < 0)
{
perror("open");
exit(-1);
}
pid = fork();
if(pid < 0)
{
perror("fork");
return -1;
}
else if(pid == 0)
{
printf("这里是子进程.\n");
write(fd, "world", 5);
//printf("pid = %d.\n", pid);
//printf("子进程中的父进程id = %d.\n", getppid());
//sleep(1);
}
else
{
printf("这里是父进程.\n");
write(fd, "hello", 5);
//printf("pid = %d.\n", pid);
//sleep(1);
}
//printf("这一句是否打印两次pid = %d.\n",getpid());
return 0;
}
测试结论是接续写,本质的原因是,子进程继承父进程的FD,这个指针是彼此关联的,特别想添加了O_APPEND的意思
实际测试时,有时候只有一个,有点像分别写,原因是文件太简短了,return0 相当于添加了close(fd),其实相当于父进程关闭了文件,其实就只写了一个进去。,办法时加sleep,延时关闭,这样就都会及时写入。
休眠的那一秒系统调度会执行子进程的操作,这样的话每一次都是接续写入,之前会有覆盖或者只有一个hello就是因为close时候会引起父进程回收给子进程的东西导致子进程没来的及执行完子进程要打印的东西。
子进程继承父进程的文件其实是接续写。
父进程和子进程分别打开同一个文件
注意这时候会发生什么
父进程打开1.txt然后写入,接下来子进程也打开1.txt然后写入
实验结果是分别写入,因为PCB已经分别独立了,因此两次读写是完全独立的
如果open的时候加入o_append,这样会把指针关联起来
父子进程虽然是分开的两个进程了,但还是有一点联系
父进程在fork之前干的事对子进程有很大影响,但是在fork之后对子进程就没什么影响了
本质上,fork是复制父进程的PCB生成了一个新的子进程,并且fork返回后,就彼此相对独立了,
子进程最终的目的,希望子进程独立地运行一些程序,子进程要去完成一些全新的独立的代码
后面就知道为什么要创建子进程,创建子进程有什么意义,要让子进程干什么东西,后面的课程就知道了
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main(void)
{
int fd = -1;
pid_t pid = -1;
pid = fork();
if(pid > 0)
{
fd = open("1.txt", O_RDWR | O_TRUNC);
if(fd < 0)
{
perror("p open");
return -1;
}
printf("P is ongoing.\n");
write(fd, "Pwrite", 6);
sleep(1);
}
else if(pid == 0)
{
fd = open("1.txt", O_RDWR | O_TRUNC);
if(fd < 0)
{
perror("p open");
return -1;
}
printf("C is ongoing.\n");
write(fd, "Cwrite", 6);
sleep(1);
}
exit(0);
//return 0;
}