Linux的Fork笔记

Linux的Fork笔记

fork()函数虽然用法比较固定,但是其若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID。对于fork自己还是有一些不理解的地方,特用该文档帮助自己理清一下思绪。

fork的作用

在Linux机器中输入命令info fork可以得到关于fork的描述大致如下:

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 unmappings (mun‐map(2)) performed by one of the processes do not affect the other.

即一个现有进程调用fork函数可以创建一个新进程,新进程叫做子进程,fork函数特点为调用一次返回两次

子进程是父进程的副本,子进程拥有父进程的数据空间、堆、栈等资源的副本,父子进程共享的存储空间只有代码段

fork函数所需的头文件:

#include <sys/types.h>
#include <unistd.h>

fork返回值:

  • 若成功创建一个子进程,对于父进程来说返回子进程ID;
  • 若成功创建一个子进程,对于子进程来说返回子进程ID;
  • 返回-1即创建失败;

简单例子:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main() {

    int pid = 1;
    pid = fork();

    if (pid == 0)
        printf("child process\n");
    else if (pid > 0)
        printf("parent process\n");
    else
        printf("fork failed!]n");

    printf("test\n");
    return 0;
}

// 输出结果
parent process
test
child process
test

子进程在fork之后开始向下执行,而不会从头开始执行,fork把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同;

每个进程都有一个唯一的进程标识符process ID,可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值;

fork的原理

简而言之,当一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。

Linux 的fork() 是通过写时拷贝 copy-on-write)实现的,写时拷贝是一种可以推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是先让父子进程共享同一个地址空间只有子进程在需要写入的时候才会复制地址空间,从而使各个进行拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,以只读方式共享地址空间,地址拷贝可以参考下图。

多层fork问题:

#include <unistd.h>
#include <stdio.h>
int main(void)
{
   int i=0;
   for(i=0;i<2;i++){
       pid_t fpid=fork();
       if(fpid==0)
           printf("son\n");
       else
           printf("father\n");
   }
   return 0;
}

问调用了几次printf函数?

posted @ 2022-09-20 17:26  醉曦  阅读(83)  评论(0编辑  收藏  举报