#include <unisth.h>
pid_t fork(void)
fork函数被调用一次,返回两次。子进程的返回值是0,父进程的返回值是子进程的进程id。
fork函数调用一次却返回两次:向父进程返回子进程的ID,向子进程中返回0。这是因为父进程可能存在很多个子进程,所以必须通过这个返回的子进程ID来跟踪子进程;而子进程只有一个父进程,他的ID可以通过getppid取得。
子进程和父进程继续执行fork调用之后的指令,子进程是父进程的副本,子进程获得父进程数据空间、堆和栈的副本。注意:这是子进程所拥有的副本,父子进程并不共享这些存储空间部分。父子进程共享正文段
#include <stdio.h> #include <sys/types.h> #include <unistd.h> int glob=6;//全局变量,在堆中 char buf[]="a write to stdout "; int main() { int var;//局部变量,栈中 pid_t pid; var =88; if(write(STDOUT_FILENO,buf,sizeof(buf)-1)!=sizeof(buf)-1) { perror("write error"); } printf("before fork: "); if((pid=fork())<0) { perror("fork error"); } else if(pid==0) { glob++; var++; } else{ sleep(2); } printf("pid=%d,glob=%d,var=%d ",getpid(),glob,var); exit(0); }
输出:
a write to stdout
before fork:
pid=4989,glob=7,var=89
pid=4988,glob=6,var=88
fork的两种用法:
1.一个父进程希望复制自己,使父子进程同时执行不同的代码段
2.一个进程要执行一个不同的程序,在这种情况下,子进程从fork返回后立即调用exec
/* fork_test.c */ #include<sys/types.h> #inlcude<unistd.h> main() { pid_t pid; /*此时仅有一个进程*/ pid=fork(); /*此时已经有两个进程在同时运行*/ if(pid<0) printf("error in fork!"); else if(pid==0) printf("I am the child process, my process ID is %d/n",getpid()); else printf("I am the parent process, my process ID is %d/n",getpid()); }