Linux系统编程之进程控制
概述
在Linux系统中,创建一个新的进程后,如何对该进程进行有效的控制,是一项非常重要的操作。控制进程状态的操作主要包括:进程的执行、进程的等待、进程的终止等。下面,我们将逐个进行介绍。
进程的执行
创建进程后,通常需要让进程执行特定的任务。这可以通过exec系列函数来实现,这些函数会用新的程序替换当前进程的内存映像,即改变当前进程的行为。常见的exec函数有:execl、execlp、execle、execv和execvp等。
1、execl函数使用可变参数列表来传递参数,最后一个参数必须是NULL。它要求提供完整的路径名来执行程序,其函数原型如下。
int execl(const char *path, const char *arg, ...);
path:新程序的完整路径名。
arg:新程序的第一个参数,通常是程序名。
...:其他参数,最后一个参数必须是NULL。
使用execl函数的示例代码如下。
#include <unistd.h>
#include <stdio.h>int main()
{execl("/bin/ls", "ls", "-l", "/home", NULL);return 0;
}
2、execlp函数类似于execl,但它会在环境变量PATH中搜索指定的命令,因此不需要提供完整的路径名。其函数原型如下。
int execlp(const char *file, const char *arg, ...);
file:要执行的程序名。
arg:新程序的第一个参数,通常是程序名。
...:其他参数,最后一个参数必须是NULL。
使用execlp函数的示例代码如下。
#include <unistd.h>
#include <stdio.h>int main()
{execlp("ls", "ls", "-l", "/home", NULL);return 0;
}
3、execle函数类似于execl,但它允许传递一个环境变量列表,这对于需要在新环境中执行程序的情况非常有用。其函数原型如下。
int execle(const char *path, const char *arg, ..., char *const envp[]);
path:新程序的完整路径名。
arg:新程序的第一个参数,通常是程序名。
...:其他参数,最后一个参数必须是NULL。
envp:环境变量列表,最后一个元素必须是NULL。
使用execle函数的示例代码如下。
#include <unistd.h>
#include <stdio.h>int main()
{char *envp[] = {"PATH=/bin:/usr/bin", NULL};execle("/bin/ls", "ls", "-l", "/home", NULL, envp);return 0;
}
4、execv函数使用一个数组来传递参数列表,第一个参数是程序的完整路径名。其函数原型如下。
int execv(const char *path, char *const argv[]);
path:新程序的完整路径名。
argv:参数列表,最后一个元素必须是NULL。
使用execv函数的示例代码如下。
#include <unistd.h>
#include <stdio.h>int main()
{char *argv[] = {"ls", "-l", "/home", NULL};execv("/bin/ls", argv);return 0;
}
5、execvp函数类似于execv,但它会在环境变量PATH中搜索指定的命令,因此不需要提供完整的路径名。其函数原型如下。
int execvp(const char *file, char *const argv[]);
file: 要执行的程序名。
argv: 参数列表,最后一个元素必须是NULL。
使用execvp函数的示例代码如下。
#include <unistd.h>
#include <stdio.h>int main()
{char *argv[] = {"ls", "-l", "/home", NULL};execvp("ls", argv);return 0;
}
为了方便查看这几个函数的区别,可以参考下面的思维导图。

进程的等待
wait和waitpid函数用于等待子进程的结束,并获取子进程的状态信息。这两个函数在父进程中非常有用,可以防止子进程成为僵尸进程。
1、wait函数等待任意一个子进程结束,并返回该子进程的PID。其函数原型如下。
pid_t wait(int *status);
status:指向一个整型变量的指针,用于存储子进程的退出状态。如果不需要获取状态信息,可以传递NULL。
返回值:成功时,返回已终止子进程的PID。如果没有子进程存在,则返回-1,并设置errno为ECHILD。
使用wait函数的示例代码如下。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>int main()
{pid_t pid = fork();if (pid == 0){// 子进程execlp("ls", "ls", "-l", "/home", NULL);perror("execlp failed");exit(1);}else if (pid > 0){// 父进程int status;pid_t cpid = wait(&status);if (WIFEXITED(status)){printf("Child process %d exited with status %d\n", cpid , WEXITSTATUS(status));}else if (WIFSIGNALED(status)){printf("Child process %d terminated by signal %d\n", cpid , WTERMSIG(status));}}else{perror("fork failed");return 1;}return 0;
}
2、waitpid函数等待指定的子进程结束,并返回该子进程的PID。它比wait函数提供了更多的灵活性,比如:可以选择非阻塞等待。其函数原型如下。
pid_t waitpid(pid_t pid, int *status, int options);
pid:指定要等待的子进程的ID。如果pid > 0,则等待进程ID等于pid的子进程。如果pid == 0,则等待任何其组ID等于调用进程的组ID的子进程。如果 pid < -1,则等待任何其组ID等于-pid的子进程。如果pid == -1,则等待任何子进程,这是最常用的情况。
status:指向一个整型变量的指针,用于存储子进程的退出状态。如果不需要获取状态信息,可以传递NULL。
options:可以用来改变waitpid的行为,常用的选项如下。
(1)WNOHANG:如果没有子进程已经退出,则立即返回,不挂起调用进程。
(2)WUNTRACED:如果有子进程已经停止运行,但未被跟踪,则返回该子进程的信息。
(3)WCONTINUED:如果有子进程已经从暂停状态恢复运行,则返回该子进程的信息,仅在某些系统上可用。
返回值:如果成功等待到一个子进程,将返回该子进程的PID。如果设置了WNOHANG选项,并且没有已退出的子进程可等待,将返回0。如果没有匹配的子进程,或调用失败,将返回-1,可通过errno来确定错误的原因。
进程的终止
kill函数用于向一个或多个进程发送信号,这些信号可以用来控制进程的行为,比如:终止进程、暂停进程等。最常用的是:发送SIGTERM信号来请求进程正常终止,或者发送SIGKILL信号强制终止进程。其函数原型如下。
int kill(pid_t pid, int sig);
pid:目标进程的进程ID。如果pid > 0,则信号将发送给进程ID为 pid 的进程。如果pid == 0,则信号将发送给所有与调用进程属于同一个进程组的进程。如果pid == -1,则信号将发送给所有除了发起该调用的进程以外的所有进程。如果pid < -1,则信号将发送给所有进程组ID为-pid的进程。
sig:要发送的信号编号,常见的信号如下。
(1)SIGTERM:请求进程优雅地终止。
(2)SIGKILL:强制终止进程。
(3)SIGINT:中断信号,通常是通过按下Ctrl + C发送的。
返回值:如果成功发送信号,将返回0。如果发生错误,将返回-1,并设置errno来指示错误类型。
相关文章:
Linux系统编程之进程控制
概述 在Linux系统中,创建一个新的进程后,如何对该进程进行有效的控制,是一项非常重要的操作。控制进程状态的操作主要包括:进程的执行、进程的等待、进程的终止等。下面,我们将逐个进行介绍。 进程的执行 创建进程后&a…...
集合的相关性质与定义
集合 集合 集合描述了一组对象的集合,而映射描述了集合之间的对应关系。 集合 集合是由一组无序的,互不相同的对象组成的整体,集合中的对象称为元素或成员。集合可以用大括号{}表示,元素之间用逗号进行分隔。 定义: 集合 A …...
pytest自定义命令行参数
实际使用场景:pytest运行用例的时候,启动mitmdump进程试试抓包,pytest命令行启动的时候,传入mitmdump需要的参数(1)抓包生成的文件地址 (2)mitm的proxy设置 # 在pytest的固定文件中…...
c++预编译头文件
文章目录 c预编译头文件1.使用g编译预编译头文件2.使用visual studio进行预编译头文件2.1visual studio如何设置输出预处理文件(.i文件)2.2visual studio 如何设置预编译(初始创建空项目的情况下)2.3 visual studio打开输出编译时…...
YOLOv8模型pytorch格式转为onnx格式
一、YOLOv8的Pytorch网络结构 model DetectionModel((model): Sequential((0): Conv((conv): Conv2d(3, 64, kernel_size(3, 3), stride(2, 2), padding(1, 1))(act): SiLU(inplaceTrue))(1): Conv((conv): Conv2d(64, 128, kernel_size(3, 3), stride(2, 2), padding(1, 1))(a…...
电子课程开发中的典型误区
创建一个有效的电子课程需要仔细的规划和执行,但常见的错误可能会破坏其成功。以下是开发人员应该避免的一些典型陷阱: 1.缺乏明确的目标 如果没有明确的学习目标,课程可能会缺乏重点,让学习者不确定自己应该实现什么。明确、可衡…...
Docker 逃逸突破边界
免责声明 本博客文章仅供教育和研究目的使用。本文中提到的所有信息和技术均基于公开来源和合法获取的知识。本文不鼓励或支持任何非法活动,包括但不限于未经授权访问计算机系统、网络或数据。 作者对于读者使用本文中的信息所导致的任何直接或间接后果不承担任何…...
残差连接,就是当某一偏导等于0时,加上x偏导就是1,这样乘以1保证不失效
目录 残差连接,就是当某一偏导等于0时,加上x偏导就是1,这样乘以1保证不失效 残差连接中F(x)一般代表什么,将F(x)变为F(x) +x,这样不是改变了函数 本身的性质 F(x)=F(x) +x F(x)偏导若==0;偏导连乘就是0,这样就梯度消失了 F(x) +x;求偏导时x导数是1,保证不丢失F(x)…...
博泽Brose EDI项目案例
Brose 是一家德国的全球性汽车零部件供应商,主要为全球汽车制造商提供机电一体化系统和组件,涵盖车门、座椅调节系统、空调系统以及电动驱动装置等。Brose 以其高质量的创新产品闻名,在全球拥有多个研发和生产基地,是全球第五大家…...
从科举到高考,人才选拔制度的变革与发展
一、引言 在人类历史的长河中,人才选拔机制始终是推动社会进步与文明传承的关键环节。古代科举制度与现代高考制度,分别在各自的时代背景下承担着筛选人才的重任,二者虽皆关乎教育与人才进阶之路,却有着诸多本质性的区别与独特的…...
利用Docker一键发布Nginx-Tomcat-MySQL应用集群
Docker简介,可以看上一篇文章: 为什么互联网公司离不开Docker容器化,它到底解决了什么问题?-CSDN博客 Docker体系结构 docker核心就是镜像和容器: 镜像就是应用程序的安装文件,包含了所有需要的资源&…...
关于数据库数据国际化方案
方案一:每个表设计一个翻译表 数据库国际化的应用场景用到的比较少,主要用于对数据库的具体数据进行翻译,在需要有大量数据翻译的场景下使用,举个例子来说,力扣题目的中英文切换。参考方案可见: https://b…...
【系统架构设计师】高分论文:论信息系统的安全与保密设计
更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 摘要正文摘要 本人所在工作单位承担了我市城乡智慧建设工程综合管理平台项目的开发工作。我有幸参与了本项目,并担任架构师一职,全面负责项目的需求分析和系统设计等工作。城乡智慧建设工程综合管理平台项目包括…...
使用Tauri创建桌面应用
当前是在 Windows 环境下 1.准备 系统依赖项 Microsoft C 构建工具WebView2 (Windows10 v1803 以上版本不用下载,已经默认安装了) 下载安装 Rust下载安装 Rust 需要重启终端或者系统 重新打开cmd,键入rustc --version,出现 rust 版本号&…...
【docker】docker compose多容器部署
Docker Compose 的详细讲解与实际应用 什么是 Docker Compose? Docker Compose 是一个工具,用于定义和运行多容器 Docker 应用。 通过一个 docker-compose.yml 文件,可以同时启动多个服务,简化多容器管理。 Docker Compose 的核心…...
JS +CSS @keyframes fadeInUp 来定义载入动画
JSCSS 更完美展现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>跳动加载指示器</title>&l…...
Seatunnel解决ftp读取json文件无法读取数组以及格式化之后的json无法解析的问题
问题原因 在JsonRead这个方法里面 在源码中使用的逻辑是读取一行 然后把这个json进行解析 但是这样存在一个问题 比如如果json的格式是这样的 { name:“zhangsan”, age:25 } 如果是这样的话 第一行读到的内容就是 { 显然 一个 { 并不是一个…...
Elasticsearch在liunx 中单机部署
下载配置 1、下载 官网下载地址 2、上传解压 tar -zxvf elasticsearch-XXX.tar.gz 3、新建组和用户 (elasticsearch 默认不允许root账户) #创建组 es groupadd es #新建用户 useradd ryzhang -g es 4、更改文件夹的用户权限 chown -R ryzhang …...
深入探索 HarmonyOS 的 Navigation 组件:灵活的页面管理与动态导航
在移动应用开发中,页面的跳转和导航一直是核心功能之一。对于 HarmonyOS 开发者来说,Navigation 组件提供了一个强大的工具来实现灵活的页面管理和导航体验。今天,我们将深入探讨如何使用 HarmonyOS 中的 Navigation 组件来管理页面跳转、工具…...
【CUDA】CUDA Hierarchy
【CUDA】CUDA 基本概念和 Hierarchy CUDA 编程基础:Host 和 Device 工作流程 首先简单介绍CUDA 编程的基本概念:讲解 Host(CPU)与 Device(GPU)的区别、内存管理以及 CUDA 运行时的工作机制。 Host&#x…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...
Vue ③-生命周期 || 脚手架
生命周期 思考:什么时候可以发送初始化渲染请求?(越早越好) 什么时候可以开始操作dom?(至少dom得渲染出来) Vue生命周期: 一个Vue实例从 创建 到 销毁 的整个过程。 生命周期四个…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
