当前位置 主页 > 服务器问题 > win服务器问题汇总 >

    简单掌握Linux系统中fork()函数创建子进程的用法

    栏目:win服务器问题汇总 时间:2019-11-03 17:57

    fork()函数用于从已存在的进程中创建一个新进程。新进程称为子进程,而园进程称为父进程。使用fork()函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程的上下文、代码段、进程堆栈、内存信息、打开的文件描述符、符号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等,而子进程所独有的只有它的进程号、资源使用和计时器等。

    因为子进程几乎是父进程的完全复制,所以父子两进程会运行同一个程序。这就需要用一种方式来区分它们,并使它们照此运行,否则,这两个进程不可能做不同的事。实际上是在父进程中执行fork()函数时,父进程会复制一个子进程,而且父子进程的代码从fork()函数的返回开始分别在两个地址空间中同时运行,从而使两个进程分别获得所属fork()函数的返回值,其中在父进程中的返回值是子进程的进程号,而在子进程中返回0。因此,可以通过返回值来判断该进程的父进程还是子进程。

    同时可以看出,使用fork()函数的代价是很大的,它复制了父进程中的代码段、数据段和堆栈段里的大部分内容,使得fork()函数的系统开销比较大,而且执行速度也不是很快。

    代码示例:

    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, const char * argv[]) {
      // insert code here...
      pid_t pid;
      if((pid = fork()) == 0){
        //返回0的是子进程
        printf("child pid: %d\n", getpid());
      } else {
        printf("pid: %d\n", pid);//父进程中返回子进程的pid
        printf("father pid: %d\n", getpid());
      }
    }
    
    

    打印的结果如下:

    pid: 552
    father pid: 549
    child pid: 552
    

    以下是一些注意点及总结:
    1) 之前在VS上想要用,结果发现根本没有这个头文件;因为<unistd.h>是类unix系统才有的;上面的代码在mac os上测试OK。

    2) fork()是用来创建子进程的,创建之后子进程是父进程的副本,子进程获得父进程的数据空间、堆和栈的副本,注意两者并不是共享的。父子两者仅共享代码段。这个是以前的实现,现在的话一般不会直接去复制,而是写时复制(copy-on-write)。

    3) fork()之后父子进程的执行顺序是不确定的。