【Linux】进程状态|优先级|进程切换|环境变量

这篇具有很好参考价值的文章主要介绍了【Linux】进程状态|优先级|进程切换|环境变量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


1. 运行队列和运行状态

💕 运行队列:

进程是如何在CPU上运行的:CPU在内核上维护了一个运行队列,进行进程的管理。让进程进入队列,本质就是将该进程的task_struct 结构体对象放入运行队列之中。这个队列在内存中,由操作系统自己维护。

task_struct 命令行参数,Linux,linux,运维,服务器

💕 运行状态:

  • 运行状态 进程PCB在运行队列里就是运行状态,不是说这个进程正在运行,才是运行状态。状态是进程内部的属性,所有的属性在PCB里,进程不只是占用CPU资源,也有可能随时要外设资源。
  • 阻塞状态 进程因为等待某种条件就绪而导致的一种不推进的状态——进程卡住了,此时的进程要通过等待的方式,等待具体的资源被别人用完之后,再被自己使用。阻塞状态进程的PCB被放在硬件的等待队列中。本质是对tack_struct对象放到不同的队列中!
    task_struct 命令行参数,Linux,linux,运维,服务器
  • 挂起状态 如果系统中存在许多进程,进程短期内不会被调度,代码和数据在短期内不会被执行,此时如果内存空间不足,操作系统就可以把代码和数据暂时保存到磁盘上,节省一部分空间,该进程暂时被挂起了,这就是挂起状态。对于阻塞状态和挂起状态,阻塞不一定挂起,挂起一定是阻塞。
    task_struct 命令行参数,Linux,linux,运维,服务器

因此,所谓的进程不同的状态,本质是进程在不同的队列之中,等待某种资源。


2. 进程状态

为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态。一个进程可以有几个状态(在Linux内核里,进程有时候也叫做任务)。

下面的状态在kernel源代码里定义:

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
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运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep)。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。
  • Z僵尸状态(zombie):这个状态是一个已经运行完的子进程,等待父进程回收他的返回值。

💕 运行状态R

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

💕 睡眠状态S

task_struct 命令行参数,Linux,linux,运维,服务器

当我们执行可执行程序后,在使用ps命令查看进程状态时,发现他是S状态,为什么我们的程序正在运行,进程却是睡眠状态呢?

task_struct 命令行参数,Linux,linux,运维,服务器

这是因为我们使用printf进行打印时,需要访问外设,但外设的速度是远远低于CPU的,所以进程大部分时间都在等待硬件资源的就绪,所以我们每次查看时,进程几乎都处于阻塞状态。

💕 磁盘休眠状态D

当内存中的空间不足时,操作系统会让一些进程进入挂起状态,但是,如果内存的空间严重不足时,进程挂起也解决不了问题,这个时候操作系统可能会将一些暂时挂起的进程或者没有被调度的进程杀掉。

但是如果要是此时挂起的进程正在向磁盘写入数据,或者进行一些重要的数据传递时,如果操作系统将这个进程杀死,那么磁盘就可能会将正在传递的数据丢弃,此时重要的数据就有可能因为操作系统将进程杀死导致重要数据的丢失。所以,我们的深度睡眠状态就是针对这种情况而生的。深度睡眠状态下的进程既不能被用户杀死,操作系统也无法将其杀死。只能通过断点,或者等待进程自己醒过来。

💕 暂停状态T

暂定状态也是阻塞状态的一种,下面我们来看一下如何让一个运行状态下的进程暂停:

task_struct 命令行参数,Linux,linux,运维,服务器

我们可以使用kill的19号指令将一个进程从运行状态变为暂停状态。

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

如果想要使得休眠中的进程重新恢复运行状态只需要执行kill的18号命令即可:

task_struct 命令行参数,Linux,linux,运维,服务器

这里我们可以看到进程又重新进入了运行状态,但是为什么进程重新进入云心状态后后面的 +号 消失了呢?

其实,进程状态后面的 +号 表示的是这个进程是一个前台进程,如果没有 +号就表示这个进程是一个后台进程。对于前台进程我们可以使用Ctrl + c将其杀死,但是对于后台进程,我们只能使用kill命令杀死他。

💕 追踪暂停状态t

属于暂停状态的一种,表示进程正在被追踪。最典型的一种就是gdb调试进程的时候。

💕 死亡状态X

表示一个进程结束运行,他的PCB以及代码和数据全部都被操作系统回收。

💕 僵尸状态Z

一个进程在退出的时候,不能立即释放全部的资源,但是该进程已经不会再被执行了,该进程的PCB中存放着他的各种各样的状态码,尤其是退出状态码。

僵尸状态就是为了在进程退出的时候能够让父进程或者操作系统拿到他退出状态码,然后释放PCB的一种状态。


3. 两种特殊的进程

僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程。僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态。

下面我们来举例看一下僵尸进程:

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

当我们杀掉子进程后,由于父进程并没有读取子进程的退出状态码,所以子进程进入了Z(僵尸状态),如果父进程一直不读取子进程的退出状态码,那么子进程就会变成僵尸进程

task_struct 命令行参数,Linux,linux,运维,服务器

僵尸进程的危害:

父进程如果一直不读取子进程的退出状态码,那子进程就一直处于Z状态。维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中。换句话说, Z状态一直不退出, PCB一直都要维护。那一个父进程创建了很多子进程,就是不回收,就会造成内存资源的浪费。


孤儿进程

父进程如果提前退出,那么子进程就会被操作系统领养,此时的子进程就称之为“孤儿进程”,孤儿进程被1号init进程领养,最后由init进程回收。

task_struct 命令行参数,Linux,linux,运维,服务器

这里我们可以看到:如果将父进程杀死后,父进程并不会进入僵尸状态,这是因为父进程在退出后会被父进程的父进程——bash所读取他的退出状态码。还有子进程被1号进程领养后会由前台进程变成后台进程。


4. 进程优先级

CPU的资源是有限的,但是内存中有很多进程都需要占用资源,所以需要给进程指定优先级来合理的分配资源。

CPU资源分配的先后顺序,就是指进程的优先级(priority)。优先级高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

task_struct 命令行参数,Linux,linux,运维,服务器

当我们输入ps -l/ps -al指令后就可以看到进程优先级相关的属性:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :该进程的父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值

下面我们重点介绍一下PRINI这两个变量,PRI(priority) 即进程的优先级,或者通俗点说就是程序被CPU执行的先后顺序,此值越小进程的优先级别越高。而NI(nice) 表示进程可被执行的优先级的修正数值。需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据。

PRI值越小越快被执行,那么加入NI值后,将会使得PRI变为: PRI(new)=PRI(old)+NI,这里我们需要注意的是:每个进程默认的PRI都是80,NI都是0,但是NI的波动范围是:[-20,19],PRI与NI的和越小,进程的优先级越高。

下面我们来看一下如何修改进程的优先级:

(1) 输入top指令

task_struct 命令行参数,Linux,linux,运维,服务器

(2) 输入r

task_struct 命令行参数,Linux,linux,运维,服务器

(3) 输入进程的id

task_struct 命令行参数,Linux,linux,运维,服务器

(4) 输入NI值

task_struct 命令行参数,Linux,linux,运维,服务器

这里我们还需要注意的是:普通用户无法直接修改NI的值,必须切换成root用户或者使用sudo提权执行top指令。


5. 进程切换

进程特性

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性: 多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行: 多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

进程切换

一个CPU里面存在一套硬件寄存器,宏观上寄存器分为用户可见,用户不可见。

计算机调度某个进程时,CPU会把这个进程的PCB地址加载到某个寄存器,也就是说,CPU内有寄存器可以只找到进程的PCB地址。

CPU里有一个eip寄存器(PC指针),指向当前执行指令的下一条指令的地址。

而进程运行的时候一定会产生很多的临时数据,但这些临时数据只属于当前进程,虽然CPU内部只有一套寄存器硬件,但是寄存器保存的数据只属于当前进程,也就是说,寄存器硬件不是寄存器内的数据,这是两码事,寄存器被所有进程共享,但是寄存器里的数据时每个进程各自私有的。

时间片引出——进程在运行的时候占有CPU,但是却不是一直占有到进程结束,进程都有自己的时间片!因为时间片的存在,进程会出现没有被执行完就被拿下去的情况,这时候问题来了:这个进程下一次如何在次回到CPU继续运行:

进程切换的时候,需要先进行上下文保护,这里的上下文指的是CPU里的寄存器的数据,而不是寄存器,这里简单理解为临时数据保存至PCB里,而当进程恢复运行的时候,要进行上下文的恢复,该进程在次回到CPU继续运行时,重新加载恢复这些数据。


6. 环境变量的基本概念

环境变量(environment variables) 一般是指在操作系统中用来指定操作系统运行环境的一些参数。

  • 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。

当我们平常执行自己的可执行程序时,必须在前面指定路径来执行,但是执行Linux中的指令时,并不需要指定路径,这是什么原因呢?

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

其实,在Linux下的各种指令和我们平常自己编写代码生成的可执行程序没有什么区别,他也是个可执行程序,但是因为系统中存在PATH环境变量,这些指令的地址都被存放在环境变量中,当我们调用这些指令时,系统会自定去PATH中寻找这些指令。


7. PATH环境变量

PATH是由一堆目录组成的,各目录之间用冒号 “:” 隔开。 当执行某个 Linux 命令时,Linux 会依照 PATH 环境变量中包含的目录依次搜寻该命令的可执行文件,一旦找到,即正常执行;反之,则提示无法找到该命令。

💕 查看环境变量:echo $PATH

task_struct 命令行参数,Linux,linux,运维,服务器

💕 添加PATH环境变量:

(1) 直接添加

task_struct 命令行参数,Linux,linux,运维,服务器

一般不建议使用这种方法添加,因为我们写的程序没有经过测试,容易污染指令池。

(2) 使用export命令添加

task_struct 命令行参数,Linux,linux,运维,服务器

在这里我们还需要注意的是,我们不能直接写成这样:export PATH=/home/Chenjiale/lesson2-22,这样会导致把系统默认的环境变量PATH覆盖掉,我们默认的那些指令就不能直接使用了,只能通过指定路径的方式来使用。

💕 系统中的其他环境变量:

  • HOSTNAME: 主机名
  • USER: 当前用户名
  • PWD: 当前系统路径
  • HOME: 当前用户的家目录
  • HISTSIZE: shell 能记忆的最多历史命令的条数

查看所有的环境变量:env指令

task_struct 命令行参数,Linux,linux,运维,服务器

下面我们来看一下环境变量是在系统中的哪个文件夹下面的:

task_struct 命令行参数,Linux,linux,运维,服务器

实际上,当我们在登录 shell 时,操作系统会让我们当前的 shell 进程执行 .bash_profile 中的内容,而 .bash_profile 又会调用执行 .bashrc,它们会将对应的环境变量导入到 shell 进程的上下文环境中。所以,如果我们上面不小心将 $PATH 覆盖掉了也不用担心,重新登录 shell 就好了。

环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量,这些变量往往具有特殊功能,且能够一直被 bash 以及 bash 的子进程访问。环境变量具有全局属性的根本原因是环境变量会被子进程继承。


8. 设置和获取环境变量

💕 设置和取消环境变量:

如果我们直接在命令行中定义一个变量,那么这个变量则是本地变量,本地变量只在bash进程中有效。

task_struct 命令行参数,Linux,linux,运维,服务器

当然我们可以使用export直接将本地变量设置为环境变量,同时,也可以直接使用export来定义一个环境变量。

export 已存在的环境变量 将本地变量设置为环境变量

export 新的变量 直接定义一个环境变量

task_struct 命令行参数,Linux,linux,运维,服务器

如果我们不想要这个变量,可以直接使用unset指令来取消变量,当然我们也可以使用set指令来查看所有变量。

task_struct 命令行参数,Linux,linux,运维,服务器

💕 获取环境变量:

获取环境变量除了可以使用echo $环境变量名之外,还可以使用一个函数getenv()来获取。

task_struct 命令行参数,Linux,linux,运维,服务器

下面我们举例来演示一下:

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

在命令行上运行mytest时候,bash就是一个系统进程,mytest也会变成一个进程(通过fork创建父子进程),是bash的子进程。而环境变量具有全局属性的根本原因是会被子进程继承下去,因为环境变量定义给bash,而子进程会全部继承下去,这就被称为环境变量。所以环境变量具有全局性,而本地变量只会在当前进程(bash内)有效。

为了不同的应用场景,让bash替我们寻找指令路径,例如:身份认证;有些子进程需要用到这些信息,确认当前用户的信息。

下面我们来举一个例子:

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

这里我们一定要使用su -来验证,我们可以使用getenv函数来获得当前的Linux用户,判断其是否具有某种权限,然后再执行对应的操作。


9. 命令行参数

我们知道在C语言中,main函数也是有参数的,不过我们平常一般都不需要手动传参,而是被系统/父进行行传参的。所以,这个参数可能会被大多数人忽略。

int main(int argc,char* argv[],char* env[])

这里我们可以先来看一下前两个参数,第一个参数是指第二个参数——指针数组中的元素个数。这里我们可以先来看一下指针数组中的每一个元素存的是什么。

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

其实这里的argv中的每一个元素都指向的是一个字符串,argc用来指定数组中元素的个数,他们配合可以使用-a -b -c 类似的选项功能。

下面我们来看一下最后一个指针数组中的内容:

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器

这里我们看到的是:打印出来的就是环境变量的内容。这是因为env接收的就是父进程传递过来的环境变量的参数。

最后,还有一种获取环境变量内容的方式就是通过环境变量表environ,这里我们直接来验证一下即可。

task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器
task_struct 命令行参数,Linux,linux,运维,服务器文章来源地址https://www.toymoban.com/news/detail-786890.html


到了这里,关于【Linux】进程状态|优先级|进程切换|环境变量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】进程状态、进程优先级和进程切换

    作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等 座右铭:松树千年终是朽,槿花一日自为荣。 目标:了解冯诺依曼体系结构与操作系统,掌握Linux的进程 毒鸡汤:一花凋零荒芜不了整个春天,一次挫折也荒废不了整个人生。 望小伙伴们点赞👍收藏✨加关注哟💕

    2024年02月04日
    浏览(18)
  • 2.【Linux】(进程的状态||深入理解fork||底层剖析||task_struct||进程优先级||并行和并发||详解环境变量)

    Linux把所有进程通过双向链表的方式连接起来组成任务队列,操作系统和cpu通过选择一个task_struct执行其代码来调度进程。 1.运行态:pcb结构体在运行或在运行队列中排队。 2.阻塞态:等待非cpu资源就绪(硬盘,网卡等资源) 3.挂起态:一个进程对应的代码和数据被操作系统因

    2024年01月22日
    浏览(11)
  • 【Linux】关于进程的理解、状态、优先级和进程切换

    进程不同的状态本质都是在满足不同的运行场景的 1.运行队列 运行队列 进程如何在CPU上运行的:CPU在内核上维护了一个运行队列,进行进程的管理。让进程入队列,本质就是将该进程的task_struct 结构体对象放入运行队列之中。 2.运行状态 运行状态 进程PCB在运行队列里就是运

    2024年02月04日
    浏览(15)
  • 【Linux】Linux进程的理解 --- 冯诺依曼体系、进程描述符、状态、优先级、切换…

    如果不改变自己,就别把跨年搞的和分水岭一样,记住你今年是什么吊样,明年就还会是什么吊样!!! 1.冯诺依曼体系结构中的存储器指的是内存,带电存储,具有掉电易失的特点。 2.CPU中含有能够解释计算机指令的指令集,指令集又可分为精简指令集和复杂指令集,这也

    2024年01月25日
    浏览(16)
  • 【Linux】进程优先级 + 环境变量

    在学完进程状态之后,本章我们将来学习一下环境变量,还有进程优先级等🙋🙋🙋…… 本文实验系统: CentOS 7.6 ~ 优先级是权限吗? 在之前我们讲解过什么是权限:👉 传送门 我们这里讲的优先级并不是权限,那么优先级到底是什么呢? 如果我们说权限是能不能的问题的

    2024年02月05日
    浏览(20)
  • 【Linux】环境变量和进程优先级

    目录 环境变量 什么是环境变量 系统结构 系统接口 深度解析 命令行参数 进程优先级 优先级查看 优先级修改 进程间的概念 🍮平时在使用  Linux  的时候,总会使用  ls  、 pwd  这类的命令,我们也都知道这些命令也是  C  语言写的,但是为什么我们自己写的可执行程序需

    2023年04月27日
    浏览(23)
  • 【Linux】进程优先级 && 命令行参数 && 环境变量

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 文章目录 前言 一、进程优先级 1.1、进程优先级的基本概念 1.2、优先级 VS 权限 1.3、为什么要有优先级? 1.4、Linux的优先级的特点 查看方式 1.5、PRI and NI 1.6、用top命令更改已存在进程的nice 1.7、其

    2024年03月25日
    浏览(18)
  • 【Linux】环境变量与进程优先级知识点

    环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。 PATH : 指定命令的搜索路径 HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录) SHELL : 当前Shell,它的值通常是/bin/bash USER:记录了当前登录的用户是谁 主要以PATH进行学习

    2023年04月23日
    浏览(13)
  • 【Linux】探索Linux进程优先级 | 环境变量 |本地变量 | 内建命令

    最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 🎉博客主页:小智_x0___0x_ 🎉欢迎关注:👍点赞🙌收藏✍️留言 🎉系列专栏:Linux入门

    2024年02月04日
    浏览(22)
  • 【Linux进行时】环境变量and进程优先级

    ❓首先一个问题:我写的代码(这个代码很简单,不用管)编译之后运行的时候为什么要带./ ? 或者说我怎么才可以让我不用带./ ? 💡.代表当前文件下,/是文件分隔符,这是用相对路径的方式来访问,所以我们也可以用绝对路径 myproc和ls都是指令,ls可以直接输入,但是我

    2024年02月08日
    浏览(16)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包