函数功能
fork()函数的详细介绍可以用man命令来查看,下面截取一部分重要的介绍。
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process.
The child process and the parent process run in separate memory spaces. At the time of fork() both memory spaces have the same content. Memory writes, file mappings (mmap(2)), and unmap‐pings (munmap(2)) performed by one of the processes do not affect the other.
RETURN VALUE
On success, the PID of the child process is returned in the parent, and 0 is returned in the child. On failure, -1 is returned in the parent, no child process is created, and errno is set appropriately.
NOTES
Under Linux, fork() is implemented using copy-on-write pages, so the only penalty that it incurs is the time and memory required to duplicate the parent’s page tables, and to create a unique task structure for the child.
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(){
pid_t pid;
pid = fork();
if(pid == 0){ /* child */
pid = getpid();
printf("child's pid:%d\r\n",pid);
exit(0);
}
else{ /* parent */
pid = getpid();
printf("parent's pid:%d\r\n",pid);
wait(NULL); /* Wait for child */
exit(0);
}
return 0;
}
上面的exit()函数是退出进程,exit(0)表示正常退出。创建的子进程执行完之后会自动退出,因此if对应的else可以不要。
wait()函数一般都要和fork()函数配套使用,作用等待子进程退出。
一次调用,两次返回
fork()函数一次调用,两次返回,通过返回值来判断返回的是那个进程,因此不同的执行代码应该放到不同的进程中,如果不做区分,fork()后面的代码会被执行两次,例如下面的例子。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(){
fork();
printf("Hello World!\r\n");
return 0;
}
上面的代码只有一次打印,但是调用fork()的原因,会打印两次。
下面的代码会打印四次:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
int main(){
fork();
fork();
printf("Hello World!\r\n");
return 0;
}
明确创建关系
由于fork()函数会两次返回,因此在创建新进程的时候一定明确哪个是父进程,子进程由哪个进程创建,特别是存在多个进程的时候。例如下面的代码中两个子进程都是由同一个父进程创建的:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(){
pid_t pid;
pid = fork();
if(pid == 0){/*child*/
/*code*/
printf("child 1 pid:%d\r\n",getpid());
exit(0);
}
pid = fork();
if(pid == 0){/*child*/
/*code*/
printf("child 2 pid:%d\r\n",getpid());
exit(0);
}
while(pid = wait(NULL),pid != -1){} /*wait for child*/
return 0;
}