进程状态转换图

一、进程状态转换基础

进程是操作系统调度的基本单位,而进程状态则是描述进程执行过程中状态的基本概念。进程在其生命周期中会处于不同的状态,包括新建态、就绪态、运行态、阻塞态和终止态。

新建态是指进程被创建后还未被分配资源的状态,就绪态是指进程已经获取到了所有必要资源等待执行的状态,运行态是指进程正在占用CPU运行的状态,阻塞态是指进程等待某些条件满足或资源释放的状态,终止态是指进程执行结束且已经被释放的状态。

当进程在不同状态之间切换的时候,需要进行状态转换操作。下面我们以Linux作为例子来介绍进程在状态之间的转换操作。

/* 进程状态 */
enum task_state {
    TASK_RUNNING = 0,   /* 运行态 */
    TASK_INTERRUPTIBLE, /* 可中断的睡眠态 */
    TASK_UNINTERRUPTIBLE,   /* 不可中断的睡眠态 */
    TASK_STOPPED,   /* 停止态 */
    TASK_TRACED,    /* 被追踪态 */
    TASK_DEAD,  /* 已终止态 */
};

二、进程状态转换图

进程的状态转换有多种可能,这里我们以一种典型的转换方式为例来说明。下面是进程状态转换图:

+--------+        +----------+       +---------+       +---------+
| 创建态 +------->+ 就绪态   +------>+ 运行态  +------>| 终止态  |
+--------+        +----------+       +---------+       +---------+
                   ^   |  ^                |
                   |   |  |                |
                   |   V  |                |
             +--------------+         +-----------+
             | 可中断的睡眠态 |<--------+ 不可中断的睡眠态 |
             +--------------+         +-----------+

三、进程状态之间的转换

下面我们来分别介绍进程状态之间的转换方式。

1. 创建态到就绪态

当一个进程被创建时,初始状态为创建态。当进程被分配到所有必要资源,可以开始执行之前,由创建态转为就绪态。这个转换是由系统调度算法决定的,通常是通过进程队列和调度程序来实现的。

/* 创建一个新进程并将其加入到就绪队列 */
struct task_struct *init_task(void)
{
    /* ...省略其他代码... */
    /* 创建进程 */
    p = __alloc_task_struct();
    /* 设置进程状态为就绪态 */
    p->state = TASK_RUNNING;
    /* 将进程加入到就绪队列 */
    enqueue_task(p, &rq->array[rq->curr]);
    return p;
}

2. 就绪态到运行态

当CPU被分配到了进程时,该进程进入运行态。如果此时还有其他进程处于就绪态,则它们将继续等待CPU资源的分配。

/* 进程从就绪态变为运行态 */
static void __sched __schedule(void)
{
    /* ...省略其他代码... */
    /* 获取就绪队列里的下一个进程,并将其状态设置为运行态 */
    next = pick_next_task(rq);
    next->state = TASK_RUNNING;

    /* 切换到下一个进程 */
    rq->curr = next;
    context_switch(rq, prev, next);
}

3. 运行态到就绪态

当一个进程正在占用CPU运行时,如果出现IO等等其它需要等待的操作,则该进程从运行态进入阻塞态,然后进入可中断的睡眠态或者不可中断的睡眠态,等待IO等操作结束后再转为就绪态。此时,其他进程有可能获得CPU使用权。

/* 进程从运行态变为阻塞态 */
void sleep_on(wait_queue_head_t *q)
{
    /* ...省略其他代码... */
    //将当前进程的状态设置为可中断的睡眠态
    current->state = TASK_INTERRUPTIBLE;
    //将当前进程加入到等待队列中
    add_wait_queue(q, &wait);
    //切换到下一个进程
    schedule();
}

4. 阻塞态到就绪态

当阻塞态的进程等待的系统调用返回并且获得了系统资源时,它从睡眠态或者阻塞态变成就绪态,表示该进程的资源需求已得到满足,可以开始运行了。

/* 进程从阻塞态变为就绪态 */
void wake_up(wait_queue_head_t *q)
{
    /* ...省略其他代码... */
    //将等待队列中阻塞进程的状态设置为就绪态
    do_each_thread(g, p) {
        if (p->state == state &&
            (wait == NULL || wait->func(wait, task, mode, key) != 0))
            p->state = TASK_RUNNING;
    } while_each_thread(g, p);
    /* 移除等待队列中的进程 */
    __remove_wait_queue(q, &wait);
    /* 切换到下一个进程 */
    schedule();
}

5. 运行态到终止态

进程在完成任务后或者出错时,会从运行态进入终止态。在终止态中,进程进行善后处理和资源释放。此后,内核将不再管理此进程,以便其它进程使用其资源。

/* 进程从运行态变为终止态 */
asmlinkage void do_exit(long code)
{
    /* ...省略其他代码... */
    //设置进程状态为终止态
    current->state = TASK_DEAD;
    //从进程表中删除该进程
    del_from_tasklist(current);
    /* 切换到下一个进程 */
    schedule();
}

结语

进程的状态转换是操作系统中非常关键的一个概念。我们通过介绍进程的五种状态和相应的转换方式,使读者加深对进程状态转换的理解。其实,在Linux系统中还有很多其它的状态转换方式,大家可以自行深入学习。

原创文章,作者:BKLI,如若转载,请注明出处:https://www.506064.com/n/133751.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
BKLIBKLI
上一篇 2024-10-04 00:01
下一篇 2024-10-04 00:01

相关推荐

  • 如何通过jstack工具列出假死的java进程

    假死的java进程是指在运行过程中出现了某些问题导致进程停止响应,此时无法通过正常的方式关闭或者重启该进程。在这种情况下,我们可以借助jstack工具来获取该进程的进程号和线程号,…

    编程 2025-04-29
  • Java中的僵尸进程简介与解决方法

    本文将对Java中的僵尸进程进行详细阐述,并给出几种解决方法。 一、僵尸进程的概念 在操作系统中,进程是指正在执行的程序。当一个进程创建了一个子进程,而该子进程完成了任务却没有被父…

    编程 2025-04-27
  • 多线程和多进程的应用

    多线程和多进程是现代编程中常用的技术,可以提高程序的效率和性能。本文将从不同的角度对多线程和多进程进行详细的介绍和应用。 一、多线程 vs 多进程 多线程和多进程都是为了实现程序并…

    编程 2025-04-27
  • Python多进程读取数据

    本文将从多个方面详细阐述在Python中如何通过多进程读取数据,并给出完整的代码示例。 一、多进程概述 在计算机科学中,进程是正在执行的程序实例。多进程是指计算机系统同时执行多个进…

    编程 2025-04-27
  • 进程a与进程b共享变量s1

    本文将从多个方面对进程a与进程b共享变量s1做详细的阐述,并给出代码示例。 一、定义全局变量s1 进程a与进程b共享变量s1,意味着s1是一个全局变量。在C语言中,可以使用关键字e…

    编程 2025-04-27
  • python多进程并行循环

    在大数据时代,我们通常需要处理大量的数据。处理大数据往往需要较长的时间,影响效率。Python提供了多线程、多进程等并行处理方式来提高数据处理效率。本文将主要讲解python多进程…

    编程 2025-04-27
  • Python进程池共享内存用法介绍

    本文将从多个方面详细阐述Python进程池共享内存的相关知识,包括如何使用进程池、进程池的实现原理、进程池中的共享内存管理等。本文内容将涵盖: 一、进程池的使用 进程池是一种有效的…

    编程 2025-04-27
  • Linux守护进程

    一、什么是Linux守护进程 Linux守护进程是在Linux系统下运行的一种特殊进程,它没有终端连接,并且在后台运行,通常用于某些服务程序、监控程序或者系统管理程序等。守护进程的…

    编程 2025-04-25
  • Python 进程通信

    当需要在不同进程之间进行通信时,Python 提供了几种方法来实现进程间通信。这些方法包括队列,管道,共享内存以及套接字。 1. 队列 Python 队列是进程安全的,并且可以很方…

    编程 2025-04-24
  • Linux下杀掉进程的命令详解

    一、杀掉进程的概念 在进行Linux系统管理以及软件开发过程中,我们常常需要杀掉卡死或异常程序的进程。杀掉进程是指在运行中的进程突然中断或终止运行,也称为进程终止。 杀掉进程的主要…

    编程 2025-04-24

发表回复

登录后才能评论