在Linux系统中,新的进程是通过已存在的父进程复制而来的。
2.1 fork函数原型
pid_t fork(void);
功能:创建一个新的进程。
参数:
无。
返回值:
fork函数调用一次返回两次。
父进程:返回子进程PID。
子进程:返回0。
失败:返回-1。
2.2 fork函数实现原理
2.3 父子进程虚拟地址空间(mm_struct)之间的关系
2.4 写时拷贝(copy-on-write)技术
传统fork函数缺点:
什么是写时拷贝?
写时拷贝是指父进程在创建子进程时,只创建虚拟地址空间,不为子进程分配实际的内存,父进程和子进程之间共享相同的物理内存页面。
当父进程或者子进程对虚拟地址空间对应的内存进行修改时才会分配实际内存。
写时拷贝技术优点:
拷贝前
拷贝后
2.5 父子进程如何共享文件(files_struct)
FD_CLOSEXEC文件标志?
子进程和父进程共享文件是一种不安全的行为,如果子进程调用exec家族函数,子进程的虚拟机制空间被新的程序替换,如果子进程还保留父进程的文件描述符表,后果很严重。
文件设置FD_CLOSEXEC文件标志后,子进程调用exec家族函数,该文件会被关闭。
如何设置FD_CLOSEXEC文件标志?
如:open(“file”, O_RDWR | O_CREAT | O_TRUNC | O_CLOSEXEC, 0644 );
3.1 vfork函数原型
pid_t vfork(void);
功能:fork函数创建一个新的子进程,该子进程与父进程共享相同的地址空间。
参数:
无。
返回值:
vfork函数调用一次返回两次。
3.2 vfork和fork函数区别?
不推荐使用vfork函数!!!
vfork函数由于子进程和父进程共享地址空间,vfork比传统fork函数效率高。随着写时复制技术出现,这个优势已经不存在了。
vfork存在不安全的行为,所以不推荐使用vfork函数。