One minute
Linux里fork出子进程的时候,哪些内容是共享的?
一、共享的内容
文件描述符与文件状态
子进程会继承父进程已打开的文件描述符表,包括文件偏移量、打开模式(如读写权限)和文件状态标志(如O_APPEND)。例如,若父进程打开了一个文件并写入数据,子进程可通过相同的文件描述符继续操作,且两者的写入位置(偏移量)会相互影响。
• 示例场景:父进程向文件写入“Parent”,子进程写入“Child”,最终文件内容会按操作顺序合并(如“ParentChild”或“ChildParent”),具体取决于调度顺序。信号处理设置
子进程继承父进程的信号处理函数(如SIG_IGN或自定义处理程序)和信号屏蔽集(sigprocmask的设置)。用户身份与环境变量
子进程继承父进程的用户ID、组ID、环境变量、当前工作目录等身份信息。写时复制(Copy-On-Write)的内存初始状态
在未发生写入操作前,父子进程的代码段(.text)、数据段(.data、.bss)、堆、栈等内存区域共享同一物理内存页。一旦某一方尝试修改数据,则会触发写时复制,生成独立的副本。文件锁
通过fcntl或flock设置的文件锁会被子进程继承,父子进程对同一文件的锁定操作会相互影响。
二、不共享的内容
进程独立属性
子进程拥有独立的进程ID(PID)、父进程ID(PPID)、运行时间统计、未决信号队列等。多线程环境中的线程资源
若父进程包含多个线程,子进程仅复制执行fork()的线程,其他线程不会被继承。独立的内存修改
通过写时复制机制,父子进程对内存的修改会各自独立。例如,全局变量初始值相同,但修改后互不影响。独立的文件描述符关闭操作
子进程关闭某个文件描述符不会影响父进程的同名描述符,反之亦然。
三、关键机制:写时复制(COW)
内核通过写时复制技术优化性能:
• 原理:fork()后,父子进程的页表项指向相同的物理内存页,并将这些页标记为只读。当某一进程尝试写入时,触发页错误,内核复制该页并修改权限为可写。
• 优点:避免不必要的内存复制,提高资源利用率。
四、应用注意事项
- 文件操作同步:父子进程对同一文件描述符的并发写入需通过锁(如
flock())或原子操作避免竞争。 - 内存共享限制:若需主动共享内存,需使用
mmap()或共享内存API(如shmget())。 - 僵尸进程处理:父进程需通过
wait()回收子进程资源,或注册SIGCHLD信号处理函数。