前言补充:fork()的工作机制和原理
目录
问:fork 以后,父进程打开的文件指针位置在子进程里面是否一样?
问:父进程打开文件以后再进行fork,父进程打开的文件指针位置在子进程里面是否一样?
问:当父进程堆区申请的空间复制后,子进程也会有一份,那么子进程申请的空间是否也需要释放?
文件描述符
- 文件描述符是指每打开一个文件,就会在这个列表中分配一项,下标就是文件描述符,每一项都是一个指向struct file的指针。
- 在父进程向子进程传递文件描述符时,需要注意:传递一个文件描述符并不是传递一个文件描述符的值,而是要在接收进程中创建一个新的文件描述符,并且该文件描述符和发送过程中被传递的文件描述符指向内核中相同的文件表项
进程打开文件的流程
(注:struct在图里面写错了,谅解一下)
- 图表解释:
- 左一:PCB里的文件表,其中的01234就是文件描述符,0,1,2指代的内容要记住。
- 中间的图:内核为“3”维护的struct file的结构体。其中,文件偏移量是度量从文件开始处计算的字节数;引用基数是指把文件打开后,被引用的进程个数;inode是文件属性信息(磁盘中位置等等),通过inode结点就可以唯一的找到文件,打开它;打开方式是只读、只写、读写...
- 右一:inode节点,包含文件的有关属性信息。
在父进程和子进程中,有关对文件偏移量的理解:
问:fork 以后,父进程打开的文件指针位置在子进程里面是否一样?
答:一样
代码解释:
- 定义file.txt文件,内存储abcdefg
- 定义main.c文件:
- 文件内先在父进程内打开open文件,然后fork()复制出子进程:
- 运行结果:
结果分析:
- 父进程读完a,父子进程接下来从b开始,也就说明父子进程的文件偏移量共享(文件偏移量是度量从文件开始处计算的字节数)。先打开文件的那个先打印(父进程先读取a,然后子进程就开始读取b)。父进程打开文件后,fork出子进程,复制pcb就相当关于把文件表也复制一份,就也指向struct,如下图所示:
- 父子进程都把file.txt打开了。因此,在关闭文件时,父子进程都要关闭。
- 如下图所示fork()复制的过程, 父进程有pcb,fork复制一份pcb,然后把pcb里的pid的加1。父进程读一次,文件偏移量+1,子进程读一次,+1,因此打印的结果是abcd
- 首先,fork创建的子进程的pcb,然后,子进程把父进程的拷贝一份。子进程的file.txt就是拷贝父进程的,也就是他俩共享fork之前的文件描述符。
总结:父进程的文件描述符fork以后,子进程也可以访问,而且父子进程共享文件偏移量。(父进程打开一个文件,fork之后的子进程也可以使用,父子进程共享)
补充:在这种情况下,共享偏移量,如果父子进程共同编写文件会出错,因此,父进程一般情况下把文件给子进程,子文件编写。
问:父进程先进行fork以后再打开文件,父进程打开的文件指针位置在子进程里面是否一样?
答:不一样
解答:
代码解释:
- 修改代码运行
- 运行结果:
结果分析:
- 过程如下图所示,先打开文件再进行fork复制,此时父子进程都有自己的文件打开流程了,就不再共享,各自用各自的。
问:当父进程堆区申请的空间复制后,子进程也会有一份,那么子进程申请的空间是否也需要释放?
答:需要
如有疑问或错误,还请在评论区告诉我~❤
本文详细解析了fork机制在进程复制中的工作原理,特别是针对文件描述符的处理方式,包括父子进程如何共享或独立操作已打开的文件,以及内存空间管理。








1140

被折叠的 条评论
为什么被折叠?



