14.多进程fork后不同进程会共享哪些资源

2026-01-23
963 字 · 5 分钟

🔬 多进程fork后资源共享机制

📖 内容概览

本文详细介绍C++多进程编程中fork函数创建子进程后,父子进程之间资源共享的机制,包括文件描述符、内存映射、信号处理等方面,并通过示例代码演示资源共享的具体行为。

🎯 核心概念

✨ fork函数的基本概念

fork函数是创建新进程的系统调用,创建的子进程是父进程的副本。父子进程的虚拟存储空间用户空间是相同的,父进程的资源会被拷贝给子进程,但采用写时拷贝(Copy-on-Write)机制,只有在子进程修改数据时才会实际拷贝。

🔗 资源共享机制

父子进程在fork后共享以下资源:

  1. 文件描述符表:父进程打开的所有文件描述符在子进程中都存在副本
  2. 文件表和v-node表:所有进程共享文件表和v-node表,因此对文件的操作是共享的
  3. 内存映射:通过mmap创建的内存映射区域是共享的
  4. 信号处理函数:信号处理函数在fork后保持一致

🛠️ 代码示例

📝 文件描述符共享演示

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
int main()
{
int fd;
char c[3];
/* 打开文件foobar.txt,采用只读形式 */
fd = open("foobar.txt", O_RDONLY, 0);
if (fork() == 0) { // 子进程
read(fd, &c, 2); /* 读文件的两个字节到c中 */
c[2] = '\0';
printf("子进程读取: c = %s\n", c);
exit(0);
}
else { // 父进程
wait(NULL); /* 等待子进程结束 */
read(fd, &c, 2);
printf("父进程读取: c = %s\n", c);
}
}

📋 运行结果

假设foobar.txt中的内容是”foobar”,编译运行后输出:

Terminal window
[gong@Gong-Computer cprogram]$ gcc -g fileshare2.c -o fileshare2
[gong@Gong-Computer cprogram]$ ./fileshare2
子进程读取: c = fo
父进程读取: c = ob

🔍 结果分析

🧩 共享文件指针

  • 父子进程共享同一文件表,因此文件读写位置是共享的
  • 子进程读取两个字节后,文件指针移动到位置2
  • 父进程继续从位置2开始读取,因此读取到”ob”
  • 这种共享机制使得父子进程可以协同操作同一文件

🧩 独立的文件描述符表

  • 每个进程都有独立的文件描述符表
  • 当父进程或子进程调用close(fd)时,只会关闭自己的文件描述符
  • 只有当所有引用同一文件的文件描述符都关闭后,文件才会真正关闭

⚠️ 注意事项

  1. 写时拷贝机制:父子进程的内存空间在fork时是共享的,但当任一进程修改内存时,会触发写时拷贝,此时才会实际分配新的内存
  2. 信号处理:fork后子进程会继承父进程的信号处理函数,但子进程的信号掩码和挂起信号会被重置
  3. 文件锁:文件锁不会被继承,子进程需要重新获取锁
  4. 定时器:定时器不会被继承,子进程需要重新设置
  5. 进程ID和父进程ID:子进程的PID和PPID与父进程不同

📋 总结

  • 共享资源:文件描述符表、文件表、v-node表、内存映射、信号处理函数
  • 独立资源:进程ID、父进程ID、内存数据(写时拷贝)、信号掩码、挂起信号、文件锁、定时器
  • 协同操作:通过共享文件指针,父子进程可以协同操作同一文件
  • 写时拷贝:优化了fork的性能,避免了不必要的内存拷贝 理解fork后的资源共享机制对于编写正确的多进程程序至关重要,特别是在涉及文件操作、内存共享和信号处理时。

Thanks for reading!

14.多进程fork后不同进程会共享哪些资源

2026-01-23
963 字 · 5 分钟

已复制链接

评论区

目录