1、fork函数    

头文件:

#include<unistd.h>

函数原型:

pid_t fork( void);(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)

返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

函数说明:

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。

LINUX将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。创建新进程成功后,系统中出现两个基本完全相同的进程,这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

为什么fork返回值有两个:

其实就相当于链表,进程形成了链表,父进程的fork函数返回的值指向子进程的进程id, 因为子进程没有子进程,所以其fork函数返回的值为0.


举个神奇的例子:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
  int i=0;
  for(i;i<2;i++)
  {
   pid_t id = fork();
   if(id==0)
   {
    printf("i=%d,child,pid=%d,father,pid=%d,id=%d\n",i,getpid(),getppid(),id);
   }
   else
   {
    printf("i=%d,father,pid=%d,grandfather,pid=%d,id=%d\n",i,getpid(),getppid(),id);
     sleep(1);
   }
  }
  return 0;
}

输入结果:

wKiom1doCyqxfSPUAABKFrxl3fY905.png

分析过程:


wKioL1doDtfTbDznAAHSalk_CrQ162.png

每一个进程都会printf一句相应的语句,一共产生了3个新的子进程,父进程重复打印1次,子进程重复打印一次,所以一共是打印了6句话。