当前位置: 首页 > news >正文

详解linux中的fork函数

在 Linux 系统中,fork 是一个非常重要的系统调用,用于创建新进程,以下为你详细介绍:

          在这里我们需要特别明确的一点就是“调用一次,返回两次”
   正在执行的代码程序遇到fork函数会发出俩个,一个为父,一个为子,父的fork和子的fork有不同的返回值

 

  • 基本概念:fork 函数可以创建一个新的进程,称为子进程,而调用 fork 的进程则为父进程。子进程是父进程的副本,它会获得父进程数据空间、堆、栈等资源的副本,但父子进程拥有相互独立的地址空间。这意味着,虽然子进程复制了父进程的这些资源,但后续父子进程对这些资源的修改不会相互影响 。同时,父子进程会共享父进程中打开的文件描述符,即父、子进程中相同编号的文件描述符在内核中指向同一个 file 结构体,file 结构体的引用计数会增加。
  • 函数原型及返回值
    • 函数原型pid_t fork(void) ,该函数不需要传入参数。其中pid_t本质是int类型,在#include <sys/types.h>中定义,同时还需要包含头文件#include <unistd.h> 。
    • 返回值:具有 “调用一次,返回两次” 的特点。如果创建子进程成功,在父进程中,fork 返回新创建子进程的进程 ID(大于 0 的整数);在子进程中,fork 返回 0。如果创建子进程失败,fork 返回 - 1,此时可以通过errno查看具体的错误原因,比如达到进程数上限(EAGAIN) 、没有足够空间给新进程分配(ENOMEM)等。
  • 工作机制 :当父进程调用 fork 函数时,操作系统会复制当前父进程的状态信息,包括代码段、数据段、堆栈指针、寄存器值等。子进程从 fork 函数调用之后的下一条指令开始执行。不过,在不同的 Linux 系统下,无法确定 fork 之后是子进程先运行还是父进程先运行,这取决于系统的调度策略。
  • 实际应用场景 :
    • 多任务处理:例如网络服务器程序中,父进程可以负责监听客户端的连接请求,每当有新的请求到来,就调用 fork 创建子进程,由子进程来处理具体的客户端请求,而父进程继续监听新的连接,这样可以实现并发处理多个客户端请求 。
    • 执行不同程序 :shell 在执行命令时会用到 fork。子进程从 fork 返回后,可以调用 exec 系列函数,用新的程序替换当前进程的内存映像,从而执行不同的程序。在 UNIX 系统中,fork 和 exec 是分开的,这使得子进程在 fork 和 exec 之间有机会更改自身属性,如进行 I/O 重定向、修改用户 ID、安排信号处理等操作。
  • 使用注意事项
    • 资源开销:fork 会复制父进程的大量资源,这在父进程资源较多或需要创建大量子进程的情况下,可能会带来较大的性能开销。为减少不必要的资源复制,通常在 fork 之后,子进程会调用 exec 系列函数,用新的程序替换自身,这样原来复制的资源就会被释放 。
    • 竞态条件:由于父子进程是异步执行的,它们可能会同时访问和修改共享资源(如共享文件等),从而导致竞态条件,造成数据不一致等问题。为避免这类问题,需要使用进程间通信(IPC)机制,如管道(pipe)、消息队列(message queue)、信号量(semaphore)等 来进行同步和数据交互。
    • 错误处理:调用 fork 后,一定要检查其返回值,以处理创建子进程失败的情况,避免程序出现未预期的行为。

下面是一个简单的 fork 示例代码:

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

int main() {
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork error");
        exit(EXIT_FAILURE);
    } else if (pid == 0) {
        printf("我是子进程,我的进程ID是 %d\n", getpid());
        exit(EXIT_SUCCESS);
    } else {
        printf("我是父进程,子进程的进程ID是 %d,我的进程ID是 %d\n", pid, getpid());
    }
    return 0;
}

在上述代码中,通过 fork 创建子进程,然后根据 fork 的返回值判断当前是父进程还是子进程,并分别执行相应的代码块。

相关文章:

  • 探索AIGC未来:通义万相2.1与蓝耘智算平台的完美结合释放AI生产力
  • 2024爱分析·央国企数字化应用实践报告
  • taosd 写入与查询场景下压缩解压及加密解密的 CPU 占用分析
  • ORACLE导入导出
  • 【网络协议详解】——isis技术(学习笔记)
  • 搭建BOA服务器
  • Note 12 R pro (MIUI 14.0.10) magisk方式 获取root教程
  • protobuf、protoc、proto这3个什么关系
  • springboot012基于springboot的社区团购系统设计与实现(源码+包运行+LW+技术指导)
  • TensorFlow的pb模型
  • AcWing 5539. 牛奶交换 整体思维+破环成链思想
  • IO多路复用(epoll)/数据库(sqlite)
  • cocos creator 混合模式编辑器与运行不一致的问题
  • TypeError: JSON.stringify cannot serialize cyclic structures
  • anolis8.9-k8s1.32-node-二进制部署
  • FreeRTOS第15篇:FreeRTOS链表实现细节03_List_t与ListItem_t的奥秘
  • Python程序的「加密」:Cython编译
  • 深度体验阿里云操作系统控制台
  • Process-based Self-Rewarding Language Models 论文简介
  • 项目管理工具 Maven
  • 站长工具最近查询/网站备案查询官网
  • 如何做网站宣传自己/网页设计模板素材图片
  • 彩票网站自己可以做吗/如何实施网站推广
  • 电子商务专业网站设计/韩国热搜榜
  • 用html做的零食网站/网站优化排名易下拉霸屏
  • 美发网站源码/深圳网站设计三把火