Linux进程(三) --- 状态和优先级

运行,阻塞,挂起

运行 (Running)

当一个进程处于运行状态时,它正在使用CPU执行指令。进程在以下两种情况下可能被认为是运行状态:

  1. 实际运行(Running on CPU): 进程当前正在CPU上执行。
  2. 可运行(Runnable): 进程准备好运行,只是在等待CPU资源。

在任务管理器中,处于运行状态的进程通常会显示为R

阻塞 (Blocked)

当一个进程被阻塞时,它正在等待某些事件完成,无法继续执行。阻塞通常发生在进程需要等待某种资源的情况,例如:

  • 等待I/O操作完成(如读取文件或网络数据)
  • 等待某个信号或条件变量

在任务管理器中,阻塞状态的进程通常会显示为D(不可中断的睡眠)或S(可中断的睡眠)。

挂起 (Suspended)

挂起状态表示进程已被暂停,暂时停止了运行。挂起可以通过以下方式发生:

  • 显式挂起(Suspended by signal): 进程收到一个挂起信号(如SIGSTOP),并停止执行,直到收到继续信号(如SIGCONT)。
  • 后台挂起(Suspended by job control): 用户在shell中使用命令(如Ctrl+Z)将前台进程挂起并转入后台。

在任务管理器中,挂起状态的进程通常会显示为T(stopped by job control signal)。

总结

  • 运行(Running): 进程正在使用CPU或准备使用CPU。
  • 阻塞(Blocked): 进程在等待某个事件或资源。
  • 挂起(Suspended): 进程已被暂停,等待继续执行的信号。

进程的状态与切换

  • 运行(Running):

    R (Running): 进程正在CPU上运行或准备运行。
  • 可中断睡眠(Interruptible Sleep):

    S (Sleeping): 进程正在等待某个事件(如I/O操作)完成,可以被信号中断唤醒。
  • 不可中断睡眠(Uninterruptible Sleep):

    D (Uninterruptible sleep): 进程在等待某个无法中断的事件(如设备I/O操作)完成,通常不会响应信号。
  • 停止(Stopped):

    T (Stopped): 进程已被停止,可以由用户或调试器发出信号(如SIGSTOP)造成。
  • 僵尸(Zombie):

    Z (Zombie): 进程已终止,但其进程表项仍然保留,等待父进程读取其退出状态。
  • 挂起(Suspended):

    挂起状态是停止状态的一种表现,通常是通过Ctrl+ZSIGSTOP信号实现的。

进程状态切换的方法

进程状态之间的切换是由内核根据进程的行为和系统事件进行管理的。常见的状态切换及其触发条件如下:

  • 从运行(Running)到可中断睡眠(Sleeping):

    • 进程执行阻塞I/O操作,如读写文件,等待网络数据等。
    • 调用系统调用如sleep()select()poll()或等待某个事件。
  • 从可中断睡眠(Sleeping)到运行(Running):

    • I/O操作完成或事件发生,唤醒等待的进程。
    • 进程收到一个信号,导致其从睡眠状态被中断。
  • 从运行(Running)到不可中断睡眠(Uninterruptible sleep):

    • 进程执行某些不可中断的系统调用或等待硬件设备响应。
  • 从不可中断睡眠(Uninterruptible sleep)到运行(Running):

    • 不可中断的系统调用或硬件设备操作完成,进程重新变为可运行。
  • 从运行(Running)到停止(Stopped):

    • 进程收到SIGSTOPSIGTSTP(由Ctrl+Z触发)等信号。
    • 用户在调试过程中手动暂停进程。
  • 从停止(Stopped)到运行(Running):

    • 进程收到SIGCONT信号,继续执行。
  • 从运行(Running)到僵尸(Zombie):

    • 进程正常退出(调用exit()),但其父进程尚未调用wait()waitpid()读取其退出状态。
  • 从僵尸(Zombie)到终止(Terminated):

    • 父进程调用wait()waitpid()读取僵尸进程的退出状态后,僵尸进程彻底从系统中移除。

僵尸进程

什么是僵尸进程?

僵尸进程是已经终止执行但仍然在进程表中保留的进程。它保留在进程表中的原因是为了让其父进程读取它的退出状态。这种状态的进程不会占用系统资源(如CPU和内存),但会占用一个进程表项。

僵尸进程的产生

当一个进程结束时(通过调用exit()或返回main()函数),操作系统会清理它所占用的大部分资源,但仍会保留一个记录,包括进程的退出状态。这是因为Unix-like系统采用了父子进程关系的机制,父进程需要通过调用wait()waitpid()系统调用来读取子进程的退出状态。

具体步骤如下:

  1. 子进程终止: 子进程调用exit()终止运行。
  2. 内核保留进程信息: 内核会保留子进程的退出状态和其他信息,以便父进程读取。
  3. 子进程进入僵尸状态: 子进程的状态变为僵尸状态,直到父进程读取它的退出状态。
  4. 父进程读取退出状态: 父进程调用wait()waitpid()读取子进程的退出状态,内核随即清理僵尸进程的剩余信息,从进程表中移除该进程。

为什么会有僵尸进程?

僵尸进程存在的主要原因是确保父进程能够得到子进程的退出信息。这对于进程间通信和进程管理非常重要。通过这种机制,父进程可以知道子进程是正常终止还是由于错误终止,并可以基于此信息进行相应的处理。

僵尸进程的问题

虽然僵尸进程本身不占用大量系统资源,但大量的僵尸进程会导致进程表项耗尽,从而阻止系统创建新进程。因此,管理僵尸进程非常重要。

如何处理僵尸进程?

  • 确保父进程读取子进程的退出状态: 父进程应该使用wait()waitpid()系统调用来处理子进程的退出状态。如果父进程没有执行这一步,子进程就会变成僵尸进程。
  • 孤儿进程和init进程: 如果父进程终止而没有处理子进程的退出状态,子进程会成为孤儿进程。孤儿进程会被init进程(PID为1)接管,init进程会自动处理这些子进程的退出状态,从而避免僵尸进程的产生。
  • 信号处理: 可以通过设置父进程的信号处理函数,当子进程终止时捕获SIGCHLD信号并调用waitpid()来处理退出状态。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>void handle_sigchld(int sig) {// 使用waitpid处理所有已终止的子进程while (waitpid(-1, NULL, WNOHANG) > 0) {// Nothing to do here}
}int main() {signal(SIGCHLD, handle_sigchld);  // 注册SIGCHLD信号处理程序pid_t pid = fork();if (pid < 0) {perror("fork failed");exit(1);} else if (pid == 0) {// 子进程printf("Child process: %d\n", getpid());exit(0);} else {// 父进程printf("Parent process: %d\n", getpid());sleep(10);  // 让父进程等待足够长的时间}return 0;
}

孤儿进程

孤儿进程(Orphan Process)是指其父进程已经终止,而它自身仍然在运行的进程。当一个进程终止时,其子进程不会自动终止,而是会变成孤儿进程。为了确保系统的稳定性和资源的合理利用,孤儿进程会被系统中的一个特殊进程,即init进程(PID为1)接管。

孤儿进程的处理

当孤儿进程被init进程接管后,init进程会成为这些孤儿进程的新父进程,并负责处理它们的退出状态,避免它们变成僵尸进程。

具体过程

  1. 父进程终止: 一个进程终止而其子进程仍在运行。
  2. 孤儿进程产生: 子进程因为其父进程终止而成为孤儿进程。
  3. init进程接管: 操作系统会将孤儿进程的父进程重新设置为init进程。
  4. init进程处理: 当这些孤儿进程终止时,init进程会调用wait()waitpid()读取它们的退出状态,从而防止它们变成僵尸进程。

示例

下面是一个简单的C语言示例,演示了孤儿进程的产生过程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>int main() {pid_t pid = fork();if (pid < 0) {// fork失败perror("fork failed");exit(1);} else if (pid == 0) {// 子进程printf("Child process, PID: %d, Parent PID: %d\n", getpid(), getppid());sleep(5);  // 保持子进程运行一段时间,确保父进程先终止printf("Child process after sleep, PID: %d, New Parent PID: %d\n", getpid(), getppid());exit(0);} else {// 父进程printf("Parent process, PID: %d\n", getpid());exit(0);  // 父进程立即终止}return 0;
}

在这个示例中:

  1. 父进程创建一个子进程。
  2. 父进程终止,而子进程保持运行。
  3. 子进程在睡眠5秒后醒来,并输出其新的父进程PID,此时父进程已经是init进程。
    输出示例:Parent process, PID: 12345
    Child process, PID: 12346, Parent PID: 12345
    Child process after sleep, PID: 12346, New Parent PID: 1
    

    在输出中可以看到,子进程最初的父进程PID是原父进程的PID,当原父进程终止后,子进程的父进程PID变为1,即init进程。

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

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

相关文章

如何利用R包进行主成分分析和可视化

一. 使用R包“FactoMineR”进行主成分分析&#xff08;PCA&#xff09; 基本步骤如下&#xff1a; 安装和加载包&#xff1a;如果尚未安装&#xff0c;首先安装“FactoMineR”包&#xff0c;然后加载它&#xff1a; install.packages("FactoMineR")library(FactoM…

在springboot项目中自定义404页面

今天点击菜单的时候不小心点开了一个不存在的页面&#xff0c;然后看到浏览器给的一个默认的404页面 后端的程序员都觉得这页面太丑了&#xff0c;那么怎么能自定义404页面呢&#xff1f; 很简单&#xff0c;在我们的springboot的静态资源目录下创建一个error包&#xff0c;然…

ue引擎游戏开发笔记(41)——行为树的建立(2)--丰富ai行为:巡逻后返回原处

1.需求分析&#xff1a; 就敌人ai而言&#xff0c;追踪到敌人有可能丢失目标&#xff0c;丢失目标后应该能返回原来位置&#xff0c;实现这一功能。 2.操作实现&#xff1a; 1.思路&#xff1a;利用clear value函数&#xff0c;禁用掉当前的追踪功能&#xff0c;执行之后的返…

积温空间分布数据、气温分布数据、日照数据、降雨量分布、太阳辐射数据、地表径流数据、土地利用数据、npp数据、ndvi数据

引言 积温是某一时段内逐日平均气温之和,它是研究植物生长、发育对热量的要求和评价热量资源的一种指标,是影响植物生长的重要因素之一&#xff0c;对指导农业生产和生态建设具有非常重要的意义。作为重要的气候资源&#xff0c;积温与其它资源的区别在于存在很大的地域差异和时…

Python | Leetcode Python题解之第91题解码方法

题目&#xff1a; 题解&#xff1a; class Solution:def numDecodings(self, s: str) -> int:n len(s)# a f[i-2], b f[i-1], c f[i]a, b, c 0, 1, 0for i in range(1, n 1):c 0if s[i - 1] ! 0:c bif i > 1 and s[i - 2] ! 0 and int(s[i-2:i]) < 26:c aa,…

Flutter 中的 FlutterLogo 小部件:全面指南

Flutter 中的 FlutterLogo 小部件&#xff1a;全面指南 在 Flutter 应用中&#xff0c;FlutterLogo 是一个展示 Flutter 官方图标的小部件。它不仅可以作为一个应用启动时的占位符&#xff0c;也可以作为装饰性图标使用&#xff0c;以展示对 Flutter 的支持。本文将详细介绍 F…

统计学中的新进展与研究领域

统计学领域一直处于不断发展和演变之中&#xff0c;涌现出许多新的研究方向和方法。以下是一些统计学领域的最新研究进展和热点&#xff1a; 1. **贝叶斯统计&#xff1a;** 贝叶斯统计作为一种概率推断的方法&#xff0c;在近年来受到越来越多的关注。随着计算技术的不断进步…

C++——STL容器——List

1. 前言 List也是STL容器的一种&#xff0c;是C提供的链表结构的容器。C中所提供的list是双向带头循环链表&#xff0c;我们这篇文章通过自己模拟实现来学习list的使用。 为了避免和库中的命名冲突&#xff0c;也为了封装的考虑&#xff0c;我们将我们的list放入一个命名空间之…

微服架构基础设施环境平台搭建 -(七)Kubesphere pod内安装vimping命令

微服架构基础设施环境平台搭建 -&#xff08;七&#xff09;Kubesphere pod安装vim&ping命令 在K8s集群运维过程&#xff0c;需要进入pod容器内通过ping来测试网络是否通畅&#xff0c;或使用vim进行编辑文件&#xff0c;但是pod容器默认情况下是不支持ping、vim命令的&…

前端面试题日常练-day05 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末。 1. 下列哪个 CSS 属性用于设置元素的背景颜色&#xff1f; A) color B) font-size C) background-color D) text-align2. 在 JavaScript 中&#xff0c;以下哪个函数可以用于将字符串转换为小写&a…

2024.05.15学习记录

1、完成Ts重构Axios项目中更多功能的开发 2、刷题&#xff1a;二叉树&#xff08;代码回忆录&#xff09; 3、复习diff算法源码解读

关于RK3588平台使用配置Qt、QtCreator、Gstreamer环境的一点记录

最近在做Qt工程代码平台适配的过程中&#xff0c;遇到了一些问题&#xff0c;记录一下。 问题一、主窗体无法透明 首先发现自己的Qt工程的主窗体的透明度无法控制的问题&#xff0c;要么全透明&#xff0c;要么不透明&#xff0c;后来查阅了一些关于linux和linux图形界面的相…

C语言 | Leetcode C语言题解之第91题解码方法

题目&#xff1a; 题解&#xff1a; int numDecodings(char* s) {int n strlen(s);// a f[i-2], b f[i-1], c f[i]int a 0, b 1, c;for (int i 1; i < n; i) {c 0;if (s[i - 1] ! 0) {c b;}if (i > 1 && s[i - 2] ! 0 && ((s[i - 2] - 0) * 10…

Flutter 中的 MaterialApp 小部件:全面指南

Flutter 中的 MaterialApp 小部件&#xff1a;全面指南 MaterialApp 是 Flutter 中用于创建整个 Material Design 风格的应用程序的小部件。它提供了一套丰富的组件和默认设置&#xff0c;以确保应用遵循 Material Design 的指南。本文将详细介绍 MaterialApp 的用途、属性、使…

C++|树形关联式容器(set、map、multiset、multimap)介绍使用

目录 一、关联式容器介绍 1.1概念 1.2键值对 1.3树形结构的关联式容器 1.3.1pair模板介绍 1.3.2make_pair的介绍 二、set的介绍和使用 2.1set介绍 2.2set使用 2.2.1构造 2.2.2容量 2.2.3修改 三、map的介绍和使用 3.1map介绍 3.2map使用 3.2.1构造 3.2.2容量 …

MyBatis-Plus 2万字面试题详解

目录 什么是MyBatis-Plus? MyBatis-Plus与MyBatis有什么区别? MyBatis-Plus的主要优点有哪些?

ubuntu下pycharm闪退

pycharm依赖于jdk环境&#xff0c;要把java的jdk环境配置好&#xff0c;可参考以下链接&#xff1a; ubuntu2024.04下配置jdk&#xff08;安装java环境&#xff09;

力扣刷题总结--链表部分

链表部分 通用操作 链表的两种操作方式 不用虚拟头结点用虚拟头节点 为什么要定义cur指针 因为操作完链表以后&#xff0c;是要返回头节点的。如果你上来就操作头节点&#xff0c;那么头节点的值都改了&#xff0c;返回head就不是我们最开始的链表了。 写while循环的时候&am…

相机模型的内参、外参

相机模型的内参、外参 文章目录 相机模型的内参、外参1. 针孔模型、畸变模型&#xff08;内参&#xff09;2. 手眼标定&#xff08;外参&#xff09; Reference 这篇笔记主要参考&#xff1a;slam十四讲第二版&#xff08;高翔&#xff09; 相机将三维世界中的坐标点&#xff…

JVM线程和内存溢出问题排查思路

一、工具 Arthas&#xff1a;Arthas 是一款能在线查看应用 load、内存、gc、线程 等状态信息&#xff0c;并对业务问题进行诊断的工具&#xff0c;支持 JDK 6 和 Linux/Mac/Windows 系统。 jstack&#xff1a;jstack是JVM自带的Java堆栈跟踪工具&#xff0c;它用于打印出给定…