linux--------------进程控制(下)

一、进程等待

1.1 进程等待必要性

  • 子进程退出后,若父进程不管不顾,可能会产生 “僵尸进程”,进而造成内存泄漏。
  • 进程一旦变为僵尸状态,即使使用 kill -9 也无法将其杀死,因为无法杀死一个已死的进程。
  • 父进程需要了解子进程的任务完成情况,比如子进程运行结束后结果是否正确,是否正常退出。
  • 父进程通过进程等待的方式,回收子进程资源并获取其退出信息。

1.2 进程等待的方法

wait() 函数

wait() 函数用于阻塞等待子进程的结束,并回收其资源。以下是一个简单的示例代码:

#include <sys/wait.h>
#include <stdio.h>int main() {pid_t child_pid = fork();if (child_pid == 0) {// 子进程执行任务exit(42);  // 子进程退出码42} else {int status;pid_t terminated_pid = wait(&status);  // 阻塞等待if (WIFEXITED(status)) {printf("子进程 %d 退出码: %d\n", terminated_pid, WEXITSTATUS(status));}}return 0;
}
waitpid() 函数

waitpid() 函数的原型为 pid_t waitpid(pid_t pid, int *status, int options);,它可以更灵活地等待指定子进程的结束。

1.3 获取子进程 status

wait 和 waitpid 都有一个 status 参数,这是一个输出型参数,由操作系统填充。若传递 NULL,表示不关心子进程的退出状态信息;否则,操作系统会根据该参数将子进程的退出信息反馈给父进程。

status 不能简单地当作整型来看待,可将其视为位图,具体细节可参考下面的图片(只研究 status 低 16 比特位):

状态位说明
低8位(0-7)子进程退出码 (正常终止时有效)
第8位(8-15)信号编号 (被信号终止时有效)
其他标志位通过宏检测状态类型(如WIFEXITED)

1.4 阻塞和非阻塞

核心结论
  • 本质区别

    • 阻塞(Blocking):调用者线程暂停执行,直到操作完成(如数据到达、资源就绪)。

    • 非阻塞(Non-blocking):调用立即返回,无论操作是否完成,需通过轮询或事件通知获取结果。

  • 选择依据

    • 阻塞:适合简单逻辑、单任务场景,代码直观但资源利用率低。

    • 非阻塞:适合高并发、实时响应需求,需配合多路复用(如epoll)或异步通知(如回调)

深度解析
运行机制对比
特性阻塞模式非阻塞模式
线程状态挂起(Sleeping)持续运行(Running)
CPU 占用低(等待时不消耗 CPU)高(需轮询检查状态)
响应延迟操作完成后立即响应需主动检测或等待通知
代码复杂度低(线性执行)高(需处理中间状态和错误码)
典型应用场景

以下是阻塞和非阻塞模式的典型应用代码示例:

阻塞模式示例

#include <stdio.h>
#include <fcntl.h>int main() {int fd = open("file.txt", O_RDONLY);  char buf[1024];  read(fd, buf, sizeof(buf));  // 阻塞直到数据就绪  printf("Data: %s\n", buf);  return 0;
}

非阻塞模式示例

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>#define BUFFER_SIZE 1024int main() {int sockfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);  struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_port = htons(8080);server_addr.sin_addr.s_addr = INADDR_ANY;connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));  char data[BUFFER_SIZE] = "Hello, Server!";int len = strlen(data);while (1) {  if (send(sockfd, data, len, MSG_DONTWAIT) == -1) {  if (errno == EAGAIN) {  usleep(1000);  // 数据未就绪,短暂等待后重试  continue;  }  }  break;  }  close(sockfd);return 0;
}

二、进程程序替换

2.1 替换原理

使用 fork 创建子进程后,子进程执行的是与父进程相同的程序(但可能执行不同的代码分支)。若子进程想执行一个全新的程序,可通过进程的程序替换来实现。当进程调用一种 exec 函数时,该进程的用户空间代码和数据会完全被新程序替换,并从新程序的启动例程开始执行。调用 exec 并不会创建新进程,因此调用前后该进程的 ID 不会改变。

2.2 替换函数

函数名参数传递方式PATH 搜索环境变量典型用途
execl参数列表(可变参数)继承当前环境已知绝对路径的固定参数调用
execv参数数组(char *[]继承当前环境动态构建参数的固定路径调用
execlp参数列表继承当前环境执行 PATH 中的命令(如 Shell)
execvp参数数组继承当前环境动态执行 PATH 中的命令
execle参数列表自定义环境变量需严格控制环境的场景
execvpe参数数组自定义环境变量动态参数 + 自定义环境

2.3 函数解释

这些函数如果调⽤成功则加载新的程序从启动代码开始执⾏,不再返回。
如果调⽤出错则返回-1
所以exec函数只有出错的返回值⽽没有成功的返回值

2.4 命名理解

  • l(list):表示参数采用列表形式。
  • v(vector):参数使用数组。
  • p(path):有 p 则自动搜索环境变量 PATH
  • e(env):表示自己维护环境变量。

以下是调用示例:

#include <unistd.h>
#include <stdio.h>int main() {char *const argv[] = {"ps", "-ef", NULL};char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};execl("/bin/ps", "ps", "-ef", NULL);// 带 p 的,可以使用环境变量 PATH,无需写全路径execlp("ps", "ps", "-ef", NULL);// 带 e 的,需要自己组装环境变量execle("ps", "ps", "-ef", NULL, envp);execv("/bin/ps", argv);// 带 p 的,可以使用环境变量 PATH,无需写全路径execvp("ps", argv);// 带 e 的,需要自己组装环境变量execve("/bin/ps", argv, envp);// 如果 exec 调用失败,会执行到这里perror("exec 调用失败");return 1;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76119.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 中跑faster-whisper 教程(1050显卡)

之前我本地机器运行faster-whisper 会报错类似 Could not load library libcudnn_ops_infer.so.8github 上也有类似的情况 &#xff1a;https://github.com/SYSTRAN/faster-whisper/issues/516#issuecomment-2785038635 缺少.so.8 文件&#xff0c;我通过以下方式&#xff0c;…

人大金仓数据库dum文件进行备份数据和恢复数据

逻辑备份命令: sys_dump -U SYSTEM -d problem_dev -Fc -f /db_backup/kingbase/dump/problem_dev/problem_dev20240329.dmp用户:SYSTEM 数据库名:problem_dev 格式:自定义格式(-Fc) 输出文件:/db_backup/kingbase/dump/problem_dev/problem_dev20240329.dmp sys_dump…

Java的Selenium元素定位-xpath

xpath其实就是一个path(路径)&#xff0c;一个描述页面元素位置信息的路径&#xff0c;相当于元素的坐标xpath基于XML文档树状结构&#xff0c;是XML路径语言&#xff0c;用来查询xml文档中的节点。 绝对定位 从根开始找--/(根目录)/html/body/div[2]/div/form/div[5]/button缺…

python-Leetcode 65.搜索旋转排序数组

题目&#xff1a; 整数数组nums按升序排列&#xff0c;数组中的值互不相同 在传递给函数之前&#xff0c;nums在预先未知的某个小标K上进行了旋转&#xff0c;使数组变为[nums[k], nums[k1], ..., nums[n-1], nums[0], nums[1], ..., nums[k-1]]&#xff0c;小标从0开始计数。…

学透Spring Boot — 010. 单元测试和Spring Test

系列文章目录 这是CSDN postnull 博客《学透Spring Boot》系列的一篇&#xff0c;更多文章请移步&#xff1a;Postnull - 学透Spring Boot系列文章 文章目录 系列文章目录前言1. 基本概念UT 单元测试TDD 测试驱动开发UT测试框架Mock框架 3. Spring Test为什么要用Spring Test引…

Chrome 135 版本新特性

Chrome 135 版本新特性 一、Chrome 135 版本浏览器更新 ** 1. 第三方托管账户注册迁移到 OIDC 授权码流程** Chrome 135 将账户注册的登录页面从营销网站迁移到动态网站&#xff0c;同时也将 OpenID Connect (OIDC) 的隐式流程迁移到授权码流程。这样做的目的是进一步提升第…

Docker Swarm集群搭建与管理全攻略

文章目录 一、节点准备二、初始化 manager 节点三、管理 swarm 集群中的 worker 节点1、添加 worker 节点2、查看 worker 节点3、删除 worker 节点 四、管理 swarm 集群服务1、创建服务2、查看服务3、删除服务 五、管理 swarm 节点服务1、节点标签管理2、创建服务3、查看服务4、…

离线语音识别 ( 小语种国家都支持)可定制词组

1产品介绍 离线语音模组采用神经网络算法&#xff0c;支持语音识别、自学习等功能。运用此模组将 AI 技 术赋能产品&#xff0c;升级改造出语音操控的智能硬件 ( 例如风扇、台灯、空调、马桶、按摩椅、运 动相机、行车记录仪等 ) 。支持全球多种语言识别&#xff0c;如中文…

Docker与VNC的使用

https://hub.docker.com/r/dorowu/ubuntu-desktop-lxde-vnc 下载nvc 客户端 https://downloads.realvnc.com/download/file/viewer.files/VNC-Viewer-7.12.0-Windows.exe 服务端 docker pull dorowu/ubuntu-desktop-lxde-vnc#下载成功 docker pull dorowu/ubuntu-desktop-l…

Linux系统学习Day0——了解和熟悉Linux系统的远程终端登录和数据传输

一、Windows系统与Linux系统虚拟机通过桥接进行网络连接 &#xff08;一&#xff09;桥接模式 桥接模式是虚拟机网络连接的一种常见方式&#xff0c;其核心原理是通过虚拟网卡将Linux虚拟机与宿主机的物理网卡建立桥接关系&#xff0c;使虚拟机能够直接接入物理网络。在该模式…

【开题报告+论文+源码】基于springboot的农贸菜市场租位管理系统的设计与实现

项目背景与意义 随着信息技术的快速发展和普及&#xff0c;信息化管理已成为各行业提升运营效率和服务质量的重要手段。农贸菜市场作为城市生活的重要组成部分&#xff0c;其管理效率和服务水平直接关系到市民的日常生活体验。传统的农贸菜市场租位管理方式往往存在信息不对称、…

Codecademy—— 交互式编程学习的乐园

一、网站概述 Codecademy 是一家美国在线学习编程知识的网站&#xff0c;它为编程学习者提供了一种全新的学习方式。在如今众多的编程学习平台中&#xff0c;Codecademy 凭借其独特的优势脱颖而出&#xff0c;吸引了全球数百万用户。其目标是帮助更多人轻松学习编程&#xff0…

WEB安全--XSS--DOM破坏

一、前言 继XSS基础篇后&#xff0c;我们知道了三种类型的XSS&#xff0c;这篇文章主要针对DOM型XSS的原理进行深入解析。 二、DOM型XSS原理 2.1、什么是DOM 以一个形象的比喻&#xff1a; 网页就像是一座房子&#xff0c;而 **DOM** 就是这座房子的“蓝图”或者“结构图”。…

Linux系统远程操作和程序编译

Linux系统远程操作和程序编译 了解和熟悉Linux系统的远程终端登录、远程图形桌面访问、 X图形窗口访问和FTP文件传输操作 网络设置和用户创建&#xff1a; 在虚拟机Ubuntu系统中&#xff0c;将网络连接设置为“桥接模式”&#xff0c;并配置好IP和网关。确保其他Windows 10系统…

linux开发环境

1.虚拟机环境搭建 在 Ubuntu 系统中&#xff0c;打开&#xff08;如图中显示的窗口 &#xff09;常见快捷键有&#xff1a; Ctrl Alt T&#xff1a;这是最常用的打开终端的快捷键组合 &#xff0c;按下后会快速弹出一个新的终端窗口。 在 VMware 虚拟机环境中&#xff0c;若…

蓝桥·20264-祝福语--找连续字串的长度

#include <iostream> using namespace std; int main() {// 请在此输入您的代码//最小字典序&#xff0c;一定是全a&#xff0c;找s的最长字串a,结果就是该字串长度加1&#xff08;t不能是s的子串&#xff09;//所以这道题就变成了&#xff0c;找s中字串a出现的长度strin…

7.第二阶段x64游戏实战-分析人物属性

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;6.第二阶段x64游戏实战-分析人物状态 首先打开人物面板&#xff0c;查看人物的…

数组的常见算法一

注: 本文来自尚硅谷-宋红康仅用来学习备份 6.1 数值型数组特征值统计 这里的特征值涉及到&#xff1a;平均值、最大值、最小值、总和等 **举例1&#xff1a;**数组统计&#xff1a;求总和、均值 public class TestArrayElementSum {public static void main(String[] args)…

汽车电子笔记之:基于Tasking编译器怎么制作库文件并将库文件集成进工程释放

目录 1、概述 2、库工程创建、使用步骤 2.1、选择对应的MCU型号及空工程 2.2、选择需要封装的代码 2.3、将需要封装的代码复制到库工程 2.4、整理库工程工程属性 2.5、预留不生成库的.c源文件 2.6、编译生成.a文件 2.7、将.a集成进工程 2.7.1、创建释放给客户的工程 …

[ctfshow web入门] web29

前置知识 eval: 把字符串按照 PHP 代码来执行&#xff0c;例如eval(“echo 1;”);这个函数拥有回显 system&#xff1a;使php程序执行系统命令&#xff0c;例如&#xff0c;system(“ls”);就是查看当前目录&#xff0c;这个拥有回显 preg_match&#xff1a;查找字符串是否匹配…