fork - create a child process (fork函数创建子进程)
#include <unistd.h>
pid_t fork(void);
/*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.*/
使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int arg,char *argc[])
{
int num=10;
pid_t pid;
pid=fork();
if(pid==0)
{
num++;
printf("child process running,the num is %d\n",num);
printf("pid is %d\n",getpid());
}
else if(pid>0)
{
num++;
printf("parent process running,the num is %d\n",num);
printf("pid is %d,pid_t 返回值为%d\n",getpid(),pid);
}
return 0;
}
写时复制copy on write
如果多个进程要读取它们自己的那部分资源的副本,那么复制是不必要的。
每个进程只要保存一个指向这个资源的指针就可以了。
如果一个进程要修改自己的那份资源的“副本”,那么就会复制那份资源。这就是写时复制的含义。
孤儿进程和僵尸进程
如果父进程先退出,子进程还没退出,则子进程被称为孤儿进程,如果父亲进程先结束,子进程会托孤给1号init进程。(注:任何一个进程都必须有父进程)
如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵进程。
fork父子进程共享文件
#include<stdio.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argv,char *agrc[])
{
pid_t pid;
int fd;
fd = open("local.txt", O_WRONLY);
pid = fork();
if (pid == 0)
{
printf("this is child pid:%d ppid:%d \n", getpid(), getppid());
write(fd, "child\n", 6);
}
else if (pid > 0)
{
printf("this is parent pid:%d ppid:%d \n", getpid(), getppid());
write(fd, "parent\n", 7);
}
close(fd);
return 0;
}

这种共享文件的方式使父子进程对同一文件使用了一个文件位移量。对于以下情况:一个进程fork了一个子进程,然后等待子进程终止。假定,作为普通处理的一部分,父、子进程都向标准输出执行写操作。如果父进程使其标准输出重定向(很可能是由shell实现的),那么子进程写到该标准输出时,他将更新与父进程共享的该文件的位移量。在我们所考虑的例子中,当父进程等待子进程时,子进程写到标准输出;而在子进程终止后,父进程也写入到标准输出上,并且知道其输出会添加在子进程所写数据之后。如果父、子进程不共享同一文件位移量,这种形式的交互就很难实现。

fork典型应用场景
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int arg,char *argc[])
{
int i;
pid_t pid;
for(i=0; i<5; i++)
{
pid=fork();
if(pid>0)
{
printf("pid is %d,the pid_t value is %d\n",getpid(),pid);
printf("current parent process is done\n");
exit(0);
}
}
return 0;
}
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
int main(int arg,char *argc[])
{
int i;
pid_t pid;
for(i=0; i<10; i++)
{
pid=fork();
if(pid==0)
{
printf("the num%d child process is running\n",i+1);
exit(0);
}
}
return 0;
}