一
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。
- 返回一个大于0的值给父进程
- 返回0给子进程
- 返回其他值说明fork失败了
#include<stdio.h> #include<unistd.h> int main() { pid_t pid; int count = 0; pid = fork(); //fork一个进程 if(pid == 0) { //pid为0, printf("this is child process, pid is %d\n",getpid());//getpid返回的是当前进程的PID count+=2; printf("count = %d\n",count); } else if(pid > 0) { printf("this is father process, pid is %d\n",getpid()); count++; printf("count = %d\n",count); } else { fprintf(stderr,"ERROR:fork() failed!\n"); } return 0; }
有人会对这个运行结果产生一种错觉,就是程序中if语句的两条分支if(pid == 0)和else if(pid > 0)都得到了执行,其实完全不是这么回事,出现这种运行结果的原因是因为,在main()函数的第6行fork了一个进程,这个进程称为原来进程的子进程,原来的那个进程称为父进程,这个进程与原来的进程并发执行,谁先税后没有规律,由操作系统调度决定。
二·
如使用fork()函数在多核机器上,父子进程可以同时执行,没有先后之分,在单处理器系统中,fork()之后很可能总是先调度父进程(优化性能),但如果恰好父进程的CPU时间片到期了,则执行子进程。所以用fork()函数不一定谁先执行。
如用vfork()创建的子进程与父进程共享地址空间,即子进程完全运行在父进程的地址空间上,子进程对虚拟地址空间的修改同样为父进程所见,
vfork保证子进程先运行,它调用exec或exit后父进程才能调度运行,fork的父子进程运行顺序不定,取决于内核的调度算法。
父进程中的数据空间和堆、栈可能会产生副本,具体情况要看使用的是fork还是vfork,fork产生副本,vfork则共享这部分内存。