一个例子简单理解linux系统调用fork的作用

发布时间:2023年12月17日

不知道大家是否和我一样,很早就听说了fork系统调用的鼎鼎大名,但是很长一段时间都不明白这个系统调用的作用,只是云里雾里的听说这个系统调用可以将一个进程变成两个进程。

那么这个函数究竟是怎么发生作用呢,这个问题的答案我是在学习了安卓系统中进程启动方式后突然明白的。

我们先来说说安卓系统的应用启动方式。我们知道,安卓系统中第一个被加载起来的进程是zygote进程,该进程负责孵化其他的java相关的进程,比如system_server和各种的APP。

这个过程可以简单描述如下

  1. zygote进程通过socket连接接收system_server发过来的创建新的应用进程的指令
  2. zygote进程进行fork系统调用,被fork出来的进程关闭socket server然后去执行相应的应用代码

这个fork的意思是,刚刚调用的时候两个进程的所有东西都是一致的。那么如何区分哪个是被fork出来的进程,哪个是原先的进程呢?

答案就是通过fork()的返回值来进行判断,函数调用成功后,会返回两次,在父进程中返回子进程的 ID,在子进程中返回 0。如果函数调用失败,则返回-1。

使用fork()的一个简单例子如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {
    pid_t pid;

    // 调用 fork 函数创建子进程
    pid = fork();

    if (pid == -1) {
        // fork 失败,打印错误信息并退出
        perror("fork failed");
        exit(1);
    } else if (pid == 0) {
        // 在子进程中,打印子进程 ID 和 "Child process"
        printf("Child process, pid: %d\n", getpid());
    } else {
        // 在父进程中,打印子进程 ID 和 "Parent process"
        printf("Parent process, pid of child: %d\n", pid);
    }

    // 等待子进程结束
    wait(NULL);

    return 0;
}

好了,说了那么多,我们现在用一个简单的例子来解释一下为什么要用fork,或者说用fork可以达到什么样的效果。

想象这样一种场景,就是你要开始写开题报告了,但是你又不想从头开始一个字一个字写,因为开题报告是有格式要求的,为了可以专注于你开题报告的内容,于是你决定向你的师兄要了他的开题报告。师兄很快就将他珍藏多年的开题报告发给了你,你也开心地下载到了硬盘里。这个时候你就面临一个问题,如何合理地使用这份开题报告呢?

如果是我,那么我一定会把开题报告复制一份,然后在名称带有副本的那一份开题报告中进行修修补补变成我自己的开题报告。

区分这两份开题报告也很简单,原先的那份文件名叫“开题报告.docx”,而被复制出来的那份文件名叫“开题报告 - 副本.docx”。在刚刚复制好的原始状态,这两份报告的内容是一样的,这就意味着你不需要在意格式的调整,而只需要专注于内容的编写就行了。

其实以上就是fork的工作流程,不知道大家对于fork的工作原理的理解有没有加深,反正当时我想到这个例子的时候是彻底搞懂了fork的工作原理,不得不说这个系统调用的设计还是非常巧妙的,哈哈。

文章来源:https://blog.csdn.net/haohulala/article/details/135048504
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。