6.进程的使用方式

embedded/2025/2/4 4:26:54/

6.进程的使用方式

      • **1. 父子进程的关系**
      • **2. 进程的终止**
      • **3. 僵尸进程和孤儿进程**
      • **4. 进程资源回收**
      • **5. exec 函数族**
      • **6. system 函数**
      • **7. 练习与作业**
      • **8. 进程的退出状态**
      • **9. 进程的清理函数**
      • **10. 总结**


1. 父子进程的关系

  • 子进程是父进程的副本
    • 子进程复制父进程的数据段、堆、栈,共享正文段(代码段)。
    • 子进程从fork之后开始执行,父子进程的执行顺序不确定。
  • 区别
    • fork的返回值不同:
      • 父进程中返回子进程的PID。
      • 子进程中返回0。
    • PID不同:子进程拥有独立的进程ID。

2. 进程的终止

  • 正常终止
    1. main函数中return
    2. exit():C库函数,刷新缓冲区,关闭所有流,执行清理函数(如atexit注册的函数)。
    3. _exit() / _Exit():系统调用,直接终止进程,不刷新缓冲区,不执行清理函数。
  • 异常终止
    4. 主线程退出。
    5. 主线程调用pthread_exit
    6. abort():触发SIGABRT信号终止进程。
    7. 收到信号(如kill命令发送的信号)。
    8. 最后一个线程被pthread_cancel取消。

3. 僵尸进程和孤儿进程

  • 僵尸进程
    • 进程已终止,但其资源未被父进程回收。
    • 父进程可以通过waitwaitpid回收子进程资源。
  • 孤儿进程
    • 父进程先于子进程终止,子进程被init进程(PID=1)接管。
    • 孤儿进程不会成为僵尸进程。

4. 进程资源回收

  • wait
    • 函数原型:pid_t wait(int *status);
    • 功能:阻塞等待任意子进程退出,并回收其资源。
    • 参数:status用于存储子进程的退出状态。
    • 返回值:成功返回子进程PID,失败返回-1。
  • waitpid
    • 函数原型:pid_t waitpid(pid_t pid, int *status, int options);
    • 功能:回收指定子进程的资源。
    • 参数:
      • pid:指定要回收的子进程PID。
      • status:存储子进程的退出状态。
      • options:选项(如WNOHANG表示非阻塞模式)。
    • 返回值:成功返回子进程PID,失败返回-1。

5. exec 函数族

  • 功能:用新程序替换当前进程的地址空间,从新程序的启动例程开始执行。
  • 常见函数
    • execl:以参数列表形式传递参数。
    • execv:以参数数组形式传递参数。
    • execlp:在PATH环境变量中查找可执行文件。
    • execvp:在PATH环境变量中查找可执行文件,并以参数数组形式传递参数。
    • execle:传递环境变量。
    • execve:系统调用,传递参数数组和环境变量。
  • 特点
    • 调用成功时不返回,调用失败时返回-1。
    • 不创建新进程,进程ID不变。

6. system 函数

  • 函数原型:int system(const char *command);
  • 功能:在代码中执行Shell命令。
  • 返回值:成功返回0,失败返回-1。
  • 实现原理fork + exec

7. 练习与作业

  • 练习1:设计一个多进程程序,父子进程分别向同一个文件写入数据,并标明进程ID和时间。
  • 练习2:使用waitpid函数回收指定子进程资源,并打印其退出状态。
  • 练习3:使用execlpexecvp启动ps命令,并带参数执行。
  • 作业1:设计一个多进程程序,父进程获取用户输入并写入文件,子进程读取文件并打印输出。输入quit时双方退出,确保不产生僵尸进程和孤儿进程。
  • 作业2:设计一个多进程程序,将一个大文件分割为多个子文件,并确保子文件可以合并为原始文件。

8. 进程的退出状态

  • 正常退出:通过exitreturn传递退出状态。
  • 异常退出:通过信号传递终止原因。
  • 状态回收
    • WIFEXITED(status):判断进程是否正常退出。
    • WEXITSTATUS(status):获取正常退出时的状态码。
    • WIFSIGNALED(status):判断进程是否因信号终止。
    • WTERMSIG(status):获取导致进程终止的信号编号。

9. 进程的清理函数

  • atexit
    • 函数原型:int atexit(void (*function)(void));
    • 功能:注册进程退出时执行的函数。
    • 返回值:成功返回0,失败返回非0。
  • 执行顺序atexit注册的函数按注册顺序的逆序执行。

10. 总结

  • 父子进程通过fork创建,子进程是父进程的副本。
  • 进程可以通过exit_exit、信号等方式终止。
  • 僵尸进程和孤儿进程是进程管理中的常见问题,需要通过waitwaitpid回收资源。
  • exec函数族用于替换进程的地址空间,执行新程序。
  • system函数可以方便地在代码中执行Shell命令。

http://www.ppmy.cn/embedded/159367.html

相关文章

国产之光DeepSeek架构理解与应用分析

目录 初步探索DeepSeek的设计 一、核心架构设计 二、核心原理与优化 三、关键创新点 四、典型应用场景 五、与同类模型的对比优势 六、未来演进方向 从投入行业生产的角度看 一、DeepSeek的核心功能扩展 二、机械电子工程产业中的具体案例 1. 预测性维护(Predictive…

用结构加法3ax+1预测第4点的分布

有1个点在19*19的平面上在某种力的作用下运动,轨迹为 共移动了90步,按照(0,1,2,3),(1,2,3,4),…,&…

TypeScript语言的语法糖

TypeScript语言的语法糖 TypeScript作为一种由微软开发的开源编程语言,它在JavaScript的基础上添加了一些强类型的特性,使得开发者能够更好地进行大型应用程序的构建和维护。在TypeScript中,不仅包含了静态类型、接口、枚举等强大的特性&…

Alibaba开发规范_编程规约之集合框架:最佳实践与常见陷阱

文章目录 引言1. hashCode与equals方法的覆写1.1 规则1.2 解释1.3 代码示例正例反例 2. ArrayList的subList方法2.1 规则2.2 解释2.3 代码示例正例反例 3. Map的keySet、values和entrySet方法3.1 规则3.2 解释3.3 代码示例正例反例 4. Collections类返回的不可变集合4.1 规则4.…

【实践】基于SakuraLLM的离线日文漫画及视频汉化

介绍 LLM 大型语言模型(英语:large language model,LLM),也称大语言模型,是由具有大量参数(通常数十亿个权重或更多)的人工神经网络组成的一类语言模型。在进行语言理解与分析&…

3 Flink 运行架构

3 Flink 运行架构 1. Flink 程序结构2. Flink 并行数据流3. Task 和 Operator chain4. 任务调度与执行5. 任务槽和槽共享 1. Flink 程序结构 Flink 程序的基本构建块是流和转换(请注意,Flink 的 DataSet API 中使用的 DataSet 也是内部流 )。…

react redux监测值的变化

现在想了解如何在React Redux中监测值的变化。他们之前已经讨论过使用useSelector来获取状态,但可能对如何有效监听状态变化的具体方法还不够清楚。需要回顾之前的对话,看看用户之前的需求是什么。 用户之前的问题涉及将Vue的响应式设备检测代码转换为Re…

Spring Boot 基础开发:实现 RESTful API 开发

前言 在现代 Web 开发中,RESTful API 已经成为前后端分离架构的核心。Spring Boot 提供了强大的支持,使得 RESTful API 的开发变得高效且简洁。本文将从以下几个方面详细讲解如何在 Spring Boot 中实现 RESTful API 开发: RestController 设…