Linux 创建进程 fork()、vfork() 与进程管理

news/2025/2/10 9:01:52/

Linux 创建进程 fork、vfork、进程管理

    • 一、Linux的0号、1号、2号进程
    • 二、Linux的进程标识
    • 三、fork() 函数
      • 1、基本概念
      • 2、函数特点
      • 3、用法以及应用场景
        • (1)父子进程执行不同的代码
        • (2)进程执行另一个程序
      • 4、工作原理
    • 四、vfork() 函数
      • 1、基本概念
      • 2、函数特点
      • 3、用法以及应用场景
      • 4、工作原理
    • 五、fork 与 vfork 的比较
    • 六、父子进程共享文件的场景
      • 示例:父子进程共享文件描述符

在这里插入图片描述

在Linux操作系统中,进程是资源分配的基本单位。进程的创建是系统正常运行的重要组成部分。通过理解进程创建的机制,开发者能够更高效地控制系统的资源和多任务处理

一、Linux的0号、1号、2号进程

在Linux操作系统中,进程以树状结构组织。最重要的进程包括0号、1号和2号进程,它们具有特殊的意义:

  • 0号进程(系统进程):也被称为swapperidle进程,是所有进程的祖先,负责初始化系统的基本工作。
  • 1号进程(systemd):是系统的初始化进程,负责系统的启动、硬件初始化以及进程管理。它是所有其他进程的父进程。
  • 2号进程(kthreadd):是内核线程的管理者,负责内核级线程的创建、管理和调度。

这些进程在系统启动时就已经存在,确保了系统的正常运行。

二、Linux的进程标识

每个进程在Linux系统中都有一个唯一的进程标识符(PID)。进程标识符用于标识和管理进程。除了PID外,还有一些相关的进程标识符:

  • PPID(父进程ID):指向父进程的PID。
  • PGID(进程组ID):用于管理进程组,多个进程可以组成一个进程组。
  • SID(会话ID):代表一组进程的会话标识,通常与终端的会话关联。

在Linux中,进程的创建通常使用fork()系统调用来实现。

三、fork() 函数

1、基本概念

fork()是Unix/Linux系统中用于创建新进程的一个系统调用。调用fork()时,当前进程(父进程)会复制一份新的进程(子进程)。子进程将继承父进程的大部分资源(如文件描述符、环境变量等)。

2、函数特点

  • 进程复制fork()会复制父进程的虚拟地址空间,但父子进程的实际物理地址不同。
  • 内存副本:父进程的堆栈空间和数据空间会被复制到子进程中,父子进程的数据并不共享。
  • 顺序不确定fork()调用后,父子进程的执行顺序是不可预知的。父进程可能先执行,也可能子进程先执行。

3、用法以及应用场景

(1)父子进程执行不同的代码

在调用fork()后,父子进程各自从fork()返回的位置继续执行代码。父进程和子进程通常执行不同的操作。

#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {// 错误处理perror("fork failed");return 1;}if (pid == 0) {// 子进程执行printf("This is the child process. PID: %d\n", getpid());} else {// 父进程执行printf("This is the parent process. PID: %d\n", getpid());}return 0;
}

运行该代码时,父子进程会并行执行,打印各自的进程ID。

(2)进程执行另一个程序

父进程可以通过fork()创建子进程,然后使用exec()系列函数来让子进程执行不同的程序。这在处理多任务时非常常见。

#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = fork();if (pid < 0) {perror("fork failed");return 1;}if (pid == 0) {// 子进程执行新的程序execlp("/bin/ls", "ls", "-l", NULL);// 如果 execlp 调用成功,下面的代码不会执行perror("execlp failed");} else {printf("Parent process is running. PID: %d\n", getpid());}return 0;
}

在此示例中,子进程通过execlp()调用执行ls命令。

4、工作原理

fork()系统调用的工作原理基于复制父进程的虚拟内存空间并为子进程创建一个新的进程。虽然父子进程的虚拟地址空间相同,但它们是不同的物理地址。

四、vfork() 函数

1、基本概念

vfork()函数和fork()类似,也用于创建子进程。但是,vfork()不会复制父进程的虚拟内存,而是让父进程暂时停止执行,直到子进程调用exec()_exit()。这种行为使得vfork()fork()更高效,尤其在子进程即将调用exec()时。

2、函数特点

  • 共享内存空间vfork()创建的子进程共享父进程的地址空间,直到子进程调用exec()_exit()
  • 父进程暂停:父进程会暂停执行,直到子进程完成某些操作(通常是执行新程序或退出)。

3、用法以及应用场景

vfork()通常用于需要子进程快速调用exec()的场景,能够提高效率。

#include <stdio.h>
#include <unistd.h>int main() {pid_t pid = vfork();if (pid < 0) {perror("vfork failed");return 1;}if (pid == 0) {// 子进程执行execlp("/bin/ls", "ls", "-l", NULL);perror("execlp failed");} else {printf("Parent process is waiting. PID: %d\n", getpid());}return 0;
}

4、工作原理

vfork()会让子进程与父进程共享内存空间,父进程在子进程调用exec()_exit()之前会被挂起,从而避免了不必要的内存复制操作。

五、fork 与 vfork 的比较

特性fork()vfork()
内存复制复制父进程的内存子进程和父进程共享内存空间
父进程执行父子进程并行执行父进程暂停,直到子进程执行完毕
性能较低(内存复制开销)较高(减少内存复制,提高效率)
适用场景适用于父子进程都需要独立运行的情况适用于子进程会调用exec()的情况

六、父子进程共享文件的场景

在Linux中,父进程和子进程共享文件描述符,这意味着它们对同一个文件的操作可能相互影响。例如,如果父进程和子进程都操作同一个文件描述符,文件的偏移量可能会改变,从而导致输出混合。为了避免这种情况,必须显式地同步文件操作。

示例:父子进程共享文件描述符

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>int main() {int fd = open("test.txt", O_RDWR | O_CREAT, 0644);if (fd == -1) {perror("File open failed");return 1;}pid_t pid = fork();if (pid < 0) {perror("fork failed");return 1;}if (pid == 0) {// 子进程写入文件write(fd, "Hello from child\n", 17);} else {// 父进程写入文件write(fd, "Hello from parent\n", 18);}close(fd);return 0;
}

在这个示例中,父进程和子进程共享fd文件描述符。如果没有适当的同步机制,写入可能会交替进行,从而产生不一致的结果。


http://www.ppmy.cn/news/1570815.html

相关文章

个人毕业设计--基于HarmonyOS的旅行助手APP的设计与实现(挖坑)

在行业混了短短几年&#xff0c;却总感觉越混越迷茫&#xff0c;趁着还有心情学习&#xff0c;把当初API9 的毕业设计项目改成API13的项目。先占个坑&#xff0c;把当初毕业设计的文案搬过来 摘要&#xff1a;HarmonyOS&#xff08;鸿蒙系统&#xff09;是华为公司推出的面向全…

Spring Boot整合DeepSeek实现AI对话

本篇博文会分为DeepSeek开放平台上的API&#xff0c;以及本地私有化部署DeepSeek R1模型两种方式来整合使用&#xff0c;本地化私有部署可以参考这篇博文&#xff1a;DeepSeek介绍及使用ollama本地化部署DeepSeek-R1大模型 Spring AI Spring AI 是由 Spring&#xff08;一个广…

我们来学人工智能 -- 将Ollama已下载的模型从C盘迁出

题记 未配置OLLAMA_MODELS系统变量导致模型下载到了C盘 迁移步骤 退出ollama 配置OLLAMA_MODELS系统变量 OLLAMA_MODELS&#xff1a;D:\ollama\models 直接将C盘下的models目录剪切到指定目录 检查 cmd命令窗口退出重新打开

【CPP】CPP经典面试题

文章目录 引言1. C 基础1.1 C 中的 const 关键字1.2 C 中的 static 关键字 2. 内存管理2.1 C 中的 new 和 delete2.2 内存泄漏 3. 面向对象编程3.1 继承和多态3.2 多重继承 4. 模板和泛型编程4.1 函数模板4.2 类模板 5. STL 和标准库5.1 容器5.2 迭代器 6. 高级特性6.1 移动语义…

基于深度学习的人工智能量化衰老模型构建与全流程应用研究

一、引言 1.1 研究背景与意义 1.1.1 人口老龄化现状与挑战 人口老龄化是当今全球面临的重要社会趋势之一,其发展态势迅猛且影响深远。根据联合国的相关数据,1980 年,全球 65 岁及以上人口数量仅为 2.6 亿,到 2021 年,这一数字已翻番,达到 7.61 亿,而预计到 2050 年,…

基于html和vue.js以及其他编程技术打造一个仿京东购物网站平台

效果展示 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>仿京东商城</title><link re…

【高级架构师】计算机网络基础:第二章 计算机网络体系结构(下)

文章目录 第二章 计算机网络体系结构2.5 运输层2.5.1 运输层概述2.5.2 端口号2.5.3 传输控制协议TCP2.5.4 TCP可靠传输的实现2.5.5 用户数据报协议UDP2.5.6 TCP和UDP的区别 2.6 wireshark2.6.1 wireshark的安装2.6.2 界面介绍2.6.3 wireshark过滤器2.6.4 使用wireshark分析TCP三…

知识库升级新思路:用生成式AI打造智能知识助手

在当今信息爆炸的时代&#xff0c;企业和组织面临着海量数据的处理和管理挑战。知识库管理系统&#xff08;Knowledge Base Management System, KBMS&#xff09;作为一种有效的信息管理工具&#xff0c;帮助企业存储、组织和检索知识。然而&#xff0c;传统的知识库系统往往依…