进程的控制

进程的创建

frok函数添加进程

进程=内核的相关管理数据结构(task_struct +mm_struct+页表)+代码数据

特性:
  • 分配新的内存块和内核数据结构给子进程
  • 将父进程部分数据结构内容拷贝至子进程
  • 添加子进程到系统进程列表当中
  • fork返回,开始调度器调度
fork可能调用失败
  • 因为一个系统的进程一定有一个上限,及用户线程到达上限
  • 系统资源已满。
fork的返回值
  • 子进程返回0
  • 父进程返回子进程pid。

为了方便父进程对子进程标识,方便管理。

进程的终止

终止是在做什么?

释放曾经的代码和数据结构所占据的空间,释放内核数据结构(僵尸)task_sturct 停滞状态

进程退出码

return返回退出码(可返回自定义退出码)

退出码分为:

  • 自定义退出码
  • 系统默认退出码

都交由bash处理,但只存在最新的一个子进程的退出码。

父进程bash为什么要知道子进程的退出码(让用户知道)?

因为要知道子进程的退出情况,如果用问题就终止。

进程终止的3中情况。

跑完

1.代码正确,结果正确

2.代码跑完,结果不正确

都可以通过进程的退出码决定。

非跑完

3.代码异常终止

vs 编程运行时,操作系统发现你的进程做了不该做的事情,os杀掉进程。

异常本质:因为进程收到了os的信号,同时,一旦出现异常,退出码无意义。

一个进程退出,我们可以通过两个数字知道原因:退出码,退出信号(task_struct结束保留等待父进程),且父进程必须知道。

如何终止

main函数return,表示进程终止(非main,函数结束)

代码调用exit函数,表示进程终止(c语言库函数,刷新缓存区)

_exit(系统调用,也是exit的底层调用)

exit最后也会调用exit, 但在调用exit之前,还做了其他工作:

1. 执行用户通过 atexit或on_exit定义的清理函数。

2. 关闭所有打开的流,所有的缓存数据均被写入

3. 调用_exit

进程等待

结论:任何子进程,在退出情况下,一般必须要被父进程等待,否则僵尸,原因:

父进程通过等待,解决子进程的退出僵尸问题,回收系统资源(必要性)。

获取子进程的退出信息,知道子进程时因什么原因退出(充要性)。

如何等待(释放僵尸)

wait方法

#include

#include

pid_t wait(int*status);

返回值:

成功返回被等待进程pid,失败返回-1。参数:

输出型参数,获取子进程退出状态,不关心则可以设置成为NULL

waitpid方法

int *status;

pid_ t waitpid(pid_t pid, int *status, int options);

返回值:

当正常返回的时候waitpid返回收集到的子进程的进程ID;

如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;

如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;

参数:

  1. pid:

Pid=-1,等待任一个子进程。与wait等效。

Pid>0.等待其进程ID与pid相等的子进程。

  1. status:WIFEXITED(status):

若为正常终止子进程返回的状态,则为真。(查看进程是否是正常退出)

WEXITSTATUS(status): 若WIFEXITED非零,提取子进程退出码。(查看进程的退出码) options:

不休眠等待

WNOHANG: 若pid指定的子进程没有结束,则waitpid()函数返回0,不予以等待。若正常结束,则返回该子进程的ID。

  • 如果子进程已经退出,调用wait/waitpid时,wait/waitpid会立即返回,并且释放资源,获得子进程退出信息。
  • 如果在任意时刻调用wait/waitpid,子进程存在且正常运行,则进程可能阻塞(永久休眠)。
  • 如果不存在该子进程,则立即出错返回。

等待父进程的一个子进程结束

子进程本身是一个软件,父进程本质实在等待某种条件就绪(阻塞等待)。

其中status变量是一个输出变量,他保存的是32位的退出码与退出信号的二进制合并。

WNOHANG等待方式:

#include <stdio.h> 
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__); return 1;}else if( pid == 0 ){ //child printf("child is run, pid is : %d\n",getpid()); sleep(5); exit(1);}else{int status = 0; pid_t ret = 0; do {ret = waitpid(-1, &status, WNOHANG);//非阻塞式等待 if( ret == 0 ){printf("child is running\n");}sleep(1);}while(ret == 0);if( WIFEXITED(status) && ret == pid ){ printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status)); }else{ printf("wait child failed, return.\n"); return 1;}}return 0;
}

进程程序替换

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

替换原理

进程之间的替换是将代码与数据(目标数据代码)与源数据交换(在执行过程中掩盖源数据代码),从而实现进程之间的替换,其中堆栈中的数据会重新刷新。

常用法:

通过子进程执行该进程,其中子进程会执行内存上的一块新空间(写时拷贝),不影响父进程的使用。

ps:exec是程序替换函数,本身并不创建进程

常见函数替换:

#include <unistd.h>`
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);

函数解释

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

命名理解

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

使用:


#include <unistd.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);exit(0);
}

事实上,只有execve是真正的系统调用,其它五个函数最终都调用 execve,所以execve在man手册 第2节,其它函数在man手册第3节。这些函数之间的关系如下图所示。
下图exec函数族 一个完整的例子: 

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

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

相关文章

grep无法使用完整的正则表达式

问题描述 grep无法使用完整的正则表达式&#xff0c;比如前置断言、后置断言、\d和\t、\n等 问题原因 使用了扩展正则&#xff0c;而不是perl正则。规则和perl正则不同 从文档上讲得很清楚&#xff1a; -E PATTERN is an extended regular expression 他是扩展表达式&#…

文字超出收起展开功能的实现(vue2)

1.编写展开收起组件 <template><div class"text-clamp"><div class"text" :style"{height}"><span v-if"isVisible" class"btn" click"toggle">{{isExpand ? 收起 : ... 展开}}</spa…

2024/4/5 AT24C02 总线(I²C总线)

存储器的介绍&#xff1a; 一、易失性存储器RAM&#xff1a;存储速度快&#xff0c;掉电丢失 SRAM&#xff08;静态RAM&#xff09;&#xff1a;极快DRAM&#xff08;动态RAM&#xff09;&#xff1a;需要配一个扫描电路&#xff0c;进行“补电”&#xff08;动态刷新&#x…

第20次修改了可删除可持久保存的前端html备忘录:重新布局

第20次修改了可删除可持久保存的前端html备忘录&#xff1a;重新布局 <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"…

易宝OA ExecuteQueryForDataSetBinary SQL注入漏洞复现

0x01 产品简介 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台,具有信息管理、 流程管理 、知识管理(档案和业务管理)、协同办公等多种功能。 0x02 漏洞概述 易宝OA ExecuteQueryForDataSetBinary 接口处存在SQL注入漏洞,未经身份认证的攻击者…

基于SpringBoot+Vue实现前后端分离的房屋租赁系统

一、&#x1f680;选题背景介绍 &#x1f4da;推荐理由&#xff1a; 计进行房屋租赁工作的管理&#xff0c;不仅能够保证各项信息准确无误、快速输出&#xff0c;同时计算机具有手工管理所无法比拟的优点&#xff0c;例如:检索迅速、查找方便、可靠性高、存储量大、保密性好、寿…

实用技巧:如何取消app的截屏禁用

因为我想要在小鹅通App做笔记,但是被小鹅通App禁用截屏了,这真是一个很糟糕的使用体验,虽然可能是为了保护商家权益…… 方法1 可以让商家设置课程可以截屏 方法2 手机root,安装Xposed框架,利用Xposed框架上面的插件我们可以对手机进行高度定制化,而安装Xposed框架的…

【Python基础教程】5. 数

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;python基础教程 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、…

第33关 使用gin开发webhook转发服务,实现prometheus和falco的钉钉、企业微信、飞书报警发送

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。 出这期视频&#xff0c;也是为了给第30关的falco公开课补一个坑&#xff0c;关于falco报警这块这期将补上&#xff0c;同时&#xff0c;对于这个gin开发的webhook服务源码这块&#xff0c;计划…

leetcode刷题-代码训练营-第7章-回溯算法1

回溯法模板 void backtracking(参数) {if (终止条件) {存放结果;return;}for (选择&#xff1a;本层集合中元素&#xff08;树中节点孩子的数量就是集合的大小&#xff09;) {处理节点;backtracking(路径&#xff0c;选择列表); // 递归回溯&#xff0c;撤销处理结果} }理解 从…

力扣108. 将有序数组转换为二叉搜索树

Problem: 108. 将有序数组转换为二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 根据二叉搜索树中序遍历为一个有序序列的特点得到&#xff1a; 1.定义左右下标left&#xff0c;right分别指向有序序列的头尾&#xff1b; 2.每次取出left和right的中间节点mid&…

Lafida多目数据集实测

Lafida 数据集 paper&#xff1a;J. Imaging | Free Full-Text | LaFiDa—A Laserscanner Multi-Fisheye Camera Dataset 官网数据&#xff1a;https://www.ipf.kit.edu/english/projekt_cv_szenen.php 官网&#xff1a;KIT-IPF-Software and Datasets - LaFiDa 标定数据下载&…