Linux_进程控制

一:进程创建

fork()函数创建新进程

#include <unistd.h>
pid_t fork(void);
返回值:自进程中返回0,父进程返回子进程id,出错返回-1

进程调用fork,当控制转移到内核中的fork代码后,内核做:

1.为新进程分配一个唯一的进程标识符(PID)。复制父进程的相关信息,创建一个新的进程控制块(PCB)。指向同一块内容

2.内核不会立即复制父进程的整个地址空间,而是标记这些页面为只读,当父进程或子进程尝试写入时会触发系统错误,再由系统判断是野指针问题,还是写时拷贝,如果是写时拷贝,就新开辟空间来拷贝再修改。(为什么不直接修改?因为count++,需要原数据)

再把进行修改的进程的页表更改,并把父子进程权限恢复。(只读->可读写)

3.对父进程而言,fork返回新创建进程的PID;对子进程而言,返回0。

4.新进程加入调度队列.

二:进程终止

退出码作用:

通常,退出码为0表示进程成功执行,而非零值表示错误或异常情况。

不同的非零值可以代表不同类型的错误。(退出码也可以用自己定义的)

echo $? 

查看最近一次进程退出码

char *strerror(int errnum);

用于根据错误码返回对应的错误信息字符串。

进程终止的方式

1.main函数return 

2.exit()

3._exit()

void exit(int status);

函数用于终止进程,并可以返回一个状态码给操作系统。它定义在 <stdlib.h> 头文件中。

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

int main() {
    printf("Starting the program...\n");

    // 假设发生了错误
    if (/* some error condition */ 1) {
        printf("An error occurred. Exiting the program.\n");
        exit(1); // 以状态 1 退出
    }

    printf("Program completed successfully.\n");
    exit(0); // 以状态 0 正常退出
}

void _exit(int status);

是一个系统调用,用于立即终止进程,而不执行任何清理工作。它定义在 <unistd.h> 头文件中。

exit和_exit不同

1.exit,退出时会刷新缓冲区,而_exit不会刷新缓冲区.

2.exit:适合在程序正常结束时使用,或者在需要进行资源清理时使用。_exit通常在子进程中使用,特别是在调用 fork 后,如果子进程出现错误或者需要立即终止而不影响父进程的状态时使用。

exit 会在内部调用 _exit 来完成终止进程的操作,但在此之前会执行清理工作。因此,可以认为 exit 是对 _exit 的封装。

三:进程等待

当我们fork创建子进程,等子进程结束后会进入僵尸状态,此时就需要父进程来回收子进程。父进程可以用wait waitpid来回收子进程获取退出信息。

pid_t wait(int *status)

父进程调用wait会阻塞,直到其任一子进程终止。参数status可以用来获取子进程的退出状态。

等待成功返回子进程pid,反之-1,并设置errno

解释:int*status是位图,看低16位,8~15位代表子进程的退出码。0~7退出信号的值。

进程退出情况:

1.代码跑完,结果正确return 0

   代码跑完,结果错误return !0    返回退出码 退出信号为0

2.进程异常,(越界访问 栈溢出)系统用信号提前终止进程。  返回退出信号

进程因接收到信号而终止,它不会返回正常的退出码。

1.获取退出码

WIFEXITED(status) 来检查子进程是否正常退出,

如果子进程正常退出,则可以调用 WEXITSTATUS(status) 来获得退出码。

2.获取退出信息

 WIFSIGNALED(status) 检查子进程是否因信号而终止,

如果子进程是因为信号终止的,可以使用 WTERMSIG(status) 来获取导致终止的信号编号。

pid_t waitpid (pid_t pid, int *status, int options)

pid_t waitpid(pid_t pid, int *status, int options);
1.pid 指定等待子进程的pid,为-1等待任意子进程。为 0,则等待与调用进程相同组的任何子进程。

2.status 输出型参数,带回子进程退出信息

3.options参数可以设定为 0,或者使用一些特定的选项来控制等待行为。

可以while循环重复调用直到子进程结束

  1. WNOHANG

    • 如果没有子进程结束,waitpid 会立即返回,而不是阻塞父进程。
    • 返回值:
      • 若有子进程结束,返回该子进程的 PID。
      • 若没有子进程结束,返回 0。

返回值:

1.成功时,返回子进程的进程ID。

2.子进程没有结束,返回0。

3.出错时,返回 -1,且设置 errno

四:进程替换

用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。

execl

int execl(const char *path, const char *arg0, ..., (char *) NULL);

execl是系统调用,是用新程序替换当前进程的映像。
path要执行程序的路径    

arg0 arg1 ... 执行方法 

最后以NULL结尾

eg. exel("bin/ls","ls","-l",nullptr);

1.execl是替换进程,并不是新建进程。

2.execl成功不返回 失败返回-1

execv

execv(const char *path, char *const argv[]);

和execl不同的是path后面不是可变参数列表,而是指针数组。

execle

execle(const char *path, const char *arg0, ..., NULL, char *const envp[]);

和execl一致,但可以传环境变量

execve

execve(const char *path, char *const argv[], char *const envp[]);

最底层的版本,允许传递参数和环境变量。

execlp 和 execvp

execlp(const char *file, const char *arg0, ..., NULL);

execvp(const char *file, char *const argv[]);

不同的是它可以在环境变量(PATH)的默认路径下查找

eg. execlp("ls", "ls", "-l", NULL); // 在 PATH 中查找 ls

execlpe 和 execvpe

int execvpe(const char *file, char *const argv[], char *const envp[]);
int execlpe(const char *file, const char *arg0, ..., NULL, char *const envp[]);
在execlp execvp基础上可以指定特定的环境变量

envp[]环境变量数组,以 NULL 结尾。如果传递 NULL,则使用当前进程的环境变量。

putenv 新增环境变量

#include <stdlib.h>

int putenv(char *string);
  • 成功时返回 0。
  • 失败时返回 -1,并设置 errno。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

KubeSphere部署Elasticsearch+Kibana

演示示例使用的是3.4.1&#xff0c;各版本有名字差异 功能是一样的 1.配置字典 名称&#xff1a;elasticsearch 键名&#xff1a;elasticsearch-conf 值&#xff1a; network.host: 0.0.0.0 http.port: 9200 transport.port: 9300 # head 插件需要这打开这两个配置,解决跨域…

面试:了解 ThreadLocal 内存泄漏需要满足的 2 个条件吗?

欢迎关注公众号 【11来了】&#xff08;文章末尾即可扫码关注&#xff09; &#xff0c;持续 中间件源码、系统设计、面试进阶相关内容 在我后台回复 「资料」 可领取 编程高频电子书&#xff01; 在我后台回复「面试」可领取 30w 字的硬核面试笔记&#xff01; 感谢你的关注&…

Vim工具使用( Linux 网络操作系统 07)

1 概念部分 vim是vimsual interface的简称&#xff0c;它可以执行输出、删除、查找、替换、块操作等众多文本操作&#xff0c;而且用户可以根据自己的需要对其进行定制。这是其他编辑程序所没有的。vim不是一个排版程序&#xff0c;它不像Word或WPS那样可以对字体、格式、段落…

记录 ruoyi-vue-plus在linux 部署遇到的问题

整理 linux 文件不要放在 /, 根目录下&#xff0c;要放在 home 文件夹下。docker 启动mysql 容器&#xff0c;映射的 my.cnf 文件不能设置太高权限&#xff0c;权限太高有安全问题&#xff0c;无法读取。 linux 使用注意事项 docker 文件夹 部署在home文件夹下 总结学习到的…

linux的随机化处理

Linux的随机化处理&#xff08;或称为地址空间布局随机化&#xff0c;ASLR&#xff09;是一种安全特性&#xff0c;旨在提高系统对抗攻击的能力&#xff0c;尤其是缓冲区溢出和代码注入攻击。随机化处理通过改变进程在内存中的布局来减少攻击者利用漏洞的可能性。 随机化处理的…

SOLIDWORKS参数化软件

在产品设计和工程领域&#xff0c;参数化设计是一种革命性的方法&#xff0c;它允许设计者通过定义一系列规则和关系来创建和修改模型。参数化设计的核心在于将设计过程分解为一系列可调整的参数&#xff0c;如尺寸、形状、材料属性等&#xff0c;这些参数之间通过数学关系相互…

【北京迅为】《STM32MP157开发板嵌入式开发指南》- 第四十九章 平台总线总结回顾

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器&#xff0c;既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构&#xff0c;主频650M、1G内存、8G存储&#xff0c;核心板采用工业级板对板连接器&#xff0c;高可靠&#xff0c;牢固耐…

Anaconda虚拟环境安装cuda和pytorch

首先电脑上要有Anaconda&#xff0c;使用conda创建一个虚拟环境,并激活 conda create yolov8 conda activate yolov8winR输入cmd&#xff0c;在命令窗口输入 NVIDIA-smi可以查看到自己电脑支持的cuda环境&#xff0c;如下图 再打开torch的官网 pytorch官网 查看目前支持的版…

C++ MFC 标准库 加密解密解惑

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…

第五届光学与图像处理国际学术会议(ICOIP 2025)征稿中版面有限!

第五届光学与图像处理国际学术会议&#xff08;ICOIP 2025&#xff09; 2025 5th International Conference on Optics and Image Processing (ICOIP 2025&#xff09; 重要信息 时间地点&#xff1a;2025年4月25-27日丨中国西安 截稿日期&#xff1a;2024年12月16日23:59 …

Java项目-基于Springboot的应急救援物资管理系统项目(源码+说明).zip

作者&#xff1a;计算机学长阿伟 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、ElementUI等&#xff0c;“文末源码”。 开发运行环境 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBoot、Vue、Mybaits Plus、ELementUI工具&#xff1a;IDEA/…

【数据结构与算法】力扣 54. 螺旋矩阵

问题描述 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a; matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a; [1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a; ma…

【C++】deque(空间适配器))

适配器 适配器是一种设计模式(设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结)&#xff0c;该种模式是将一个类的接口转换成客户希望的另外一个接口。 STL标准库中stack和queue的底层结构 deque原理介绍 deque(双端队列)&#xff1a;是一种…

Visual Studio2022 无法打开源文件

今天在新电脑上安装了Visual Studio2022&#xff0c;但是无法打开多个源文件&#xff0c;网上搜索都是说重新安装Windows SDK 我最开始安装的sdk版本是win11SDK 修改成其他版本后也没有解决问题 最后安装了Windows 10 SDK 10.0.20348.0 这个版本&#xff0c;成功解决问题。 有…

快速了解kubernetes中的存储管理

目录 一 configmap 1.1 configmap的功能 1.2 configmap的使用场景 1.3 configmap创建方式 1.3.1 字面值创建 1.3.2 通过文件创建 1.3.3 通过目录创建 1.3.4 通过yaml文件创建 1.3.5 configmap的使用方式 1.3.5.1 使用configmap填充环境变量 1.3.5.2 通过数据卷使用c…

大数据-173 Elasticsearch 索引操作 增删改查 详细 JSON 操作

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

【ESP32-IDFV5.3.1开发】带SSL的MQTT-demo连接教程

目录 1.VSCODE以及IDF环境配置(略) 2.准备demo 2.1打开VSCODE,主菜单创建示例 找到SSL对应demo,点击创建,并成功创建项目,点击编译,显示编译成功即可以下一步。 确认该demo支持的开发板是你手上的开发板 3.修改demo配置项 3.1插上开发板,点击底部开发工具,分别配置好烧…

Maya---骨骼绑定

调节骨骼大小 回车键确认骨骼 FK子集跟父集走 IK子集不跟父集走 前视图中按shift键添加骨骼 清零、删除历史记录&#xff0c;创建新的物体

Go 设置并发控制数量 【go并发模型】

背景&#xff1a;go的并发控制也是老生常谈&#xff0c;在公司业务中也是经常出现 谈谈我们这次并发模型的适用场景&#xff1a;要处理的任务很多比如有10000个&#xff0c;没开并发的时候我们要一个一个进行执行这个时候其实无论是cpu压力还是数据库和redis压力都比较小也就是…

CTFHUB技能树之HTTP协议——响应包源代码

开启靶场&#xff0c;打开链接&#xff1a; 是个贪吃蛇小游戏&#xff0c;看不出来有什么特别的地方 用burp抓包看看情况&#xff1a; 嗯&#xff1f;点击“开始”没有抓取到报文&#xff0c;先看看网页源代码是什么情况 居然直接给出flag了&#xff0c;不知道这题的意义何在 …