一、关于子进程
(1)子进程和父进程的关系
(2)子进程有自己独立的PCB
(3)子进程被内核同等调度
二、父子进程对文件的操作
1、子进程继承父进程中打开的文件
(1) 上下文:父进程先open打开一个文件得到fd,然后在fork创建子进程。之后在父子进程中各自write向fd中写入内容
(2) 测试结论是:接续写
。实际上本质原因是父子进程之间的fd对应的文件指针是彼此关联的(很像O_APPEND标志后的样子)
(3) 实际测试时有时候会看到只有一个,有点像分别写。但是实际不是,原因是当父进程或者子进程其中有一个还没开始调度执行,其两个进程的某个进程就已经运行结束 然后操作系统帮我们关闭了文件,导致文件只被写入了一次数据。
添加 slepp函数,等待两个进程都执行完,这样就能测得结论是 接续写
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
// 首先打开一个文件
int fd = -1;
pid_t pid = -1;
fd = open("1.txt", O_RDWR | O_TRUNC);
if (fd < 0)
{
perror("open");
return -1;
}
// fork创建子进程
pid = fork();
if (pid > 0)
{
// 父进程中
printf("parent.\n");
write(fd, "hello", 5);
sleep(1);
}
else if (pid == 0)
{
// 子进程
printf("child.\n");
write(fd, "world", 5);
sleep(1);
}
else
{
perror("fork");
exit(-1);
}
return 0;
}
2、父子进程各自独立打开同一文件实现共享
(1)父进程open打开1.txt然后写入,子进程打开1.txt然后写入,结论是:
分别写
。
原因是父子进程分离后才各自打开的1.txt,这时候这两个进程的PCB已经独立了,文件表也独立了,因此2次读写是完全独立的。
(2)open时使用O_APPEND标志看看会如何?实际测试结果标明O_APPEND标志可以把父子进程各自独立打开的fd的文件指针给关联起来,实现分别写。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
// 首先打开一个文件
int fd = -1;
pid_t pid = -1;
// fork创建子进程
pid = fork();
if (pid > 0)
{
// 父进程中
fd = open("1.txt", O_RDWR | O_APPEND);
if (fd < 0)
{
perror("open");
return -1;
}
printf("parent.\n");
write(fd, "hello", 5);
sleep(1);
}
else if (pid == 0)
{
// 子进程
fd = open("1.txt", O_RDWR | O_APPEND);
if (fd < 0)
{
perror("open");
return -1;
}
printf("child.\n");
write(fd, "world", 5);
sleep(1);
}
else
{
perror("fork");
exit(-1);
}
close(fd);
}
总结
(1)父子进程间终究多了一些牵绊
(2)父进程在没有fork之前自己做的事情对子进程有很大影响,但是父进程fork之后在自己的if里做的事情就对子进程没有影响了。本质原因就是因为fork内部实际上已经复制父进程的PCB生成了一个新的子进程,并且fork返回时子进程已经完全和父进程脱离并且独立被OS调度执行。
(2)子进程最终目的是要独立去运行另外的程序