嵌入式学习---DAY24:进程--二
一、exec函数族----启动一个新程序
用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),
子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的
用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建
新进程,所以调用exec前后该进程的id并未改变。
其实有六种以exec开头的函数,统称exec函数:
1.execl execv
int exec l(const char *path, const char *arg, ...);
要运行文件的路径 要执行的文件名 要执行文件需要的参数
以NULL结尾
int exec v(const char *path, char *const argv[]);
将除了文件路径的其他放入char *const argv[]中。
l --- list //ls -l /
path ---文件路径 "/bin/ls"
arg ---> 要执行的 文件的名字 "ls"
"-l" "/" NULL 表示结束
#include <stdio.h>
#include <unistd.h>int main(int argc, const char *argv[])
{printf("---begin---\n");//execl("/bin/ls","ls","-l",".",NULL);//char * const arg[] ={"ls","-l",".",NULL}; //execv("/bin/ls",arg);execl("/home/linux/linux_prog/01-prog/mycp","mycp","1.c","2.c",NULL);printf("---end---\n");return 0;
}
2.execlp execvp
int exec l p(const char *file, const char *arg, ...);
p-----表示要执行的文件,从PATH环境变量中去找。
出错才有返回值,返回值为-1,
int exec v p(const char *file, char *const argv[]);
和execv一致,除file其余放入char *const argv[]中
#include <stdio.h>
#include <unistd.h>int main(int argc, const char *argv[])
{printf("---begin---\n");//execl("/bin/ls","ls","-l",".",NULL);//char * const arg[] ={"ls","-l",".",NULL}; //execv("/bin/ls",arg);//execl("/home/linux/linux_prog/01-prog/mycp","mycp","1.c","2.c",NULL);//if (execlp("mycp","mycp","1.c","2.c",NULL) < 0)char *const arg[] = {"mycp","1.c","2.c",NULL};if (execvp("mycp",arg) < 0){perror("execl fail");return -1;}printf("---end---\n");return 0;
}
l 与 v 的区别后面参数是为数组(v)还是直接写入(l)。
3.execle execvpe
带e 表示的是可以给要执行的 新程序 传递需要的 环境变量
int execle (const char *path, const char *arg, ..., char * const envp[]);
要运行文件的路径 要执行的文件名 要执行文件需要的参数 环境变量
#include <stdio.h>
#include <unistd.h>
extern char **environ;int main(int argc, const char *argv[])
{char *menv[] = {"USER=linux","PASSWD=123456",NULL};//execle("./myenv","myenv",NULL,environ);//execle("./myenv","myenv",NULL,menv);execle("./myenv","myenv",NULL,menv);return 0;
}
environ:系统环境变量,环境变量可自定义,也可为NULL ,以下代码为系统环境变量
#include <stdio.h>
extern char **environ;int main(int argc, const char *argv[])
{int i = 0;while (environ[i] != NULL){printf("env[%d] = %s\n",i,environ[i]); //char * ++i;}return 0;
}
int execvpe(const char *file, char *const argv[] , char * const envp[]);
路径加文件名
1.带l的默认会搜索当前路径下。
2.带p的只搜索只搜索PATH系统环境变量
子进程做与父进程相同的事情------创建子进程,执行任务即可
子进程做与父进程不同的事情------fork + exec
二、进程的终止
1.main中返回ruturn
return 当该关键字出现在main函数中时候可以结束进程,如果在其他函数中则表示结束该函数
2.exit-----库函数
void exit(int status)
功能:让进程退出,并刷新缓存区
参数:status:进程退出的状态
返回值:缺省
会调用atexit函数
3._exit-----系统调用
void _exit(int status);
功能:让进程退出,不刷新缓存区
参数:status:进程退出状态
返回值:缺省
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{printf("hello world!\n");exit(0); //(3)库函数//_exit(0); //(2)系统调用return 0;
}
4.atexit
int atexit(void (*function)(void));
功能:注册进程退出前执行的函数
参数:function:函数指针,指向void返回值void参数的函数指针
返回值:成功返回0,失败返回非0
当程序调用exit或者由main函数执行return时,所有用atexit
注册的退出函数,将会由注册时顺序倒序被调用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void cleanup(void)
{free(q);printf("----cleanup---\n");
}
int main(int argc, const char *argv[])
{atexit(cleanup);printf("hello world!\n");return 0;
}
异常退出 ---信号结束掉
abort signal
三、进程结束时的资源回收
1.wait
功能:1.获取子进程退出状态 。2.回收资源 //会让僵尸态的子进程销毁
注:wait的本身 是一个 阻塞操作 会使调用者 阻塞
父进程要获得子进程的退出状态
子进程 exit(退出状态值) 退出状态值 只有最低8位有效 [0~255]
父进程 wait(&status) 获取到退出状态值
WIFEXITED() 先判断是否为正常退出
WEXITSTATUS() 获取到exit传递的退出状态值
2.waitpid
pid_t waitpid(pid_t pid, int *wstatus, int options);
功能:等待子进程状态发生变化
参数: pid :pid = -1 //表示等待所有子进程 pid > 0 //表示等待 指定的子进程状态改变
wstatus //表示获取到 子进程 状态信息
options //选项 //可以不阻塞 WNOHANG //hang on
//默认是阻塞 0
wait(&wstatus) <=> waipid(-1,&wstatus,0)
非阻塞调用:waitpid(-1,&wstatus,WNOHANG); //表示非阻塞调用
非阻塞 和 阻塞
1.阻塞 会父进程处理逻辑
2.非阻塞 父进程 会去查看 子进程状态改变,但是,如果没有发生改变,父进程不阻塞,整个程序继续往下 。非阻塞 必须 套在循环中处理 //轮询 。
wait 和 waitpid都是 等待子进程状态改变
wait 是一种阻塞调用
waitpid 可以实现非阻塞调用
进程退出:处理方式
wait //阻塞方式 --- 调用进程 一般不做额外的事情
waitpid //非阻塞的方式 --- 调用进程 逻辑一般不受影响waitpid 想要处理到子进程
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{pid_t pid = fork();if (-1 == pid){perror("fork fail");return -1;}if (pid > 0){int status;printf("father ----\n");wait(&status);printf("status = %d\n",status);if (WIFEXITED(status)){printf("status = %d\n",WEXITSTATUS(status));}}else if (pid == 0){printf("child exit \n");exit(256);}return 0;
}
相关文章:

嵌入式学习---DAY24:进程--二
一、exec函数族----启动一个新程序 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支), 子进程往往要调用一种exec函数以执行另一个程序。当进程调用一种exec函数时,该进程的 用户空间代码和数据完全被…...

Diffusion Model相关论文解析之(二)DENOISING DIFFUSION IMPLICIT MODELS
目录 1、摘要2、创新点3、主要公式4、自己的理解,对错不确定 1、摘要 Denoising Diffusion Implicit Models (DDIM)是一种扩散模型的改进版本,旨在加速采样过程并提高采样速度。DDIM通过引入非马尔可夫扩散过程,相对于传统的去噪扩散概率…...

【STM32嵌入式系统设计与开发拓展】——14_定时器之输入捕获
参考哔站:链接: 铁头山羊 一、微控制器的高级定时与控制功能集合 1、时基单元 2、输入捕获 3、输出比较 4、从模式控制器 5、高级定时器的输出控制 二、问题集合 1、什么是定时器 定时器是一种专门负责定时功能的片上外设GPI0AFI0EXTIUSART RCC I2C) 2、定时器…...
docker swarm如何让两个副本分别跑在两台不同的主机上
虽然 docker swarm 支持自动扩容部署,但是为了服务的稳定性、可靠性,有的时候甲方巴巴会要求一定要服务分散部署在不同的服务器上。 使用默认的部署方式,虽然副本为 N,但是部署的 N 个服务可能落在同一台服务器上。 在 Docker Swa…...

GPT助手的训练流程四个主要阶段( GPT Assistant training pipeline )
GPT助手的训练流程四个主要阶段( GPT Assistant training pipeline ) flyfish 四个阶段 预训练(pre-training) 监督微调(supervised fine tuning, SFT) 奖励建模(reward modeling)…...

网络如何发送一个数据包
网络如何发送一个数据包 网络消息发送就是点一点屏幕。 骚瑞,这一点都不好笑。(小品就是我的本质惹) 之前我就是会被这个问题搞的不安宁。是怎么知道对方的IP地址的呢?怎么知道对方的MAC呢?世界上计算机有那么多&…...

【Harmony OS 4.0】向上滑动加载案例
// 自定义class类对象类型 class Article {public id: numberpublic title: stringpublic content: stringconstructor(id: number, title: string, content: string) {this.id idthis.title titlethis.content content} }// 子组件 Component struct ArticleComponent {Pro…...

SQL基础教程(八)SQL高级处理
※食用指南:文章内容为《SQL基础教程》系列学习笔记,该书对新手入门非常友好,循序渐进,浅显易懂,本人主要用来补全学习MySQL中未涉及的部分,便于刷题和做项目。 官方电子书:《SQL基础教程》第2…...
[论文笔记] Data-Juicer: A One-Stop Data Processing System for Large Language Models
https://arxiv.org/pdf/2309.02033 GitHub - modelscope/data-juicer: A one-stop data processing system to make data higher-quality, juicier, and more digestible for (multimodal) LLMs! 🍎 🍋 🌽 ➡️ ➡️🍸 🍹 🍷为大模型提供更高质量、更丰富、更易”…...

期末速成复习资料——操作系统
体型:选择20判断10填空10*2简答4*5计算2*10 第一章 在一个计算机系统中,通常都含有多种硬件和软件资源。归纳起来可将这些资源分为四类:处理机、存储器、I/O设备以及文件(数据和程序)。相应地,OS的主要功能…...
Android之Service与IntentService区别
目录 Service特点使用场景示例 IntentService特点使用场景示例 区别总结线程管理:生命周期:使用场景:自动停止: 总结 在Android开发中,Service是一个可以在后台执行长时间运行操作的组件。主要有两种类型的Service&…...
【MySQL】表的设计
系列文章目录 第一章 数据库基础 第二章 数据库基本操作 第三章数据库约束 文章目录 系列文章目录前言一、表的设计二、表的关系总结 前言 在前文中,我们学会了基本的CRUD操作,对数据库中的数据进行约束以提高数据库的准确性。接下来介绍的表的设计就是…...

NC 用两个栈实现队列
系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 描述 用两个栈来实…...

用后端实现一个简单的登录模块2 前端页面
该模块能做到的功能: 1阶:输入账号和密码,输入正确即可返回登录成功的信息,反之则登录失败 2阶:有简单的前端页面,有登录成功和失败的弹窗,还有登录成功的主页面 3阶:前端页面的注…...

MySQL慢查询的查找语法
一、引言 数据库查询快慢是影响项目性能的一大因素,对于数据库,我们除了要优化SQL,更重要的是得先找到需要优化的SQL语句。 性能优化的思路 首先需要使用慢查询功能,去获取所有查询时间比较长的SQL语句其次使用explain命令去查…...
SQL中的聚合方法与Pandas的对应关系
在SQL和Pandas中,聚合方法是用来对数据进行汇总统计的重要工具。下面是SQL中的各种聚合方法及其与Pandas中相应操作的对应关系: 1. COUNT SQL: COUNT(*) 返回表中的行数。COUNT(column) 返回指定列中非空值的数量。 Pandas: count() 方法用于计算非空值…...

计算机毕业设计选题推荐-计算中心高性能集群共享平台-Java/Python项目实战
✨作者主页:IT毕设梦工厂✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

仿RabbitMq实现简易消息队列基础篇(future操作实现异步线程池)
TOC 介绍 std::future 是C11标准库中的一个模板类,他表示一个异步操作的结果,当我们在多线程编程中使用异步任务时,std::future可以帮助我们在需要的时候,获取任务的执行结果,std::future 的一个重要特性是能…...

经典算法题总结:数组常用技巧(双指针,二分查找和位运算)篇
双指针 在处理数组和链表相关问题时,双指针技巧是经常用到的,双指针技巧主要分为两类:左右指针和快慢指针。所谓左右指针,就是两个指针相向而行或者相背而行;而所谓快慢指针,就是两个指针同向而行…...

版本控制基础理论
一、本地版本控制 在本地记录文件每次的更新,可以对每个版本做一个快照,或是记录补丁文件,适合个人使用,如RCS. 二、集中式版本控制(代表SVN) 所有的版本数据都保存在服务器上,协同开发者从…...
rknn优化教程(二)
文章目录 1. 前述2. 三方库的封装2.1 xrepo中的库2.2 xrepo之外的库2.2.1 opencv2.2.2 rknnrt2.2.3 spdlog 3. rknn_engine库 1. 前述 OK,开始写第二篇的内容了。这篇博客主要能写一下: 如何给一些三方库按照xmake方式进行封装,供调用如何按…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...

Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...