【Linux篇】第六篇——Linux下的进程(冯若依曼体系结构+操作系统+进程相关内容)(二)

简介: 【Linux篇】第六篇——Linux下的进程(冯若依曼体系结构+操作系统+进程相关内容)

进程状态


查看进程的状态


可以使用ps aux或者ps axj命令查看进程的状态

image.png

不同进程的状态


进程有很多的不同的状态,在kernel源代码中是这样定义的

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运行状态

这里并不是指进程一直在运行,而是指进程在运行队列中,可随时被CPU调度

模拟实现:

image.png

  • S睡眠状态

这种状态是一种浅度睡眠,此时的进程是在被阻塞的状态中,等待着条件的满足过后进程才可以运行。在这种状态下可以被信号激活,也可以被信号杀死。

模拟实现:

可以使用sleep() 系统调用接口使得一个进程睡眠

#include <stdio.h>
int main()
{
    while (1) 
    {
      printf("hello world\n");
        sleep(100); // 睡眠100秒
    }
    return 0;
}

  • D磁盘休眠状态

这种状态是一种深度休眠状态,是不可以被大段的,在这种状态下即使是操作系统发送信号也不可以杀死进程,只能等待进程自动唤醒才可以。

模拟实现:

这种情况没法模拟,一般都是一个进程正在对IO这样的外设写入或者读取的时候,为了防止操作系统不小心杀掉这个进程,所以特地创建出一个状态保护这个进程。


总结:我们把从运行状态的task_struct放到等待队列中,就叫做挂起等待(阻塞),从等待队列放到运行队列,被COU调度就叫做唤醒进程!!!

  • T停止状态

可以通过发送SIGSTOP信号让进程停下

模拟实现

1. kill -SIGSTOP PID // 停止进程
2. kill -SIGSONT PID // 继续进程

image.png

  • x死亡状态

进程停止执行,进程不能投入运行。通常这种状态发生在接受到SIGSTOP、SIGTSTP、SIGTTIN、SIGOUT等信号的时候。

模拟实现

可以使用kill -9 PID即可杀死一个进程

  • Z僵死状态

后面详细讲解

孤儿进程


孤儿进程的概念

一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

孤儿进程会产生危害嘛?

孤儿进程是没有父进程的进程,孤儿进程这个重任就落在了init进程身上,init进程就好像是一个民政局,专门负责处理孤儿进程的善后工作。每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为init,而init进程会循环地wait()它的已经退出地子进程。这样,当一个孤儿进程凄凉地结束了其生命周期地时候,init进程就会代表党和政府出现处理它地一切善后工作,因此孤儿进程并不会有什么危害。

模拟实现:

模拟实现让父进程比子进程提前退出。

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
int main()
{
    pid_t pid;
    //创建一个进程
    pid = fork();
    //创建失败
    if (pid < 0)
    {
        perror("fork error:");
        exit(1);
    }
    //子进程
    if (pid == 0)
    {
        printf("I am the child process.\n");
        //输出进程ID和父进程ID
        printf("pid: %d\tppid:%d\n",getpid(),getppid());
        printf("I will sleep five seconds.\n");
        //睡眠5s,保证父进程先退出
        sleep(5);
        printf("pid: %d\tppid:%d\n",getpid(),getppid());
        printf("child process is exited.\n");
    }
    //父进程
    else
    {
        printf("I am father process.\n");
        //父进程睡眠1s,保证子进程输出进程id
        sleep(1);
        printf("father process is  exited.\n");
    }
    return 0;
}

运行结果:

image.png

父进程退出后,子进程被1号init进程收养。

僵尸进程


为什么会出现僵尸进程?

任何一个子进程(除init外)在exit()之后,并非马上消失,而是留下一个称为僵尸进程的数据结构,等待父进程处理。这是每个子进程在结束时都要经过的阶段。如果子进程在exit之后,父进程并没有来得及处理,这时用ps命令就能看到子进程的状态时"Z“。如果父进程能及时处理,可能用PS命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态.如果父进程在子进程结束之前退出,则子进程由init接管。

僵尸进程的概念

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程地状态信息,那么子进程地进描述符仍然保存在系统种,这种进程称之为僵死进程。

僵尸进程的危害

进程已经结束了,但是进程控制块PCB却还是没有被释放,这时就会浪费这一块资源空间。所以会导致操作系统的内存泄漏。

如何消灭僵尸进程?

例如有个进程,它定期的产生一个子进程,这个子进程需要做的事情很少,做完它该做的事情之后就推出了,因此这个子进程的生命周期很短,但是父进程只管生成新的子进程,至于子进程退出之后的事,则一概不问,这样系统运行上一段时间,系统就会存在很多僵死进程。倘若用ps命令查看的话,就会看到很多状态为Z的进程。严格来说,僵死进程并不是问题的根源,罪魁祸首是产生大量僵死进程的那个父进程。因此,当我们寻求如何消灭系统中大量的僵死进程时,答案就是把产生大量僵死进程的那个元凶枪毙掉(也就是通过kill发送SIGTERM或者SIGKILL信号)。枪毙元凶进程后,它产生的僵死进程就变成了孤儿进程,这些孤儿进程会被init进程接管,init进程会wait()这些孤儿进程,释放他们占用的系统进程表中的资源。

模拟实现:

模拟实现让子进程比父进程提前退出。

#include <stdio.h>    
#include <stdlib.h>    
#include <unistd.h>    
int main()    
{    
    pid_t pid = fork();    
    if (pid == 0) {    
        int count = 5;    // 子进程运行5次
        while (count --) {    
            printf("I am a child, pid=%d, ppid=%d\n", getpid(), getppid());    
            sleep(1);    
        }    
        exit(0);    
    } else {              // 父进程一直运行
        while (1) {    
            printf("I am a father, pid=%d, ppid=%d\n", getpid(), getppid());    
            sleep(1);    
        }    
    }
    return 0;    
}

可以使用shell脚本监控

while :; do ps axj | head -1 && ps axj | grep test | grep -v grep; sleep 1; echo "############"; done

运行结果

image.png

进程状态转化

image.png

进程优先级


进程优先级的概念


进程优先级的定义

进程优先级为进程获取CPU资源分配的先后顺序,即进程的优先权,优先级高的进程可以优先执行的权力。

程优先级的意义

之所以会存在进程优先级,是因为cpu本身的资源分配是有限的,一个cpu一次只能run一个进程,但是一个操作系统中可能会有成千上百的进程,所以需要存在进程优先级来确定每一个进程获得cpu资源分配的顺序。

查看进程优先级


在linux或者unix系统中,用ps -al或者ps -l命令则会类似输出以下几个内容:

image.png

其中我们来了解几组关于进程优先级的相关信息

  • UID:执行者的身份,用户标识符
  • PID:进程的编号
  • PPID:进程的父进程的编号
  • 其中我们来了解几组关于进程优先级的相关信息
  • UID:执行者的身份,用户标识符
  • PID:进程的编号
  • PPID:进程的父进程的编号

PRI和NI


PRI和NI是一组对应的概念。NI的取值会影响到PRI的最终值。

PRI代表进程被CPU执行的先后顺序,并且PRI越小进程的优先级越高。NI代表nice值,表示进程的优先级的修改数值。所以两者之间有一个计算公式:(new)PRI=(old)PRI+NI。

注意:

  • PRI在系统中默认初始化为80
  • NI的取值范围为-20~19,一共40个级别
  • 当NI值为负值,那么该程序将会优先级值变小,即其优先级会变高,则其越快被执行。

例如:

image.png

默认进程的PRI为80,当前的nice值为10,所以最终的PRI为90.

总结:在linux环境下,我们一般说调整进程的优先级,就是在调整nice值。nice值决定性的影响到进程优先级。

更改nice值


通过top命令更改nice值

  • 使用top命令后,按r键,要求你输入需要更改进程优先级的进程PID
  • 输入需要更改进程优先级的进程PID

image.png

  • 输入你想要更改后的nice值,按回车键即可

image.png

  • 当然还有很多方法去更改nice值,这里不做过多讲解,感兴趣的同学可以去查查相关知识。

进程相关概念


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

今天就到这里啦,如果对你有帮助的话,那就一赞三连吧,你的支持就是我持续更新的动力,爱你吆!!!

09c2e23791ba4f4b81b49be6087e659f.png


相关文章
|
2月前
|
Ubuntu 物联网 Linux
从零安装一个Linux操作系统几种方法,以Ubuntu18.04为例
一切就绪后,我们就可以安装操作系统了。当系统通过优盘引导起来之后,我们就可以看到跟虚拟机中一样的安装向导了。之后,大家按照虚拟机中的顺序安装即可。 好了,今天主要介绍了Ubuntu Server版操作系统的安装过程,关于如何使用该操作系统,及操作系统更深层的原理,还请关注本号及相关圈子。
|
2月前
|
监控 Ubuntu Linux
什么Linux,Linux内核及Linux操作系统
上面只是简单的介绍了一下Linux操作系统的几个核心组件,其实Linux的整体架构要复杂的多。单纯从Linux内核的角度,它要管理CPU、内存、网卡、硬盘和输入输出等设备,因此内核本身分为进程调度,内存管理,虚拟文件系统,网络接口等4个核心子系统。
228 0
|
2月前
|
Unix 物联网 Linux
都什么年代了,你还不懂啥是Linux操作系统
至于华为鸿蒙操作系统是不是独树一帜,这个留给各位阅读本文的网友们来讨论
74 0
|
2月前
|
Web App开发 缓存 Rust
|
2月前
|
安全 Linux iOS开发
linux属于什么操作系统
Linux是一种自由和开放源代码的操作系统,具有高度的灵活性和可定制性。与常见的操作系统如Windows和macOS相比,Linux具有自由、安全和稳定等优势。Linux已广泛应用于服务器、桌面电脑、超级计算机和嵌入式设备等领域,并且在未来的发展前景广阔。由于其自由和开放源代码的特性,Linux还促进了计算机技术和社区的发展,为全球的计算机用户提供了更多的选择和可能性。
|
2月前
|
Ubuntu Unix Linux
操作系统的最强入门科普(Unix/Linux篇)
下期文章,小枣君会重点聊聊Windows和macOS那条线。敬请关注! 如果大家觉得文章不错,还请帮忙多多转发!谢谢!
|
2月前
|
安全 Ubuntu Unix
关于Linux操作系统,你必须要知道的事
我们可以看到无论是Debian还是Buildroot都有各自的特点,为客户提供了更大的选择空间和灵活性,大家可以根据自己的需求选择合适的版本来满足终端用户的体验和功能需求。从平技术将会一直关注更多更安全、灵敏、易于开发的Linux版本,做好适配工作,不断为客户带来“简单开发、方便应用”的使用体验。
|
2月前
|
安全 Ubuntu Linux
如何安装Linux操作系统?
此时,您可以选择重新启动计算机,然后从硬盘上的Linux系统启动。以上是一个大致的安装过程。请注意,不同的Linux发行版可能会在细节上有所差异,因此在进行安装之前,请确保您阅读并理解了相应发行版的安装指南或文档。
|
7月前
|
Linux 数据库 Perl
【YashanDB 知识库】如何避免 yasdb 进程被 Linux OOM Killer 杀掉
本文来自YashanDB官网,探讨Linux系统中OOM Killer对数据库服务器的影响及解决方法。当内存接近耗尽时,OOM Killer会杀死占用最多内存的进程,这可能导致数据库主进程被误杀。为避免此问题,可采取两种方法:一是在OS层面关闭OOM Killer,通过修改`/etc/sysctl.conf`文件并重启生效;二是豁免数据库进程,由数据库实例用户借助`sudo`权限调整`oom_score_adj`值。这些措施有助于保护数据库进程免受系统内存管理机制的影响。
|
7月前
|
Linux Shell
Linux 进程前台后台切换与作业控制
进程前台/后台切换及作业控制简介: 在 Shell 中,启动的程序默认为前台进程,会占用终端直到执行完毕。例如,执行 `./shella.sh` 时,终端会被占用。为避免不便,可将命令放到后台运行,如 `./shella.sh &`,此时终端命令行立即返回,可继续输入其他命令。 常用作业控制命令: - `fg %1`:将后台作业切换到前台。 - `Ctrl + Z`:暂停前台作业并放到后台。 - `bg %1`:让暂停的后台作业继续执行。 - `kill %1`:终止后台作业。 优先级调整:
402 5

热门文章

最新文章