从0开始linux(10)——进程(2)进程属性

news2024/10/9 21:28:24

欢迎来到博主的专栏:从0开始linux
博主ID:代码小豪

文章目录

    • 进程与操作系统
      • 并发与并行
      • 进程的状态
    • linux的进程状态

进程与操作系统

进程的状态可分为3种,分别是新建态,运行态,终止态,就绪态与阻塞态。状态之间的关系如下图所示:
在这里插入图片描述

并发与并行

一个cpu在一段时间内只能有一个程序运行,但是有人就会说了,我在使用电脑时,一边运行qq,一边听音乐,还能一边打游戏,这些程序都是同时运行的啊。一方面,这是由于现在的电脑大多数都是多核的,而另一方面,即使是单核的电脑也能同时运行多个程序,这是与并发和并行有关。

并行:多个进程可以由cpu同时调度
并发:cpu在单个时间内只能运行一个程序。

这两个概念看起来有点互相矛盾了,既然多个进程能同时调度,但是在单一时间内有只能运行一个进程,这不是互相矛盾吗?

我们现在的cpu每秒能运算惊人的上亿次,那么也就是说,在一个人眼无法察觉的时间内就能运算非常多次,比如,我们规定cpu每运行一个程序100ms,就切换另外一个程序开始运行,那么就会出现这样的情况
在这里插入图片描述
由于程序暂停的时间太短,以至于我们察觉不到,所以就导致在宏观角度上,这些程序是同时运行的,而在微观角度上,cpu在单个时间内(100ms)内,只能运行一个程序。

我们将这种单个时间称为时间片,在linux系统中,时间片为5ms到800ms,用户是察觉不到程序暂停的。

进程的状态

在linux系统中,进程被描述成一个task_struct的结构体,当一个进程开始时,linux就会创建一个task_struct对象,将该进程的各个属性就记录在task_struct当中,通过task_struct来管理,以一个例子为例:

我们假设现在有三个进程,分别为进程1,进程2,进程3,而linux分别用task_struct类型的对象:task1,task2,task3来描述它,在内存当中它们的关系是这样的。
在这里插入图片描述

现在,我们让进程1,进程2,进程3进入运行态,当进程处于运行态时,cpu会轮着处理这些进程(并发)。而进程是由操作系统来管理的,此时操作系统会创建一个运行队列,以控制cpu处理的进程。

控制的方法如下:将队列中的第一个task_struct对应的进程(比如task1对应进程1)调度给cpu处理,每隔一个时间片,就将运行队列中的task_struct放到队列的最后一位。
在这里插入图片描述

只要处于运行态中的进程,都会在这个运行队列当中。

有时候,我们需要让进程去进行IO操作,比如在代码中写了printf,或者scanf之类的系统调用函数,我们来思考一个问题,IO操作与cpu有没有关系?

答案是没有,IO操作是与硬件相关的操作,那么也就是说,当程序执行IO操作时,并不需要cpu处理,而是需要与硬件进行交互,而我们在前面的章节中降到了,管理硬件是谁的工作?没错还是操作系统。

当我们的进程需要与硬件发生交互时,此时进程不再需要让cpu进行处理了,这意味着,cpu不应该在花时间在该进程中。对应的,该进程不应该放在运行队列中,而是要让这个进程与硬件进行交互,等待这个交互结束时,再回到运行队列当中,这个等待进程与硬件交互的过程,就是进程的阻塞态。

由于我们的计算机通常会与多个硬件进行交互,因此操作系统会为每个硬件都提供该硬件对应的等待队列。

我们以一个例子为例:
假如进程1中有scanf,当程序运行到scanf时,该进程就会等我们的键盘输入,此时进程1就会被操作系统拖入到我们的键盘的等待队列中,当我们在键盘完成输入时,进程1才会从键盘灯等待队列回到运行队列,即从阻塞态回到运行态中。
在这里插入图片描述
这里我们得出一个结论:进程运行态与阻塞态的区别,是处于不同的队列当中!运行态的进程在运行队列,阻塞态的进程在等待队列。运行队列的进程等待cpu调度,等待队列的进程等待与外设的交互结束!

阻塞状态的进程有时还会被挂起,挂起进程的原因是由于,虽然阻塞状态的进程没有运行,但是它依然处于内存当中,会占用内存的资源,而此时随着进程的不断的增多,内存资源严重不足,处于阻塞状态的进程依然在等待外设的交互,此时操作系统就会将进程挂起。

挂起的操作就是将处于阻塞状态的进程从内存移动到磁盘swap分区当中,这个操作叫换出,这个磁盘的swap分区是专门用来存放挂起的进程。此时由于被挂起的进程不再占用内存空间,因此操作系统可以继续让进程运行(内存不足就不行了)。等设备的交互完成后,再将被挂起的进程移动回内存当中,这个操作称之为换入。
在这里插入图片描述
在这里插入图片描述
由于换入换出的本质是内存与磁盘之间做IO操作(将内存中的进程输出到磁盘中)。因此,换入换出的过程会比较慢,在用户的严重,就是程序运行变慢了!因此,服务器通常都不会让进程挂起,因为对于线上服务器来说,用户的使用体验是第一位的,用时间换取空间的做法并不明智,因此如果服务器的内存不够了,采取的做法是扩大服务器,或者优化算法。

linux的进程状态

linux的进程状态不止上面提到的五种,为了弄清楚linux的状态具体有多少中,博主在linux的内核代码中找到有关状态的定义:

static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

R状态
R状态即运行态,指的是该进程正在处于等待cpu调度的运行队列。比如下面的代码:

#include<stdio.h>
#include<unistd.h>
int main()
{
     int i=0;
     while(1)
    	 i++;
     return 0;
}    

我们将其编译生成二进制文件code,并运行,接着打开另外一个窗口,输入命令:

ps ajx | head -1; ps ajx | grep code

在这里插入图片描述
这说明,如果一个进程的状态为R,说明该进程处于运行状态。

S状态
接着我们将代码改一下:
在这里插入图片描述
重新编译并运行该程序。
在这里插入图片描述
可以发现,code程序正在不停的运行,而且向显示器输出i的数据。然后我们来查看一下code程序的进程状态
在这里插入图片描述诶,code程序明明在运行,但是为什么它的状态显示的是S,而非R?我们先来搞清楚这个S状态又是什么状态呢?

S状态在linux中被称为睡眠状态(sleeping),但是实际上这个状态对应的是阻塞态,我们在前面提到了,当进程处于阻塞态时,其实是该进程需要与硬件进行交互时,操作系统为了不让该进程浪费cpu的资源(因为进程和硬件交互不需要用到cpu),将进程从运行队列,拖动到了硬件对应的等待队列。

比如在code当中,当程序执行printf时,此时是code程序与显示器进行做交互,所以每当cpu执行printf函数时,操作系统就会将code程序从R态,转换成S态。但是按照理论,这说明如果我们运气好,在cpu执行i++的时候,去查看进程的状态,那么是不是显示code的状态就是R态呢?是的,但是概率远低于出现S态。因为cpu的计算速度远高于内存与硬件设备做交互的速度,因此绝大多数的情况,code的状态都是S态。当然,你可以多试几次,会有可能出现R态的。
在这里插入图片描述
现在,我们已经弄清楚linux进程的两种状态了,一种是R态,一种是S态,R态代表该进程正在被cpu调度,S态则说明该进程处于与应交交互的过程中(比如向显示器输出数据)。

D状态

那么D态是什么呢?D态的全称为(disk sleep),sleep是睡眠的意思,说明D态也是睡眠状态。而disk则是磁盘的意思,那么disk sleep也就很好理解了,那就是进程与磁盘交互时,进程的状态。

那么为什么进程和磁盘交互就要搞特殊,与其他外设进行交互,状态用的是S,而磁盘则是D呢?

还记得我们前面说的挂起吗?当一个程序处于阻塞状态时,如果此时内存严重不足,则会将处于阻塞状态的进程挂起,以保持其他进程的正常使用,又或者出现更严重的情况,即操作系统选择将进程杀死,而非挂起。

但是如果进程正在与磁盘进行交互,特别是进程向磁盘写入的状况。此时如果杀死进程,那么向磁盘中写入的操作就会失败,而进程原本准备写入到磁盘中的数据就会消失,如果这个数据非常重要(比如用户数据),那么这将是一个灾难级别的事故。

因此与磁盘交互的进程状态被设为D,这个D像是一个免死金牌一样,可以让操作系统在需要杀死进程才能继续工作的情况下,去杀死其他的进程,而非D状态的进程。

由于D状态不好展示(因为一般情况下与磁盘交互的速度很快,很难查看到),如果一个进程长期处于D状态,那么此时就要考虑一下磁盘或者内存是否出现问题了。

T状态
T状态也称stoped状态,和sleep状态都属于是阻塞状态,但是和sleep状态有所不同,T状态是由用户决定的,比如一些程序正在执行我们不想要的情况,此时用户就能主动让程序进入T状态,处于T状态的程序不能执行任何代码,除非用户取消T状态。

我们接着运行刚才的code程序。然后打开另外一个窗口,输入:kill -19 [pid],就能让程序处于T状态。
在这里插入图片描述
这个kill -19的意思的就是向进程发送暂停信号,使进程进入T状态。
在这里插入图片描述
可以发现,输入kill -19命令后,code程序从S+变为了T状态,此时在前台也能看到code程序显示stoped,已表明程序已经被暂停了。
在这里插入图片描述
如果我们想要让code恢复运行,此时输入kill -18 [pid]即可
在这里插入图片描述
SIGCONT是让被暂停的程序恢复到运行状态,但是要注意,恢复的进程默认进入后台运行,此时我们无法使用[ctrl +c]的快捷键关闭该进程,因为该快捷键只能关闭处于前台的当前运行进程。如果想要关闭处于后台的进程,我们只能使用kill -9命令。

这就好比windows当中我们打开音乐播放器时,此时该播放器是属于前台运行的,我们点击右上角的‘×’,就能将该进程关闭,而如果我们将该播放器放在了后台运行,此时想关闭就要用任务管理器了,或者将其调到前台再关闭。

在这里插入图片描述
** t状态**
t状态则是调试暂停状态,比如我们用gdb调试一个进程时,此时进程若是来到断点处,该进程则的状态则是‘t’状态。这里不多展示

X状态
X状态又称“dead”状态,即死亡状态,当一个进程结束时,操作系统需要对其回收以及其他操作,此时的进程状态就会变成X,由于X状态持续时间非常短,因此博主无法向大家展示这个内容
Z状态
Z状态又称“zombie”状态,即僵尸状态,其实和X状态类似,处于Z状态的进程已经结束了,但是由于某个操作未完成,因此还不能消失。那么这个操作是什么呢?

我们先来了解一下一个正常“死亡”的进程需要干什么事才能正常死亡,首先该进程已经执行完成,或者被我们kill了,该进程就会结束,此时它要完成一下事情:
(1)将进程占用的内存回收
(2)向父进程发送结束信息
由于(1)是由系统完成的,所以基本上不会发生不回收的事(如果发生了我们也束手难测,不是吗?)。

而向父进程发送结束信息则是写在main()函数的return的返回值。比如输入echo $?,我们可以查看最近一个进程的结束的信息。比如:
在这里插入图片描述

结束信息可以让父进程根据子进程的结束信息来判断子进程的执行结果,这也是为什么我们在写C语言代码时,经常在程序正常退出时,要写一个return 0,通常来说,正常退出时,结束信息都是0,而错误退出时,结束信息为非。

那么如何查看到进程处于“Z”状态呢?前面说了,当结束信息没有发送给父进程时,进程就会处于僵尸状态。所以我们可以写一个程序,在程序运行的过程中,fork出一个子进程,然后让子进程先结束,且父进程不接收子进程的结束信息,此时由于子进程的结束信息没有发送出去,一直处于“Z”状态。

代码如下:
在这里插入图片描述
运行该代码
在这里插入图片描述
查看testzombie_proc的进程信息
在这里插入图片描述
此时子进程处于Z状态,而且<defunct>的意思是该进程已经不起作用了,已经结束了。

我们将这种处于Z状态的进程称为僵尸进程,这种僵尸进程其实并不好,这是因为,一个进程结束,系统会对其做两种事,(1)将进程的内存空间回收(2)将该进程对应的task_struct回收。而僵尸进程虽然被回收了内存空间,但是由于其结束信息一致没有发送给父进程,此时系统会保留下该进程的task_struct,而这个task_struct是会占用内存空间的,因此僵尸进程会导致内存泄漏的事故!!!

当然,解决僵尸进程可以用wait()函数解决,但是博主打算后面再说。

** 孤儿进程**
我们都知道,一个子进程在结束时,需要向父进程发送结束标志,否则就会导致僵尸进程的出现。那么如果父进程先结束了呢?

那么我们将代码修改一下,让子进程进入循环,而父进程直接结束。
在这里插入图片描述
运行改代码,然后查看该进程信息
在这里插入图片描述
可以发现,如果父进程比子进程结束的还快,为了让子进程的结束信息能够成功返回,避免让子进程变成僵尸进程,系统会将子进程的父进程给改了。这种进程则是孤儿进程。

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

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

相关文章

【深度学习总结】热力图-Grad-CAM使用

Grad-CAM使用 介绍 Grad-CAM&#xff0c;全称为Gradient-weighted Class Activation Mapping&#xff0c;是一种用于深度学习模型可视化的技术&#xff0c;特别是在卷积神经网络&#xff08;CNN&#xff09;中。它通过生成热力图来展示模型在做出决策时关注的区域&#xff0c…

反应香精市场报告:预计2030年全球市场规模将达到264.3亿美元

“反应香精”通常是指通过在食品或饮料加工过程中发生的物理、化学或酶反应而产生的风味剂。可以有意添加这些香料以增强最终产品的味道、香气或其他感官方面。它们通常用于食品和饮料行业&#xff0c;以保持一致性、提高适口性或创造独特的风味特征。生产工艺香料的方法有多种…

[论文阅读] DVQA: Understanding Data Visualizations via Question Answering

原文链接&#xff1a;http://arxiv.org/abs/1801.08163 启发&#xff1a;没太读懂这篇论文&#xff0c;暂时能理解的就是本文提出了一个专门针对条形图问答的数据集DVQA以及一个端到端模型SANDY&#xff0c;模型有两个版本&#xff0c;Oracle和OCR。主要解决的问题是固定词表无…

树莓派3b安装ubuntu18.04服务器系统server配置网线连接

下载ubuntu镜像网址 img镜像&#xff0c;即树莓派官方烧录器使用的镜像网址 ubuntu18.04-server&#xff1a;ARM/RaspberryPi - Ubuntu Wiki 其他版本&#xff1a;Index of /ubuntu/releases 下载后解压即可。 发现使用官方烧录器烧录配置时配置wifi无论如何都不能使用&am…

AI的历史、现状与理论基础

在本篇文章中&#xff0c;我们将深入探讨人工智能&#xff08;AI&#xff09;的起源、现状以及理论基础&#xff0c;为读者提供一个全面的理解框架。 I. 引言 人工智能&#xff08;AI&#xff09;作为一门跨学科的研究领域&#xff0c;其目标是模拟、延伸和扩展人的智能。本文…

是德(KEYSIGHT) N9040A、N9040B 信号分析仪

Keysight N9040B 的特性和规格包括&#xff1a; 功能性 3 Hz 至 8.4、13.6 或 26.5 GHz&#xff1b;使用是德科技智能混频器将频率扩展至 110 GHz&#xff0c;使用其他供应商的混频器将频率扩展至 THz10 MHz&#xff08;标准&#xff09;、25、40、255 或 510 MHz 分析带宽全…

第十八篇:一文说清楚ICMP的底层原理

作为程序员或者网络工程师&#xff0c;有时候无法访问对方主机&#xff1b;导致这个现象的有很多原因&#xff0c;那要排查具体的网络原因&#xff0c;可能会用到ping的指令。而ping的底层实现是互联⽹控制报⽂协议&#xff08;ICMP&#xff09;。 ICMP 全称是 Internet Contr…

清华系“仓颉”来袭:图形起源:用AI颠覆字体设计,推动大模型商业化落地

大模型如何落地&#xff1f;又该如何实现商业化&#xff1f;这一议题已成为今年科技领域的焦点话题。 在一个鲜为人知的字体设计赛道上&#xff0c;清华创业公司“图形起源”悄然实现了商业变现&#xff1a;他们帮助字体公司将成本降低了80%&#xff0c;生产速度提升了10倍以上…

网站优化门槛低了还是高了?

自从2015年刚接触网站时&#xff0c;从一无所知到现在无人指导&#xff0c;一直跌跌撞撞走过来&#xff0c;当年花了1500元找了广东一个网友用织梦CMS做了一个门户网站&#xff0c;记得那时一星期没下楼&#xff0c;把网站折腾的千疮百孔&#xff0c;而终逐步熟悉网站建设与搜索…

手机怎样改网络ip地址?内容详尽实用

随着网络技术的发展&#xff0c;更改手机IP地址已成为一种常见需求。本文将详细介绍如何在不同网络环境下更改手机IP地址&#xff0c;包括移动网络和WiFi网络&#xff0c;以及同时适用于两种网络的方法&#xff0c;内容详尽实用&#xff0c;干货满满。 一、适用于移动网络&…

sentinel微服务部署

一.启动nacos和redis 1.查看是否有nacos和redis docker ps -a2.启动nacos和redis docker start nacos docker start redis-6379 docker ps 二.使用openfeign项目 这里看我另一个博客OpenFeign微服务部署-CSDN博客&#xff0c;我把SpringSessiondemo复制后改为sentinel1…

钡铼技术R10工业4G路由在智能交通中的应用

随着物联网技术的迅猛发展&#xff0c;智能交通系统&#xff08;Intelligent Transportation System, ITS&#xff09;正逐渐成为现代城市交通管理的重要组成部分。智能交通系统通过集成先进的信息技术、通信技术、传感技术以及计算机处理技术&#xff0c;实现对交通信息的实时…

抖店API接口系列(商品详情数据),Json数据格式参考

抖店API接口系列中的商品详情数据接口允许第三方应用通过编程方式访问抖音小店的商品数据。这些数据通常包括商品的基本信息、价格、库存、用户评价等&#xff0c;并且会以JSON数据格式返回。以下是一个抖店商品详情数据JSON格式的参考示例&#xff1a; { "status":…

共享购模式:绿色积分引领消费新潮流

绿色消费浪潮席卷全球&#xff0c;绿色积分作为一种创新的激励机制&#xff0c;正受到越来越多消费者的青睐。在众多消费模式中&#xff0c;共享购模式凭借独特的绿色积分体系&#xff0c;不仅推动了绿色消费&#xff0c;还为消费者带来了更多实惠与额外收益&#xff0c;成为市…

解数独Python

怎样解数独&#xff1f; Python def setBoardFunc(puz): global grid print("Original Sudoku") for i in range(0, len(puz), 9): row puz[i:i9] temp [] for block in row: temp.append(int(block)) g…

简单理解程序地址空间:Linux 中的内存映射与页表解析

ps: Linux操作系统对于程序地址&#xff0c;物理地址的处理&#xff0c;对于源码&#xff0c;我也看不大懂&#xff0c;只是截取当我们进程发生正常缺页中断的时候的调用情况。本文中所有的源码都是进行截取过的&#xff0c;如果大家感兴趣可以去下载源码。 在Linux 操作系统 …

【Linux】wsl2安装ubuntu并移动安装位置

本文首发于 ❄️慕雪的寒舍 1.启用wsl 首先是启用你的wsl&#xff0c;参考本站wsl安装centos8中的教程; 启用wsl后&#xff0c;更新一下&#xff0c;并设置版本为2&#xff1b; wsl --update wsl --set-default-version 2 # 设置wsl版本为2&#xff0c;不然可能安装失败2.安…

【FPGA开发】Modelsim仿真精度的坑

问题所在 最近在使用黑金的AXU3EG板卡对着正点原子ZYNQ7020的例程进行移植学习。但在编写tb代码以及使用modelsim进行仿真时出了问题&#xff0c;发现我的实际波形与正点的对不上&#xff0c;仔细测量一下波形发现&#xff0c;我的系统时钟是6ns周期&#xff0c;而不是理想中的…

某象异形滑块99%准确率方案

注意,本文只提供学习的思路,严禁违反法律以及破坏信息系统等行为,本文只提供思路 如有侵犯,请联系作者下架 该文章模型已经上线ocr识别网站,欢迎测试!!,地址:https://yxlocr.windy-rain.cn/ocr/slider/6 所谓的顶象异形滑块,是指没有采用常规的缺口,使用各种形状的…

20.安卓逆向-frida基础-hook分析调试技巧2-hookDES

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…