操作系统 实验二 观察Linux进程状态

实验二 观察Linux进程状态

一、实验目的

在本实验中学习Linux操作系统的进程状态,并通过编写一些简单代码来观察各种情况下,Linux进程的状态,进一步理解进程的状态及其转换机制。

二、实验环境

硬件环境:计算机一台,局域网环境;

软件环境:Linux Ubuntu操作系统,gcc编译器。

三、实验内容和实验步骤

  1. Linux进程状态及其相互转换

    Linux中,进程有以下6中状态。

    Linux系统中的进程主要有以下六种状态。

    • (1)TASK_RUNNING(可运行状态)。正在运行的进程或在可运行进程队列(run_queue)中等待运行的进程处于该状态。它实际上包含一般操作系统原理教材中所谓进程三种基本状态中的运行态和就绪两种状态。

    • 当CPU空闲时,进程调度程序只在处于该状态的进程中选择优先级最高的进程运行。Linux中运行态的进程可以进一步细分为3种:内核运行态、用户运行态和就绪态。

    • (2)TASK_INTERRUPTIBLE(可中断阻塞状态)。处于可中断阻塞状态的进程排成一个可中断阻塞状态进程队列,该队列中的阻塞进程在资源有效时,能被信号或中断唤醒进入到运行态队列。

    • (3)TASK_UNINTERRUPTIBLE(不可中断阻塞状态)。不可中断指的是进程不响应信号。处于不可中断阻塞状态的进程排成一个不可中断阻塞状态进程队列。该队列中的阻塞进程,不可被其他进程唤醒,只有被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。

    • (4)TASK_STOP/TASK_TRACED(暂停状态)。当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号,让进程转换到可运行状态。

    • (5)TASK_DEAD-EXIT_ZOMBIE(僵死状态)。表示进程停止但尚未消亡的一种状态。此时进程已经结束运行并释放掉大部分资源,但父进程尚未收回其PCB。在进程退出时,将状态设为TASK_ZOMBIE,然后发送信号给父进程,由父进程再统计其中的一些数据后,释放它的task_struct结构。处于该状态的进程已经终止运行,但是父进程还没有询问其状态。

    • (6)TASK_DEAD-EXIT_DEAD(退出状态),处于此状态的进程即将被销毁,EXIT_ DEAD非常短暂,几乎不可能通过ps命令捕捉到。

    • Linux中进程的状态转换过程如下图所示:

    • 在这里插入图片描述

    • 可以使用ps命令查看进程在系统中的状态。在ps命令的显示结果中,5中字符分别代表5种不同的进程状态。

      (1)R(TASK_RUNNING):可执行状态或运行状态

      (2)S(TASK_INTERRUPTIBLE):可中断阻塞状态,可响应中断、接收信号(如SIGKILL)

      (3)D( TASK_ UNINTERRUPTIBLE):不可中断阻塞状态,只能响应中断

      (4)T( TASK_ STOPPED/ TASK_ TRACED):暂停状态或跟踪状态

      (5)Z( TASK_ DEAD/EXIT_ZOMBIE):退出状态,进程成为僵尸进程

      注:在状态字符后面如果带+(如S+),表示进程是前台运行,否则是后台运行

  2. 观察进程状态

    • (一)查看“运行”状态(R)

      #include<unistd.h>
      #include<stdio.h>
      int main()
      {
          int i=0,j=0,k=0;
          for(i=0;i<1000000;i++)
          {
              for(j=0;j<1000000;j++)
              {
                  k++;
                  k--;
              }
          }
      } 
      
    • 在这里插入图片描述

    • (二)查看“暂停”状态(T)

      • 运行run_status进程,其进入R状态:
      • 使用kill命令,向run_status进程发送SIGSTOP信号,并使用ps命令观察其状态(进入了T状态)
      • 使用kill命令,向run_status进程发送SIGSCON信号,并使用ps命令观察其状态(恢复到R状态)
      • 在这里插入图片描述
    • (三)查看“可中断阻塞”状态(S)

      #include<unistd.h>
      #include<stdio.h>
      int main()
      {
          sleep(30);
          return;
      }
      
      • 在这里插入图片描述
    • (四)查看“不可中断阻塞”状态(D)

      #include<unistd.h>
      #include<stdio.h>
      int main()
      {
          if(vfork()==0)
          {
              sleep(30);
              return;
          }
      }
      

      在这里插入图片描述

    • (五)查看“僵尸”进程(Z)

      #include<unistd.h>
      #include<stdio.h>
      int main()
      {
          if(fork())
          {
              sleep(30);
      	}
      }
      
      • 在这里插入图片描述

四、实验总结

分析为什么出现以上现象,并对其进行总结:什么时候出现运行状态、暂停状态、可中断阻塞状态、不可中断阻塞状态、僵尸状态?

  1. 运行状态:因为在查看状态时长循环仍然在执行,进程还没有执行完毕

    暂停状态:因为用了命令行向该进程发送了暂停信号

    可中断阻塞状态:因为直接对进程使用sleep命令,则进程可以再通过信号直接唤醒。

    不可中断阻塞状态:因为对子进程进行了sleep,这时子进程进入阻塞状态,而父进程进入不可中断阻塞状态。父进程不能被信号唤醒只能被中断唤醒,不能被其他进程唤醒。因为子进程可能正在阻塞,不能直接唤醒父进程

    僵死状态:因为子进程已经结束了,但是父进程正在阻塞,所以没有对子进程的信号进行相应进行后续的处理,所以子进程处于僵死状态。

  2. 出现各种状态的情况:

    (1)可运行状态R:当创建一个新进程,系统调用创建原语,该进程为就绪状态,或者进程执行唤醒原语,把处于阻塞状态进程的状态改为就绪状态,或者进程获得CPU正在运行,处于执行状态。

    (2)可中断阻塞状态S:进程调用阻塞原语把状态改为阻塞状态,在资源有效时,能被信号或中断唤醒进入到运行态队列。

    (3)不可中断阻塞状态D:进程调用阻塞原语把状态改为阻塞状态,不可被其他进程唤醒,只有被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。

    (4)暂停状态T:当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号,让进程转换到可运行状态。

D:进程调用阻塞原语把状态改为阻塞状态,不可被其他进程唤醒,只有被使用wake_up()函数明确唤醒时才能转换到可运行的就绪状态。

(4)暂停状态T:当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号,让进程转换到可运行状态。

(5)僵死状态Z:表示进程停止但尚未消亡的一种状态。此时进程已经结束运行并释放掉大部分资源,但父进程尚未收回其PCB。

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jian圣楠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值