当前位置: 首页 > news >正文

Linux系统编程基础:进程控制

在这里插入图片描述

文章目录

  • 一.子进程的创建
      • 操作系统内核视角下的父子进程存在形式
      • 验证子进程对父进程数据的写时拷贝
  • 二.进程等待
      • 进程非阻塞等待示例:
  • 三.进程替换
      • 内核视角下的进程替换过程:
      • 综合利用进程控制系统接口实现简单的shell进程

进程控制主要分为三个方面,分别是:子进程的创建,进程等待,进程替换
在这里插入图片描述

一.子进程的创建

  • 父进程调用fork()系统接口创建子进程后,操作系统会为子进程创建独立的PCB结构体虚拟地址空间mm_struct,因此父子进程之间具有互相独立性

操作系统内核视角下的父子进程存在形式

  • 父进程调用fork()函数之后:在这里插入图片描述

验证子进程对父进程数据的写时拷贝

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main(int argc,const char * argv[])
{//创建子进程pid_t id = fork();if(id < 0){//创建子进程失败,退出主函数perror("fork");return 0;}else if(id == 0)  {//子进程执行流//子进程对变量g_val进行修改,引发写时拷贝g_val=100;printf("childProcess[%d]: %d : %p\n", getpid(), g_val, &g_val);}else{//父进程的执行流//父进程先休眠3秒,让子进程先完成g_val变量的写入sleep(3);printf("parentProcess[%d]: %d : %p\n", getpid(), g_val, &g_val);}sleep(1);return 0;
}
  • 执行结果:在这里插入图片描述
  • 内核视角下,代码段中的写时拷贝图解:在这里插入图片描述
    在这里插入图片描述
  • 写时拷贝保证了父子进程之间互相独立的同时提高了计算机整机的内存使用效率

二.进程等待

  • 子进程退出后会进入僵尸状态,僵尸状态进程的内核数据结构对象会保留在操作系统内核空间中,在父进程读取子进程的退出信息后,操作系统才会释放掉子进程所占用的所有系统资源
    • 若父进程比子进程先退出,那么操作系统就会接管子进程(成为孤儿进程),子进程退出后,操作系统会自动读取子进程的退出信息.
  • 父进程读取子进程的退出信息这一过程称为进程等待
  • 进程等待常用系统接口:int waitpid(int pid, int *status, int options);
    • 形参int pid:在这里插入图片描述

    • 形参int *status:用于记录进程退出码和退出信号的输出型参数

    • 形参int options表示进程等待的方式:主要分为阻塞等待非阻塞等待两大类:

      • option0时:进程执行阻塞等待,此时进程会进入阻塞状态(PCB退出运行队列,进入阻塞队列),直到其所等待的子进程退出,该进程才会重新进入运行状态读取子进程的退出信息
      • option为非零时(比如使用系统宏WNOHANG):进程执行非阻塞等待, 此时进程会尝试读取其子进程的退出信息,若没能读取到子进程的退出信息,则waitpid系统接口立即返回0
    • 返回值int:若waitpid系统接口读取到子进程的退出信息,返回子进程的pid,若waitpid执行过程中出现错误,则返回-1

进程非阻塞等待示例:

#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>int main()
{int pid = 0;//创建子进程pid = fork();if(pid == -1){//子进程创建失败printf("fork failed\n");return -1;}else if(pid == 0){//子进程的代码执行流int cnt = 5;while(cnt--){sleep(1);printf("child process running\n");}exit(11);}else{//父进程的代码执行流//非阻塞等待子进程int status = 0;bool quit = 0;while(quit == 0){//循环非阻塞等待子进程int res =  waitpid(pid,&status,WNOHANG);if(res > 0){//子进程已退出printf("waiting pid success,chilProc exit,退出码:%d\n",WEXITSTATUS(status));quit = 1;}else if(res == 0){//子进程还未退出printf("waiting pid success,childProc still running\n");}else{//等待发生错误printf("waiting pid failed\n");}sleep(1);}}return 0;
}

在这里插入图片描述

三.进程替换

  • 进程替换的概念:通过特定的系统调用接口,操作系统可以将进程当前执行的代码段替换成指定系统路径下其他可执行程序的代码段,然后根据进程从头开始执行新的代码段(因此需要通过进程替换系统接口为新代码段传入main函数命令行参数)

内核视角下的进程替换过程:

在这里插入图片描述
在这里插入图片描述

  • 可见进程替换并不是创建新的进程(进程的PCB虚拟内存结构体不变)
  • 进程替换系统接口:
    在这里插入图片描述
  • 形参和返回值统一解释:
    • 参数const char*path:表示将要替换现有代码段的目标可执行程序的完整路径
    • 参数const char*file:表示将要替换现有代码段的目标可执行程序的文件名,其系统路径由环境变量PATH决定
    • 参数const char*arg,...:表示传给新代码段main函数命令行参数的字符串,...表示可变参数列表,可以传入多个字符串,最后一个字符串需传入NULL
    • 参数char *const argv[]:表示传给新代码段main函数命令行参数的字符串数组,数组中最后一个字符串需传入NULL
    • 参数cahr*const envp[]:表示传递给新代码段的环境变量字符串数组
    • 当进程替换失败时,exec系列系统接口会返回-1

综合利用进程控制系统接口实现简单的shell进程

  • shell进程的运行原理:shell进程接收到用户输入的指令后,对指令进行格式化处理,然后创建子进程,子进程通过exec系列系统接口将自身替换成系统命令并执行以响应用户需求,shell进程的这种运行机制保证了自身的进程安全(子进程出现错误不会影响到父进程的运行)
    在这里插入图片描述
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <string.h>
#include <memory.h>//用户输入的命令行的最大长度
#define CStrLen 1024
//解析命令行得到的格式化字符串数组
#define SStrLen 50
//命令行字符串
char CommStr[CStrLen];
//格式化命令行字符串数组
char*  StdStr[SStrLen];//命令行分隔符
#define Sep " "
//操作系统配置的环境变量
extern char ** environ;
int main()
{while(1) {printf("[我的命令行解释器 myshell]$ ");fflush(stdout);memset(CommStr,'\0',sizeof StdStr);//获取用户输入命令if(fgets(CommStr,sizeof CommStr,stdin)== NULL){continue;}CommStr[strlen(CommStr)-1] = '\0';StdStr[0] = strtok(CommStr,Sep);//根据空格对用户输入的字符串进行分割并存入StdStr字符串数组中int i = 1;while(StdStr[i++] = strtok(NULL,Sep));//部分命令(比如cd命令)需要由shell进程自己来执行if(strcmp(StdStr[0],"cd")== 0){//用chdir函数改变shell进程的工作路径if(StdStr[1] != NULL){chdir(StdStr[1]);}continue;}//shell创建子进程来执行系统命令int pid = fork();if(pid == 0){//printf("shell的子进程执行系统命令:\n");execvp(StdStr[0],StdStr);printf("-mybash: %s: command execute failed\n",StdStr[0]);exit(-1);}else{int status;//父进程进行阻塞等待,等待子进程执行完系统命令结束并获取其退出码int waitres = waitpid(pid,&status,0);if(waitres == -1){printf("waitchild process failed\n");}}}return 0;
}

在这里插入图片描述
在这里插入图片描述

相关文章:

Linux系统编程基础:进程控制

文章目录 一.子进程的创建操作系统内核视角下的父子进程存在形式验证子进程对父进程数据的写时拷贝 二.进程等待进程非阻塞等待示例: 三.进程替换内核视角下的进程替换过程:综合利用进程控制系统接口实现简单的shell进程 进程控制主要分为三个方面,分别是:子进程的创建,进程等待…...

选择和操作元素

上一篇文档我们介绍了DOM元素和DOM的获取&#xff1b;其实除了获取DOM&#xff0c;我们也可以去替换DOM元素中的文本 document.querySelector(.message).textContent "&#x1f389;Correct Number"● 除此之外&#xff0c;我们可以设置那个数字部分 document.que…...

消息中间件(二)——kafka

文章目录 Apache Kafka综述什么是消息系统&#xff1f;点对点消息类型发布-订阅消息类型 什么是Kafka?优点关键术语Kafka基本原理用例 Apache Kafka综述 在大数据中&#xff0c;会使用到大量的数据。面对这些海量的数据&#xff0c;我们一是需要做到能够收集这些数据&#xf…...

量化交易全流程(四)

本节目录 数据准备&#xff08;数据源与数据库&#xff09; CTA策略 数据源&#xff1a; 在进行量化分析的时候&#xff0c;最基础的工作是数据准备&#xff0c;即收集数据、清理数据、建立数据库。下面先讨论收集数据的来源&#xff0c;数据来源可分为两大类&#xff1a;免…...

idea 如何在命令行快速打开项目

背景 在命令行中从git仓库检出项目&#xff0c;如何在该命令行下快速用idea 打开当前项目&#xff0c;类似vscode 可以通过在项目根目录下执行 code . 快速打开当前项目。 步骤 以macos 为例 vim /usr/local/bin/idea 输入如下内容 #!/bin/sh open -na "IntelliJ IDE…...

YOLOV8-DET转ONNX和RKNN

目录 1. 前言 2.环境配置 (1) RK3588开发板Python环境 (2) PC转onnx和rknn的环境 3.PT模型转onnx 4. ONNX模型转RKNN 6.测试结果 1. 前言 yolov8就不介绍了&#xff0c;详细的请见YOLOV8详细对比&#xff0c;本文章注重实际的使用&#xff0c;从拿到yolov8的pt检测模型&…...

数量关系 --- 方程

目录 一、代入排除法 例题 练习 二、数字特性 例题 练习 整除特性 例题 倍数特性 普通倍数 因子倍数 比例倍数 例题 练习 三、方程法 例题 练习 四、 不定方程&#xff08;组&#xff09; 例题 练习 一、代入排除法 例题 素数&#xff1a…...

【C语言 模拟实现strlen函数的三种方法】

C语言程序设计笔记---022 C语言之模拟实现strlen函数1、介绍strlen函数2、模拟strlen函数的三种方法2.1、计数器法模拟实现strlen函数2.2、递归法模拟实现strlen函数2.3、指针减指针法模拟实现strlen函数 3、结语 C语言之模拟实现strlen函数 前言&#xff1a; 通过C语言字符串…...

MySQL数据库与表管理《三国志》为例

在数据库管理中,一个典型的应用场景是游戏数据的存储和管理。以经典游戏《三国志》为例,该游戏具有多个角色、任务、装备等元素,如何有效地存储和管理这些数据就成为了一个问题。 本文将通过《三国志》的实例,详细解释如何在MySQL中进行数据库和表的管理。 文章目录 《三国…...

D. Jellyfish and Mex - DP

题面 分析&#xff1a; 题目最终需要达到MEX位0&#xff0c;也就是从最开始的MEX变成0后m的最小值&#xff0c;可以设 d p i dp_i dpi​表示当前MEX为 i i i时&#xff0c;m的最小值&#xff0c;那么就可以根据前一个状态推出后一个状态&#xff0c;也就是假如当前MEX是 i i …...

奥斯卡·王尔德

奥斯卡王尔德 奥斯卡王尔德&#xff08;Oscar Wilde&#xff0c;1854年10月16日—1900年11月30日&#xff09;&#xff0c;出生于爱尔兰都柏林&#xff0c;19世纪英国&#xff08;准确来讲是爱尔兰&#xff0c;但是当时由英国统治&#xff09;最伟大的作家与艺术家之一&#xf…...

IDEA常用快捷键大全

整理了一些IDEA开发常用的快捷键&#xff1a; 快捷键组合实现效果psvm Tab键 / main Tab键public static void main(String[] args)sout Tab键System.out.println()Ctrl X删除当前行Ctrl D复制当前行AltInsert(或右键Generate)生成代码(如get,set方法,构造函数等)CtrlAltT…...

Java之多线程的综合练习二

练习六&#xff1a;多线程统计并求最大值 需求&#xff1a; 在上一题基础上继续完成如下需求&#xff1a; 每次抽的过程中&#xff0c;不打印&#xff0c;抽完时一次性打印(随机) 在此次抽奖过程中&#xff0c;抽奖箱1总共产生了6个奖项。 分别为&#xff1a;10,20,100,50…...

selenium下载安装 -- 使用谷歌驱动碰到的问题

安装教程参考: http://c.biancheng.net/python_spider/selenium.html 1. 谷歌浏览器和谷歌驱动版本要对应(但是最新版本谷歌对应的驱动是没有的,因此要下载谷歌历史其他版本): 谷歌浏览器历史版本下载: https://www.chromedownloads.net/chrome64win/谷歌浏览器驱动下载: http:…...

开放式耳机怎么选择、300之内最好的耳机推荐

开放式耳机凭借不入耳、不伤耳、安全更舒适的佩戴体验&#xff0c;得到了越来越多音乐爱好者和专业人士的青睐。开放式耳机不需要插入耳道&#xff0c;在佩戴时可以更加自然和轻松&#xff0c;减少了长时间佩戴引起的不适感&#xff0c;而且不会完全隔绝外界声音&#xff0c;用…...

git密码提交切换SSH提交

git保存密码 每次登录都要输入密码是显示繁琐&#xff0c;好在git提供了保存密码的功能。 在本地工程文件夹下&#xff0c;.git目录&#xff0c;保存以下配置。 [credential] helper store或者 在git bash命令行&#xff0c;执行命令 git config credential.helper store如…...

数字乡村包括哪些方面?数字乡村应用介绍

数字乡村是指利用物联网、数字化和智能化技术&#xff0c;借助现代数字智能产品、高效信息服务和物联网基础设施&#xff0c;以提高农村居民生活质量&#xff0c;助力拓展经济发展前景。 创建数字村庄有助于缩小城乡社区之间的差距&#xff0c;保障每个人都能平等地享受科技发展…...

弹性资源组件elastic-resource设计(一)-架构

简介 弹性资源组件提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。 本文介绍弹性资源组件的设计,包括架构设计和详细设计,指导开发人员代码开发 关键词 作业管理器/资源管理器/…...

C/C++笔试面试真题

C/C++笔试面试真题 1、堆和栈的区别 1、栈由系统自动分配,而堆是人为申请开辟; 2、栈获得的空间较小,而堆获得的空间较大; 3、栈由系统自动分配,速度较快,而堆一般速度比较慢; 4、栈是连续的空间,而堆是不连续的空间。 2、什么是野指针?产生的的原因? 野指针的指向的…...

【Vue3】兄弟组件传参

1. 借助父组件传参 A 组件派发一个事件&#xff0c;修改 flag 的值&#xff0c;先传递给父组件&#xff0c;然后由父组件传递给 B 组件。 缺点&#xff1a;必须由 App.vue 处理中间逻辑。 A.vue <template><div class"A"><h1>A组件</h1>…...

【CSS 中 link 和@import 的区别】

<link> 和 import 都可以用于引入 CSS 文件&#xff0c;但是两者有以下区别&#xff1a; 加载时间&#xff1a;<link> 标签在页面加载时同时加载&#xff0c;而 import 是在页面加载后才开始加载。 兼容性&#xff1a;<link> 标签可以被所有的浏览器正确解释…...

笔记二:odoo搜索、筛选和分组

一、搜索 1、xml代码 <!--搜索和筛选--><record id"view_search_book_message" model"ir.ui.view"><field name"name">book_message</field><field name"model">book_message</field><field…...

Ubuntu Zookeeper开机自启动服务

1、创建service文件 在/lib/systemd/system目录下创建zookeeper.service文件 [Unit] DescriptionApache Zookeeper server Documentationhttp://zookeeper.apache.org Requiresnetwork.target remote-fs.target Afternetwork.target remote-fs.target[Service] Typesimple Env…...

关于Matlab与Python中日期转时间戳不一致的问题

由于 Matlab 中的日期序列号精确到秒&#xff0c;而 Python 的时间戳精确到秒&#xff0c;因此在进行转换时可能会存在精度损失&#xff0c;导致转换结果不完全相同。 将 Python 中的时间戳转换为 Matlab 中的日期序列号&#xff0c;可以使用下方代码进行转换&#xff1a; de…...

【Django 笔记】第一个demo

1. pip 安装 2. django 指令 D:\software\python3\anconda3\Lib\site-packages\django\bin>django-adminType django-admin help <subcommand> for help on a specific subcommand.Available subcommands:[django]checkcompilemessagescreatecachetabledbshelldiff…...

算法通过村第十一关-位运算|白银笔记|高频题目

文章目录 前言1. 位移的妙用1.1 位1的个数1.2 比特位计算1.3 颠倒无符号整数 2. 位实现加减乘除专题2.1 位运算实现加法2.2 递归乘法 总结 前言 提示&#xff1a;他不是不想多明白些&#xff0c;但是每每在该用脑子的时候&#xff0c;他用了感情。 --老舍《黑白李》 与位运算和…...

04、EL和JSTL核心技术

目录 1 EL表达式&#xff08;熟悉&#xff09; 1.1 基本概念 1.2 主要功能 1.3 访问内置对象的数据 1.3.1访问方式 1.3.2 执行流程 1.4 访问请求参数的数据 1.5 访问Bean对象的属性 1.5.1 访问方式 1.5.2 主要区别 1.6 访问集合中的数据 1.7 常用的内置对象 …...

【LeetCode热题100】--148.排序链表

148.排序链表 对链表进行排序最适合的算法就是归并排序&#xff1a; 对链表自顶向下归并排序的过程&#xff1a; 找到链表的中点&#xff0c;以中点为分界&#xff0c;将链表拆分成两个子链表&#xff0c;寻找链表的中点可以使用快慢指针的做法&#xff0c;快指针每次移动 2步…...

分布式并行训练(DP、DDP、DeepSpeed)

[pytorch distributed] 01 nn.DataParallel 数据并行初步 数据并行 vs. 模型并行 数据并行&#xff1a;模型拷贝&#xff08;per device&#xff09;&#xff0c;数据 split/chunk&#xff08;对batch切分&#xff09; 每个device上都拷贝一份完整模型&#xff0c;每个device分…...

Linux- fg命令 bg命令

fg fg是Unix-like操作系统&#xff08;如Linux和macOS&#xff09;中的一个shell内建命令&#xff0c;用于将后台作业带到前台执行。这个命令常用于与bg&#xff08;后台执行&#xff09;命令和jobs&#xff08;列出当前作业&#xff09;命令一起&#xff0c;进行shell中的作业…...

广州做网站开发/下载百度官方版

简介 Vapor 是一个基于纯 Swift 构建出的 Web 开发框架&#xff0c;目前可以运行在 macOS 和 Ubuntu &#xff0c;用于构建出漂亮易用的网站或者 API 服务。 官方称是用的最多的 Swift web 框架&#xff0c;理由是因其在 IBM Swift Package CatalogBETA - Most Essential 排名第…...

网站排名突然下降解决/百度代发收录

参考网址详细链接直达 任意浏览器的默认字体高都是16px 如果自己设置字体大小 按设置的字体大小转换 宽高也能使用 1em16px。那么12px0.75em,10px0.625em在css中的body选择器中声明Font-size62.5% px: 相对长度单位。像素px是相对于显示器屏幕分辨率而言的。 em:相对长度单…...

黄石建设网站/搜索排名竞价

ASP.NET Core是一个开放源代码&#xff0c;跨平台&#xff0c;精益和模块化的框架&#xff0c;用于构建高性能&#xff0c;可伸缩的Web应用程序。 ASP.NET Core带有一个现成的内置日志记录框架。 它可作为Microsoft.Extensions.Logging命名空间的一部分使用。 LoggerMessage是…...

企业简介/教程推广优化网站排名

JAVA基础 JAVA异常分类及处理异常分类异常的处理方式Throw和throws的区别JAVA反射动态语言反射机制概念 &#xff08;运行状态中知道类所有的属性和方法&#xff09;Java反射API反射使用步骤&#xff08;获取Class对象、调用对象方法&#xff09;获取Class对象的3种方法创建对…...

盘锦如何做百度的网站/网站优化招商

Docker 修改容器端口 本文介绍如何修改容器端口 对于已经创建的容器&#xff0c;可以通过下面的方法修改端口&#xff1a; 将容器提交为镜像&#xff0c;重新运行修改容器配置文件 将容器提交为镜像&#xff0c;重新运行 略 修改容器配置文件 修改前需要关闭docker&…...

固原网站建设/域名查询系统

一、SDK的安装 安装过程中不要插相机&#xff0c;且一定注意SDK和realsense_ros之间的版本对应关系 我这里使用的版本是2.42.0&#xff0c;对应成功的包&#xff0c;可以到该链接下直接下载&#xff0c;https://download.csdn.net/download/YOULANSHENGMENG/87672407 然后再N…...