【C/C++】线程状态以及转换

news2025/12/15 9:33:23

文章目录

  • 线程状态以及转换
    • 1 基本状态
      • 1.1 新建(New)
      • 1.2 就绪(Ready / Runnable)
      • 1.3 运行中(Running)
      • 1.4 阻塞/等待(Blocked / Waiting / Sleeping)
      • 1.5 挂起(Suspended)
      • 1.6 终止(Terminated / Dead / Exit)
      • 注意点
    • 2 状态转换
      • 2.1 C/C++ 线程状态转换图(基于 Linux/POSIX 和 `std::thread`)
      • 2.2 状态转换说明
      • 2.3 示例:多个状态的转换代码
    • 3 调试
      • 3.1 Linux 中线程/进程的典型状态码
      • 3.2 深入 `/proc/[pid]/task/` 查看线程状态
      • 3.3 状态之间的实际转换(C++ 映射)
      • 3.5 调试技巧
    • 总结:线程状态的决定者是谁?

线程状态以及转换

线程的基本状态通常用于描述线程在程序执行过程中的生命周期。


1 基本状态

1.1 新建(New)

  • 说明:线程对象已经创建,但尚未启动。
  • 示例(C++):std::thread t(myFunction);(如果尚未调用 join()detach()

1.2 就绪(Ready / Runnable)

  • 说明:线程已经准备好运行,但由于 CPU 正忙,暂时未被调度执行。
  • 特征:已具备运行条件,等待调度。

1.3 运行中(Running)

  • 说明:线程正在由 CPU 调度并执行任务。
  • 特征:只有一个线程能在某一时刻占用一个 CPU 核心运行。

1.4 阻塞/等待(Blocked / Waiting / Sleeping)

  • 说明:线程暂时无法继续运行,处于等待某些资源或事件状态。

  • 常见原因:

    • 等待锁(mutex)释放
    • 等待条件变量(std::condition_variable
    • 调用了 sleep_for() / sleep_until()
    • 等待 I/O 操作完成

1.5 挂起(Suspended)

  • 说明:线程被人为暂停,暂时不会被调度(某些系统中才存在,如 Windows)。
  • 补充:这不是所有系统都显式支持的状态。

1.6 终止(Terminated / Dead / Exit)

  • 说明:线程执行完任务或被强制终止,生命周期结束。

  • 注意事项:

    • 线程终止后不能被重启。
    • C++ 中,必须在适当时机调用 join()detach(),否则可能引发资源泄露。

注意点

  • std::thread 构造后即启动,不能“延迟启动”。
  • join():主线程等待子线程执行完毕。
  • detach():子线程后台运行,主线程不再关心其状态。
  • 未调用 join()detach() 就析构 std::thread,会导致程序崩溃。

2 状态转换

在 C/C++ 中,线程状态的转换并不像 Java 那样有统一的虚拟机控制模型,而是依赖于底层操作系统(如 Linux、Windows)调度机制。C++ 本身通过 std::thread 提供了对系统线程(如 POSIX Threads 或 Windows Threads)的封装,但不显式暴露线程状态。

结合操作系统线程模型,理解 C/C++ 中线程状态的转换路径。


2.1 C/C++ 线程状态转换图(基于 Linux/POSIX 和 std::thread

简单版本

 [New] 
   ↓
 [Ready] ↔ [Running] → [Terminated]
   ↑          ↓
 [Blocked] ←---
 +--------+       thread constructor
 |  New   | --------------------------+
 +--------+                           |
      |                               v
      |                        +-------------+
      |        OS调度          |   Runnable  |
      +----------------------> +-------------+
                               |             |
                               v             |
                       +--------------+      | 被抢占或 yield
                       |   Running    | <----+
                       +--------------+
                             |
      +----------------------+------------------------------+
      |                      |                              |
      v                      v                              v
[Waiting on lock]   [Waiting on cond_var]          [sleep_for / sleep_until]
     Blocked              Waiting (CondVar)             Sleeping
      +                      +                              +
      |                      |                              |
      +---------> 信号/条件满足/定时器超时  <---------------+
                             |
                             v
                       +--------------+
                       |   Runnable   |
                       +--------------+
                             |
                             v
                       +--------------+
                       |   Running    |
                       +--------------+
                             |
                        执行结束 or 异常
                             |
                             v
                       +--------------+
                       | Terminated   |
                       +--------------+

Linux 实际版

            +-------------+
            |   Running   | <--------+
            +-------------+          |
               |        ^            |
           preempt    schedule       |
               v        |            |
           +-------------+           |
           |   Runnable   | ---------+
           +-------------+
               |
        +------+------+
        |             |
    +-------+     +--------+
    | Sleep |     |  Disk  |
    |  (S)  |     | Sleep  |
    +-------+     |  (D)   |
        |         +--------+
        |               |
        v               v
    +---------------------+
    |     Runnable        |
    +---------------------+

      (via wakeup or I/O completion)

2.2 状态转换说明

状态名称触发条件示例代码
New → Runnable创建线程对象 std::thread t(...)std::thread t(myFunc);
Runnable → Running被操作系统调度自动完成,无需显式操作
Running → Blocked获取互斥锁失败(如 mutex.lock()std::unique_lock<std::mutex> lock(m);
Running → Waiting调用 condition_variable.wait()cv.wait(lock);
Running → Sleeping调用 std::this_thread::sleep_for(...)std::this_thread::sleep_for(1s);
Blocked/Waiting/Sleeping → Runnable条件满足/超时/锁释放由 OS 处理,代码中不可见
Running → Terminated线程函数返回/异常函数结束或 return

2.3 示例:多个状态的转换代码

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
    std::unique_lock<std::mutex> lock(mtx);
    std::cout << "Worker: waiting...\n";
    
    // Running → Waiting(挂起等待条件变量)
    cv.wait(lock, [] { return ready; });

    std::cout << "Worker: resumed and working...\n";
    // Running → Sleeping
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Worker: finished.\n";
    // → Terminated
}

int main() {
    std::thread t(worker);

    std::this_thread::sleep_for(std::chrono::seconds(2));
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
        std::cout << "Main: notifying worker...\n";
    }
    cv.notify_one();

    t.join();
}

执行结果

Worker: waiting...
Main: notifying worker...
Worker: resumed and working...
Worker: finished.

3 调试

3.1 Linux 中线程/进程的典型状态码

运行命令如:

ps -o pid,tid,stat,comm -L -p <pid>

或者使用 top,会看到类似以下状态码:

例如输出:

  PID   TID STAT COMMAND
12345 12345 Ss   my_program
12345 12346 Sl   my_program
12345 12347 Rl   my_program
12345 12348 S    my_program
  • Ss:主线程,sleeping 且为 session leader。
  • Sl:sleeping + 多线程(L)。
  • Rl:runnable + 多线程(L)。
  • S:普通 sleeping 线程。
状态码含义说明
RRunning / Runnable正在运行,或在运行队列中等待调度
SSleeping (Interruptible)可中断的睡眠,等待事件或条件,如 sleep()read()
DUninterruptible sleep不可中断的睡眠(通常为 IO),如等待磁盘或网络
TTraced / Stopped被调试器暂停或收到 SIGSTOP 信号
ZZombie僵尸进程,子进程已终止但父进程未调用 wait()
XDead非正常终止(很少见)

3.2 深入 /proc/[pid]/task/ 查看线程状态

Linux 把每个线程当作一个任务(task),在 /proc/[pid]/task/ 下有所有线程的子目录:

ls /proc/<pid>/task/

然后可以查看每个线程状态:

cat /proc/<pid>/task/<tid>/status

输出中有一行:

State:	S (sleeping)

其他可能值包括:

  • R (running)
  • D (disk sleep)
  • T (stopped)
  • Z (zombie)

3.3 状态之间的实际转换(C++ 映射)

Linux 状态对应 C++ 场景
R (Runnable)正在执行或准备被调度,CPU 调度队列中
S (Sleeping)std::this_thread::sleep_for、等待条件变量、I/O 等
D (Disk Sleep)被阻塞在磁盘或网络 I/O(不可中断)
T (Stopped)被调试或 SIGSTOP 暂停
Z (Zombie)线程/进程退出但未被 join()/wait()

3.5 调试技巧

  1. htop 可视化线程状态
htop
# F2 -> Display options -> Show custom thread names (如你设置了)
  1. gdb 附加调试线程状态
gdb -p <pid>
info threads
  1. perf top 查看哪些线程/函数在消耗 CPU

总结:线程状态的决定者是谁?

决定因素状态
程序员代码睡眠、等待、join 等显式操作
操作系统调度器Running / Runnable 切换、抢占等
锁竞争Blocked(mutex、spinlock)

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

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

相关文章

如何制作可以本地联网搜索的MCP,并让本地Qwen3大模型调用搜索回答用户问题?

环境: SearXNG Qwen3-32B-FP8 vllm 0.8.5 问题描述: 如何制作可以本地联网搜索的MCP,并让本地Qwen3大模型调用搜索回答用户问题? 解决方案: 一、安装searxng 1.按需新建模型相关文件夹 mkdir MCP chmod 777 /mnt/program/MCP2.配置conda源 nano ~/.condarc nano…

服务器硬盘虚拟卷的处理

目前的情况是需要删除逻辑卷&#xff0c;然后再重新来弄一遍。 数据已经备份好了&#xff0c;所以不用担心数据会丢失。 查看服务器的具体情况 使用 vgdisplay 操作查看服务器的卷组情况&#xff1a; --- Volume group ---VG Name vg01System IDFormat …

一个国债交易策略思路

该国债交易策略的核心在于通过分析历史价格数据来识别市场趋势&#xff0c;并在趋势确认时进行开仓操作。策略的设计思路结合了价格波动范围的计算和市场波动性的评估&#xff0c;旨在捕捉市场的短期趋势并控制风险。 首先&#xff0c;策略通过对过去5根K线的最高价和最低价进行…

【三维重建】【3DGS系列】【深度学习】3DGS的理论基础知识之如何形成高斯椭球

【三维重建】【3DGS系列】【深度学习】3DGS的理论基础知识之如何形成高斯椭球 文章目录 【三维重建】【3DGS系列】【深度学习】3DGS的理论基础知识之如何形成高斯椭球前言高斯函数一维高斯多维高斯 椭球基本定义一般二次形式 3D高斯椭球3D高斯与椭球的关系各向同性(Isotropic)和…

手写ES6 Promise() 相关函数

手写 Promise() 相关函数&#xff1a; Promise()、then()、catch()、finally() // 定义三种状态常量 const PENDING pending const FULFILLED fulfilled const REJECTED rejectedclass MyPromise {/*定义状态和结果两个私有属性:1.使用 # 语法&#xff08;ES2022 官方私有字…

【NLP 76、Faiss 向量数据库】

压抑与痛苦&#xff0c;那些辗转反侧的夜&#xff0c;终会让我们更加强大 —— 25.5.20 Faiss&#xff08;Facebook AI Similarity Search&#xff09;是由 Facebook AI 团队开发的一个开源库&#xff0c;用于高效相似性搜索的库&#xff0c;特别适用于大规模向…

软件名称:系统日志监听工具 v1.0

软件功能&#xff1a;一款基于 PyQt5 开发的 Windows 系统日志监听工具&#xff0c;适用于系统运维、网络管理、故障排查等场景&#xff0c;具备以下核心功能&#xff1a; 支持监听系统三大日志源&#xff1a;应用程序 / 系统 / 安全日志实时抓取新日志事件&#xff0c;自动滚…

Spring AI 之结构化输出转换器

截至 2024 年 2 月 5 日,旧的 OutputParser、BeanOutputParser、ListOutputParser 和 MapOutputParser 类已被弃用,取而代之的是新的 StructuredOutputConverter、BeanOutputConverter、ListOutputConverter 和 MapOutputConverter 实现类。后者可直接替换前者,并提供相同的…

Java虚拟机面试题:内存管理(上)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

进程间通信I·匿名管道

目录 进程间通信&#xff08;IPC&#xff09; 含义 目的 分类 匿名管道 原理 创建过程 特性 四大情况 close问题 代码练习 简单通信 进程池 小知识 进程间通信&#xff08;IPC&#xff09; 含义 就是让不同的进程能看到同一份资源&#xff0c;实现数据交流。 …

Ubuntu Linux系统的基本命令详情

1.Ubuntu Linux是以桌面应用为主的Linux发行版操作系统 2.Ubuntu的用户使用 在登录系统一般使用在安装系统时建立的普通用户登录&#xff0c;如果要使用超级用户权限 #sudo ---执行命令 sudo passwd ---修改用户密码 su - root ---切换超级用户 系统的不同&#xff0c;命令也不…

大数据治理:理论、实践与未来展望(二)

书接上文 文章目录 七、大数据治理的未来发展趋势&#xff08;一&#xff09;智能化与自动化&#xff08;二&#xff09;数据隐私与安全的强化&#xff08;三&#xff09;数据治理的云化&#xff08;四&#xff09;数据治理的跨行业合作&#xff08;五&#xff09;数据治理的生…

PCB布局设计

PCB布局设计 一、原理图到PCB转换前的准备工作 在将原理图转换为PCB之前&#xff0c;我们需要进行一系列准备工作&#xff0c;确保设计的正确性和完整性。这一步骤至关重要&#xff0c;可以避免后续PCB设计中出现不必要的错误。 // 原理图转PCB前必要检查步骤 // 1. 仔细检查…

esp32+IDF V5.1.1版本编译freertos报错

error: portTICK_RATE_MS undeclared (first use in this function); did you mean portTICK_PERIOD_MS 解决方法: 使用命令 idf.py menuconfig 打开配置界面配置freeRtos 使能configENABLE_BACKWARD_COMPATIBLITY

笔记本6GB本地可跑的图生视频项目(FramePack)

文章目录 &#xff08;一&#xff09;简介&#xff08;二&#xff09;本地执行&#xff08;2.1&#xff09;下载&#xff08;2.2&#xff09;更新&#xff08;2.3&#xff09;运行&#xff08;2.4&#xff09;生成 &#xff08;三&#xff09;注意&#xff08;3.1&#xff09;效…

SpringMVC实战:动态时钟

引言 在现代 Web 开发中&#xff0c;选择一个合适的框架对于项目的成功至关重要。Spring MVC 作为 Spring 框架的核心模块之一&#xff0c;以其清晰的架构、强大的功能和高度的可配置性&#xff0c;成为了 Java Web 开发领域的主流选择。本文将通过一个“动态时钟”的实战项目…

哈希表的实现(上)

前言 在C98中&#xff0c;STL提供了底层为红黑树结构的一系列关联式容器&#xff0c;在查询时效率可达到&#xff0c;即最差情况下需要比较红黑树的高度次&#xff0c;当树中的节点非常多时&#xff0c;查询效率也不理想。最好的查询是&#xff0c;进行很少的比较次数就能够将…

【Java高阶面经:微服务篇】1.微服务架构核心:服务注册与发现之AP vs CP选型全攻略

一、CAP理论在服务注册与发现中的落地实践 1.1 CAP三要素的技术权衡 要素AP模型实现CP模型实现一致性最终一致性(Eureka通过异步复制实现)强一致性(ZooKeeper通过ZAB协议保证)可用性服务节点可独立响应(支持分区存活)分区期间无法保证写操作(需多数节点可用)分区容错性…

实验7 HTTP协议分析与测量

实验7 HTTP协议分析与测量 1、实验目的 了解HTTP协议及其报文结构 了解HTTP操作过程&#xff1a;TCP三次握手、请求和响应交互 掌握基于tcpdump和wireshark软件进行HTTP数据包抓取和分析技术 2、实验环境 硬件要求&#xff1a;阿里云云主机ECS 一台。 软件要求&#xff1…

python:机器学习概述

本文目录&#xff1a; 一、人工智能三大概念二、学习方式三、人工智能发展史**1950-1970****1980-2000****2010-2017****2017-至今** 四、机器学习三要素五、常见术语六、数据集的划分七、常见算法分类八、机器学习的建模流程九、特征工程特征工程包括**五大步**&#xff1a;特…