进程与线程(一)

进程与线程(一)

  • 理解什么是并发编程
  • 进程的相关概念
    • 什么是进程
    • 对比进程和程序
    • 理解进程是一个独立的可调度的任务
    • 理解进程是程序执行和资源管理的最小单位
    • 进程状态转换图
    • 进程的种类
  • 进程相关命令
    • 进程状态标志
    • ps命令
      • -aux:
      • -axj:(可以查看到进程的PPID)
      • pstree
      • kill命令
  • 进程相关的系统调用
    • 进程创建
      • fork()
      • vfrok()
      • fork和vfork的区别
      • 获取进程ID和父ID的方法
      • 进程的退出
  • 僵尸进程和孤儿进程
    • 僵尸进程
    • 孤儿进程
    • 回收僵尸进程的方法
      • wait阻塞回收子进程的退出资源
      • waitpid非阻塞回收子进程的退出资源

理解什么是并发编程

并发是什么?
—》多个任务同时运行
任务是什么?
—》就是一个应用程序
思考:程序是如何产生的?
—》程序:一组能被计算机直接识别的有序指令的集合
所以:程序是被编译生成的 eg:gcc test.c -o App (App就是一个程序)
程序在外存(U盘,硬盘)上存储(静态的概念)
一个程序一旦被运行起来,就会产生一个进程(动态的:被创建,被调度,被消亡)
总结:Linux下的多任务编程就是多进程/多线程去协同工作,将某一个事情搞定的过程该过程避免不了多进程/多线程之间数据交互的问题(进程间通信的技术)

进程的相关概念

什么是进程

概念:进程就是程序的一次动态执行过程

对比进程和程序

程序:一组存储在磁盘上的有序指令的集合,是一个静态且没有任何执行的概念
进程:运行一个程序,就会拥有一个进程,它是程序的一次动态执行过程,动态性:创建,调度,消亡

理解进程是一个独立的可调度的任务

一个进程是一个独立的个体,意味着拥有自己专属的地址空间
地址空间图解:
在这里插入图片描述
调度:调用进程/线程,调用动作是由CPU来完成的!
再次理解:
CPU调用进程/线程本质:执行它!
思考:Linux下如何实现多任务(并发编程)的?(借助于CPU调度)
注意:单核的CPU同一时刻只能处理一个进程/线程,并发如何实现?
—》Linux下实现并发的思想:引入“时间片”的概念时间片?
–》每一个任务,操作系统为其分配了一段执行的时间,在这段时间之内处理你,超时则下次再处理,时间片很小,小到用户都可能感知不到时间片的概念,因此每一个任务都会有一个时间片,他们之间采用时间片轮转的概念,被加入到一个循环队列中(注意:该资源队列并不遵循先进先出的原则,多个任务的调度的是随机的,且存在优先级的概念!),多个任务(程序的执行过程)存在状态的切换。

理解进程是程序执行和资源管理的最小单位

程序执行的最小单位:每运行一个程序,就会产生一个进程
资源管理的最小单位:每一个进程都会拥有一个独立的地址空间(资源)

进程状态转换图

进程的状态:运行态,就绪态,等待态,停止态,死亡态,僵尸态
图解:运行态,等待态,死亡态
在这里插入图片描述

进程的种类

(1)交互进程:该进程需要人机交互,用户需要给该进程一个信息的反馈。(shell终端)
(2)批处理进程:也称批处理文本或者批处理脚本,他们采用轮询的概念去依次执行。
(3)守护进程:也称“精灵进程”,“监测进程”,”后台进程“,不受终端的控制!运行在后台。

进程相关命令

进程状态标志

在这里插入图片描述

ps命令

作用:打印出当前运行的进程
使用ps命令时,一般都会搭配选项来使用:
常用的选项

-aux:

在这里插入图片描述

-axj:(可以查看到进程的PPID)

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

pstree

作用:以树形关系呈现当前终端所有进程的所属关系
在这里插入图片描述

kill命令

作用:发送信号
常用的:杀死进程
方法:kill -9 pid; //pid为需要杀死的进程ID号
Linux下共有64个信号:
在这里插入图片描述

进程相关的系统调用

明确:进程都是被进程创建出来的
1号进程:init进程
init进程创建出一个systemd进程!
终端也是一个进程,也是被创建出来的
故:想要得到一个子进程,就必须去创建!!!

进程创建

fork()

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
功能:创建一个进程
参数:无参
返回值:pid_t是int的别名,含义:
小于0,代表创建子进程失败,可以打印错误码查看原因
等于0,是在子进程中返回的
大于0,是在父进程中返回的,且含义为子进程的ID号(PID)

在这里插入图片描述
验证子进程的数据段是也是拷贝于父进程的(fork()):
在这里插入图片描述
在这里插入图片描述
验证fork之前,子进程会悉数拷贝父进程的所有内容:fork之前父进程有的,子进程都会拷贝一份

在这里插入图片描述
在这里插入图片描述
fork()的原理:

调用进程(称为父进程)通过复制自己,创建出一个新进程(称为子进程),子进程获得父进程的数据空间、堆和栈的副本,即父子进程的空间是独立的,创建出的子进程从fork返回处开始运行。

总结fork():

fork创建的子进程:
1、会完美拷贝父进程中的所有资源(堆栈段,代码段,数据段…)
2、子进程从fork的下一句话开始,会存在父子进程,为了区分两个进程到底谁在执行?
—》通过返回值来判断:等于0(子进程在执行)。大于0(父进程在执行)
3、子进程永远都是在fork的下一句开始执行的!(会用到fork之前父进程定义过的一些资源。)、
4、父子进程的执行次序不确定的!
5、父子进程的地址空间独立,互不影响,父子进程可以被CPU进行调度。

vfrok()

#include <sys/types.h>
#include <unistd.h>
pid_t vfork(void);
用法同fork()!!!

vfork()的原理

vfork()函数创建新进程时并不复制父进程的地址空间,刚开始是运行在父进程的地址空间上的,且保障了子进程会优先被执行,当子进程执行了exec或者exit之后,父进程才有可能被调度。如果在调用exec或者exit之前,子进程依赖于父进程的进一步动作,则会导致死锁!
注意:使用vfork函数之后,子进程内部必须使用exec或者exit函数,否则会造成死锁的现象。

fork和vfork的区别

1、
fork():子进程拷贝父进程的数据段,代码段
vfork():子进程与父进程共享数据段
2、
fork()父子进程的执行次序不确定
vfork()保证子进程先运行,在调用exec或exit之前与父进程数据是共享的,在它调用exec或exit之后父进程才可能被调度运行。
3、
vfork()保证子进程先运行,在它调用exec或exit之后父进程才可能被调度运行。如果在调用这两个函数之前子进程依赖于父进程的进一步动作,则会导致死锁,所以使用vfork创建的子进程必须使用exec重新启动一个新的程序或者exit()使得子进程退出

获取进程ID和父ID的方法

#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);//获取当前进程的ID号
pid_t getppid(void);//获取当前进程的父进程ID号

以上两个函数的返回值就是获取的ID号的结果!!!

进程的退出

_exit()函数的作用最为简单:直接使进程终止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;
exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。
exit()函数在调用exit系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件,就是图中的"清理I/O缓冲"一项。

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

僵尸进程和孤儿进程

僵尸进程

子进程先于父进程退出,而父进程没有回收子进程的退出资源(一小部分的PCB:struct_task的结构体),此时的子进程就会沦为僵尸进程!
僵尸进程的危害:内存泄漏,因此需要避免僵尸进程的产生!
如何避免僵尸进程产生?
----》子进程的退出资源本应该是父进程来回收,因此将回收子进程的退出资源这件事让父进程使用某种手段进行处理即可!

孤儿进程

父进程先于子进程退出,此时的子进程会沦为孤儿进程,会被systemd进程收养,孤儿进程没有任何坏处

回收僵尸进程的方法

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

wait阻塞回收子进程的退出资源

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, const char *argv[])
{//定义局部变量int a = 0;//使用fork来创建一个子进程pid_t pid = fork();if(pid < 0){perror("fork child process error");return -1;}else if(0 == pid){//子进程在执行代码while(1){a++;printf("子进程:a = %d\n",a);printf("I am child process!\n");sleep(1);}}else{//使用wait阻塞回收子进程的退出资源printf("等待回收子进程中......\n");pid_t exitPID = wait(NULL);//阻塞printf("exitPID = %d的子进程已被回收!\n", exitPID);//父进程在执行代码while(1){a++;printf("父进程:a = %d\n",a);printf("I am parent process!\n");sleep(1);}}printf("test!!!\n");return 0;
}

waitpid非阻塞回收子进程的退出资源

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{//定义局部变量int a = 0;//使用fork来创建一个子进程pid_t pid = fork();if(pid < 0){perror("fork child process error");return -1;}else if(0 == pid){//子进程在执行代码while(1){a++;printf("子进程:a = %d\n",a);printf("I am child process!\n");sleep(1);if(a >= 5){exit(0);//子进程主动退出 返回-1此时对方查看的是255}}}else{//父进程在执行代码while(1){printf("等待回收资源中...\n");//引入waitpid回收子进程的退出资源,关心子进程的退出状态int status;pid_t exitPID = waitpid(-1, &status, WNOHANG);if(exitPID < 0){perror("waitpid error");}else if(0 == exitPID){printf("未检测到有子进程结束...\n");}else{//判断子进程是正常退出还是异常退出if(WIFEXITED(status)){//进入if则代表正常退出printf("正常退出!\n");}else{printf("非正常退出!\n");}printf("已成功回收exitPID = %d的子进程资源!\n", \exitPID);//获取子进程的退出状态数值printf("退出状态数值:%d\n",WEXITSTATUS(status));}a++;printf("父进程:a = %d\n",a);printf("I am parent process!\n");sleep(1);}}printf("test!!!\n");return 0;
}

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

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

相关文章

浅析R16移动性增强那些事儿(DAPS/CHO/MRO)

R16移动性增强相关技术总结 Dual Active Protocol Handover Dual Active Protocol Handover意为双激活协议栈切换&#xff0c;下文简称DAPS切换&#xff0c;DAPS切换的核心思想是切换过程中&#xff0c;在UE成功连接到目标基站前继续保持和源基站的连接和数据传输&#xff0c;…

【全开源】Java共享台球室无人系统支持微信小程序+微信公众号+H5

智能引领台球新体验 一、引言&#xff1a;共享经济的新篇章 在共享经济的大潮中&#xff0c;各类共享服务层出不穷&#xff0c;为人们的生活带来了极大的便利。共享台球室作为其中的一员&#xff0c;以其独特的魅力吸引了众多台球爱好者的目光。而今天&#xff0c;我们要介绍…

【通信专题】I2C上拉电阻计算方法

I2C 通信总线是电子设计中常见的总线之一,由于 I2C 的硬件芯片内部为开漏输出,所以要求在外部增加一个上拉电阻,总线上拉电阻的选取受多个因素的影响,因此如何计算 I2C 总线的上拉电阻阻值成为硬件工程师在使用 I2C总统时需要关注的话题。 从本质上讲: I2C 总线电容和上升…

算法第三天力扣第69题:X的平方根

69. x 的平方根 (可点击下面链接或复制网址进行做题) https://leetcode.cn/problems/sqrtx/https://leetcode.cn/problems/sqrtx/ 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内…

基于Qt GraphicView 解析 CIM/G 电力接线图文件

本文讲述了如何使用Qt的框架来渲染展示标准的CIM/G格式的图形文件&#xff0c;也就是公用信息模型&#xff08;common information model&#xff0c;CIM&#xff09;中的G文件部分的内容。这是一种电力系统图形的交换规则&#xff0c;用于电网图形交换。 [by amjieker] CIM/G …

C# WinForm —— 26 ImageList 介绍

1. 简介 图片集合&#xff0c;用于存储图像的资源&#xff0c;并在关联控件中显示出来 可以通过 索引、键名 访问每张图片 没有事件 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般以 imgList 开头ClolorDepth用于呈现图像的颜色数&#xff0c;默…

函数:计算数组的元素和

一、计算数组的元素和 参数传递给函数时&#xff0c;实际上只有数组的首地址作为指针传递给了函数。 在函数定义中的int a[ ]等价于int *a。在只有地址信息的情况下&#xff0c;是无法知道数组里有多少个元素的&#xff0c;因此在计算数组中的元素和时&#xff0c;要加一个参…

探索JavaScript函数---基础篇

目录 函数 声明和调用 声明&#xff08;定义&#xff09; 调用 参数 形参和实参 形参&#xff08;Formal Arguments&#xff09; 实参&#xff08;Actual Arguments&#xff09; 形参与实参的关系 返回值 作用域 全局作用域 局部作用域 匿名函数 函数表达式 立…

海康 面阵相机命名规则

海康 面阵相机命名规则 https://www.v-club.com/vCollage/vCollageDetail/516?subjectIdRMse6nPiyo

【JS重点知识02】栈、堆与数据类型 关系

一&#xff1a;栈堆空间分配区别&#xff1a; 1 栈&#xff1a;由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈&#xff1b; 简单数据类型存放在栈中 2 堆&#xff1a;存储复杂数据类型&#xff08;对象&#xff09;&#xff0c;…

【JMeter接口自动化】第3讲 Jmeter语言及外观配置

Jmeter语言配置 方法一&#xff1a;暂时生效&#xff0c;下次打开JMeter还会恢复默认配置 Jmeter安装后&#xff0c;默认语言是英文&#xff0c;可以在“选项”——“选择语音”中更改 方法二&#xff0c;修改配置文件&#xff0c;永久生效 修改jmeter.properties文件 Jmete…

【详细讲解版】史上最全transformer面试题

史上最全transformer面试题答案 1.Transformer为何使用多头注意力机制&#xff1f;&#xff08;为什么不使用一个头&#xff09;2.Transformer为什么Q和K使用不同的权重矩阵生成&#xff0c;为何不能使用同一个值进行自身的点乘&#xff1f;3.Transformer计算attention的时候为…

20240601在Toybrick的TB-RK3588开发板上跑IPC的SDK并确认eth0

20240601在Toybrick的TB-RK3588开发板上跑IPC的SDK并确认eth0 2024/6/1 20:06 ADB的详细LOG&#xff1a; Microsoft Windows [版本 10.0.22621.3296] (c) Microsoft Corporation。保留所有权利。 C:\Users\QQ>adb shell adb server version (40) doesnt match this client …

全国产飞腾模块麒麟信安操作系统安全漏洞

1、背景介绍 目前在全国产飞腾模块上部署了麒麟信安操作系统&#xff0c;经第三方机构检测存在以下漏洞 操作系统版本为 内核版本为 openssh版本为 2、openssh CBC模式漏洞解决 首先查看ssh加密信息 nmap --script "ssh2*" 127.0.0.1 | grep -i cbc 可以通过修改/…

spring boot 3.x版本 引入 swagger2启动时报错

一&#xff0c;问题 Spring Boot 3.x版本的项目里&#xff0c;准备引入Swagger2作为接口文档&#xff0c;但是项目启动报错&#xff1a; java.lang.TypeNotPresentException: Type javax.servlet.http.HttpServletRequest not present at java.base/sun.reflect.generics.…

Nginx(openresty) 开启gzip压缩功能 提高web网站传输速度

1 开启nginx gzip压缩后&#xff0c;网页的图片&#xff0c;css、js等静态资源的大小会减少&#xff0c;节约带宽&#xff0c;提高传输效率&#xff0c;给用户快的体验,给用户更好的体验. 2 安装 #centos 8.5 yum install gzip 3 配置 #建议统一配置在http段 vim /usr/loca…

SleepFM:利用对比学习预训练的多模态“睡眠”基础模型

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在阅读过程中有些知识点存在盲区&#xff0c;可以回到如何优雅的谈论大模型重新阅读。另外斯坦福2024人工智能报告解读为通识性读物。若对于如果…

逻辑这回事(三)----功耗优化

低功耗设计概述 低功耗设计动机 功耗的增加影响芯片Power grid(电源网格)的设计;功耗的增加导致芯片温度的上升,进而带来一系列影响。如Leakage Power增加;电路时序可能变差;IR Drop(IR压降)变大;功耗的增加导致芯片封装成本和散热成本的增加(packing cost、cooling cost)功耗…

Mysql 8.0.37 安装教程

图片有点长&#xff0c;慢慢来 安装教程 安装地址&#xff1a;MySQL :: MySQL Downloads 进入官网 下载社区版 此处有两个版本&#xff0c;我们下载的是8.0.37版本 第一个需要联网安装&#xff0c;我们现在第二个离线安装 server only&#xff1a;仅安装MySQL server clien…

Java18+前端html+后端springboot一套可在线预约、在线下单的家政预约上门服务系统源码 家政系统(用户端)介绍

Java18前端html后端springboot一套可在线预约、在线下单的家政预约上门服务系统源码 家政系统&#xff08;用户端&#xff09;介绍 家政服务用户端是一个为家庭用户提供便捷、高效家政服务的应用程序。 以下是家政服务用户端的详细功能描述&#xff1a; 一、注册与登录&#…