进程fork和exec ---Unix网络编程笔记
—Unix网络编程笔记)
fork
#include <unistd.h>
pid_t fork(void);
一次调用,两次返回
fork在父进程中返回子进程的进程ID号,fork在子进程返回0。返回值告知当前进程是子进程还是父进程。
子进程如果想得到父进程的进程ID,可以调用getppid。
fork的两个典型用法
(1)一个进程创建一个自身的副本。
(2)一个进程想要执行另一个程序。该进程首先调用fork创建一个自身的副本,然后其中一个副本(子进程)调用exec把自身换成新的程序。
最简单的并发服务器—fork子进程
pid_t pid;
int listenfd,connfd;
listenfd = socket(...);
bind(listenfd,...);
for(;;){
connfd = accept(listen,...);
if( (pid = fork() ) == 0){
close(listenfd); //关闭子进程的listen套接字描述符
doit(connfd); //子进程的操作
close(connfd); //关闭子进程的connfd套接字描述符
exit(0); //处理完毕,退出子进程
}
close(connfd); //关闭父进程的connfd套接字描述符
}
每个文件或者套接字都有一个引用计数,它代表 当前打开着的 引用该文件或者套接字的 描述符的 个数。
fork函数执行之前父进程打开了 listenfd 和 connfd,因此这两个套接字的引用计数都是1。
forl函数执行之后,子进程复制父进程的资源,子进程中同样也有listen 和 connfd 套接字描述符,因此这两个套接字的引用计数都变成 2。
当父进程关闭connfd 套接字 ,子进程关闭listen套接字之后,这两个套接字的引用计数又重新变成1。
套接字真正的清理和资源释放要等到引用计数到达0时才发生。
exec
存放在硬盘上的可执行程序文件能够被Unix执行的唯一方法:由一个现有进程调用6个exec函数中的某一个。exec将当前进程映像替换成新的程序文件,而且该新程序通常从main函数开始执行。
称调用exec函数的进程为调用进程,新执行的程序称为新程序。
六个exec函数之间的区别:
(1)待执行的程序文件是由文件名还是由路径名指定
(2)新程序的参数是一一列出还是有一个指针数组来引用
(3)把调用进程的环境传递给新程序还是新程序指定新的环境
只有execve是内核中的系统调用,其他五个都是调用execve的库函数。