多进程fork

转自: http://blog.youkuaiyun.com/jason314/article/details/5640969



<think>好的,用户想了解在C++中使用fork创建多进程后,哪些资源会被共享。我需要结合提供的引用资料来回答这个问题。 首先,根据引用[4],fork创建的子进程会拷贝父进程的资源,而不是共享,所以各自修改数据不会影响对方。这说明一般情况下,资源是拷贝的,但可能存在例外。 然后,引用[2]和[3]提到fork的基本用法,子进程复制父进程的地址空间。但系统为了效率,可能使用写时复制(COW)技术,这时候资源在未修改时是共享的,直到有写入操作才会复制。不过引用里没有直接提到COW,可能需要确认是否属于隐含知识。 接下来,需要考虑哪些资源是共享的。通常来说,文件描述符在fork后会共享,因为子进程会复制父进程的文件表项,导致同一文件偏移量。引用中没有提到这点,但根据常规知识,这属于共享资源的一部分。 其他共享资源可能包括:打开的文件的文件描述符、文件指针的位置、信号处理函数等。而独立的部分包括内存变量、堆栈数据等,因为每个进程有自己的地址空间。 总结起来,需要分清楚“共享”和“复制”的区别。fork后,子进程获得父进程资源的副本,但某些资源如文件描述符可能指向相同的系统级资源,所以表现出共享的行为。但根据引用[4],资源并不共享,所以这里的共享可能是指内核中的同一资源,比如文件描述符表项,而用户空间的数据是独立的。 最后,整理出共享的资源包括文件描述符、信号处理程序,以及可能的命名管道等。需要明确说明哪些是复制但表现为共享,哪些是真正共享的。</think>在C++多进程编程中,`fork()`调用会创建一个与父进程几乎完全相同的子进程。关于资源共享机制,需从以下三个层面分析: ### 一、进程资源的复制机制 通过`fork()`创建的子进程会复制父进程的**完整虚拟地址空间副本**,包括: - 堆内存段(如`malloc`分配的内存) - 栈内存段(局部变量) - 数据段(全局变量、静态变量) - 代码段(程序指令) 例如父进程有全局变量`int global = 10;`,子进程修改为`global = 20;`后,父进程的`global`仍保持10[^4]。 ### 二、显式共享的资源 以下三类资源会真正实现共享: 1. **文件描述符** - 子进程继承父进程打开的文件描述符表 - 共享文件偏移量指针(如同时写入同一文件会交错输出) ```c++ int fd = open("data.txt", O_WRONLY); fork(); write(fd, "test", 4); // 父子进程都会写入同一文件位置 ``` 2. **内存映射文件** - 使用`mmap()`创建的文件映射区域 - 修改会同步到磁盘文件但不会在进程间自动同步 3. **命名资源** - 命名管道(FIFO) - System V共享内存 - 消息队列等IPC资源 ### 三、内核级共享机制 | 资源类型 | 共享特性 | 示例场景 | |-----------------|----------------------------------|--------------------------| | 信号处理函数 | 子进程继承信号处理器设置 | `signal(SIGINT, handler)`| | 用户ID/组ID | 保持相同的身份标识 | 权限校验场景 | | 进程组/会话ID | 维持进程间关系 | shell作业控制 | | 文件锁 | 锁状态被子进程继承 | `flock()`锁文件操作 | ### 四、写时复制优化(COW) 现代操作系统通过**Copy-On-Write**技术优化资源复制: 1. 父子进程初始共享物理内存页 2. 当任一进程尝试修改内存页时 3. 内核自动创建该页的独立副本 4. 该机制对进程完全透明 这种机制使得`fork()`的实际资源消耗远小于完全复制的情况[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值