当前位置: 首页 > article >正文

【C/C++】多线程开发:wait、sleep、yield全解析

文章目录

  • 多线程开发:wait、sleep、yield全解析
    • 1 What
      • 简要介绍
      • 详细介绍
        • `wait()` — 条件等待(用于线程同步)
        • `sleep()` — 睡觉,定时挂起
        • `yield()` — 自愿让出 CPU
    • 2 区别以及建议
      • 区别
      • 应用场景建议
    • 3 三者协作使用示例

多线程开发:wait、sleep、yield全解析

多线程开发中, wait()sleep()yield() 的正确使用对于控制线程行为、避免死锁、提升性能至关重要。


1 What

简要介绍

方法属于哪类是否释放锁作用
wait()同步原语(条件变量)✅ 释放锁当前线程等待某个条件满足,挂起执行。
sleep()时间控制❌ 不释放锁当前线程强制睡眠一段时间。
yield()调度建议❌ 不释放锁当前线程主动让出 CPU,允许其他线程执行。

详细介绍

wait() — 条件等待(用于线程同步)
  • std::condition_variable::wait()(C++11)
  • Java 的 Object.wait() 也类似

行为:

  • 线程在等待某个条件成立
  • 释放所持的互斥锁(mutex),进入阻塞状态。
  • 条件满足后,被 notify_one() / notify_all() 唤醒,重新竞争锁并继续执行。

C++ 示例:

std::mutex mtx;
std::condition_variable cv;
bool ready = false;void worker() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; }); // 释放锁等待条件成立std::cout << "Condition met, working..." << std::endl;
}

sleep() — 睡觉,定时挂起
  • std::this_thread::sleep_for()
  • std::this_thread::sleep_until()

行为:

  • 当前线程被强制阻塞指定时间
  • 不会释放任何锁
  • 时间一到,线程进入就绪状态(可被调度)。

示例:

std::mutex mtx;void worker() {std::lock_guard<std::mutex> lock(mtx);std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "Wake up after 2 seconds.\n";
}

🔺 注意:如果你在持锁状态下调用 sleep(),会让其它线程“饿死”或引发死锁。


yield() — 自愿让出 CPU
  • std::this_thread::yield()(C++11)
  • 实际为对操作系统 sched_yield() 的封装

行为:

  • 当前线程主动放弃 CPU 时间片
  • 线程回到就绪队列,允许其他同优先级线程执行。
  • 不会阻塞、不休眠、不释放锁。

示例:

void busy_wait() {while (!ready) {std::this_thread::yield(); // 避免 CPU 忙等}
}

2 区别以及建议

区别

特性wait()sleep()yield()
阻塞线程?✅ 是✅ 是❌ 否(可能暂停)
是否释放锁?✅ 是(必须配合 mutex 使用)❌ 否❌ 否
唤醒条件notify_one() / notify_all()时间到被 OS 再次调度
典型用途线程间同步,条件等待限制频率、延时模拟忙等时避免 CPU 占用
所属 APIcondition_variable / pthread_condstd::this_thread::sleep_for()std::this_thread::yield()

应用场景建议

场景推荐方法
等待某个状态改变wait()
模拟延时 / 限速 / 轮询间隔sleep()
忙等 / 自旋等待中降低 CPU 占用yield()

3 三者协作使用示例

验证目标:

  • 主线程 sleep 控制节奏
  • 子线程 yield 等待任务
  • 条件变量 wait 同步工作

代码目标:

  • 主线程每 1 秒产生一个任务。
  • 工作线程使用 yield() 自旋检查是否有任务。
  • 一旦任务准备好,工作线程使用 wait() 等待条件变量通知,再执行任务。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <chrono>std::mutex mtx;
std::condition_variable cv;
std::atomic<bool> ready{false};
int task_counter = 0;// 工作线程:等待任务并执行
void worker_thread() {while (true) {// ⏳ 自旋检查任务是否准备好(减少 wait 的频率)while (!ready.load()) {std::this_thread::yield(); // 主动让出 CPU}std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, [] { return ready.load(); }); // 等待通知,并释放锁// 模拟任务处理std::cout << "[Worker] Executing task #" << task_counter << std::endl;ready = false;  // 标记任务完成if (task_counter >= 5) break;  // 结束条件}
}// 主线程:周期性产生任务
void task_producer() {for (int i = 1; i <= 5; ++i) {std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟任务生成延迟{std::lock_guard<std::mutex> lock(mtx);task_counter = i;ready = true;std::cout << "[Main] Task #" << i << " ready\n";}cv.notify_one(); // 通知工作线程}
}int main() {std::thread worker(worker_thread);std::thread producer(task_producer);producer.join();worker.join();std::cout << "All tasks finished.\n";return 0;
}

输出:

[Main] Task #1 ready
[Worker] Executing task #1
[Main] Task #2 ready
[Worker] Executing task #2
[Main] Task #3 ready
[Worker] Executing task #3
[Main] Task #4 ready
[Worker] Executing task #4
[Main] Task #5 ready
[Worker] Executing task #5
All tasks finished.

代码行为解析:

  • 主线程:

    • 每秒产生一个任务,调用 sleep_for()
    • 使用锁保护 task_counterready 状态。
    • 调用 cv.notify_one() 唤醒工作线程。
  • 工作线程:

    • 使用 yield() 忙等(在任务未准备好前避免 CPU 占用)。
    • 使用 condition_variable::wait() 挂起,等待任务准备。
    • 被通知后执行任务,打印日志,重置状态。

相关文章:

【C/C++】多线程开发:wait、sleep、yield全解析

文章目录 多线程开发&#xff1a;wait、sleep、yield全解析1 What简要介绍详细介绍wait() — 条件等待&#xff08;用于线程同步&#xff09;sleep() — 睡觉&#xff0c;定时挂起yield() — 自愿让出 CPU 2 区别以及建议区别应用场景建议 3 三者协作使用示例 多线程开发&#…...

uint8_t是什么数据类型?

一、引言 在C语言编程中&#xff0c;整数类型是最基本的数据类型之一。然而&#xff0c;你是否真正了解这些看似简单的数据类型&#xff1f;本文将深入探索C语言中的整数类型&#xff0c;在编程中更加得心应手。 二、C语言整数类型的基础 2.1 标准整数类型 C语言提供了多种…...

SystemUtils:你的Java系统“探照灯“——让环境探测不再盲人摸象

各位Java系统侦探们好&#xff01;今天要介绍的是Apache Commons Lang3中的SystemUtils工具类。这个工具就像编程界的"雷达系统"&#xff0c;能帮你一键获取所有系统关键信息&#xff0c;再也不用满世界找System.getProperty()了&#xff01; 一、为什么需要SystemU…...

对象存储(Minio)使用

目录 1.安装 MinIO&#xff08;Windows&#xff09; 2.启动minio服务&#xff1a; 3.界面访问 4.进入界面 5.前后端代码配置 1)minio前端配置 2&#xff09;minio后端配置 1.安装 MinIO&#xff08;Windows&#xff09; 官方下载地址&#xff1a;[Download High-Perform…...

yolov11使用记录(训练自己的数据集)

官方&#xff1a;Ultralytics YOLO11 -Ultralytics YOLO 文档 1、安装 Anaconda Anaconda安装与使用_anaconda安装好了怎么用python-CSDN博客 2、 创建虚拟环境 安装好 Anaconda 后&#xff0c;打开 Anaconda 控制台 创建环境 conda create -n yolov11 python3.10 创建完后&…...

历史数据分析——宁波港

个股走势 公司简介: 货物吞吐量和集装箱吞吐量持续保持全球港口前列。 经营分析: 码头开发经营、管理;港口货物的装卸、堆存、仓储、包装、灌装;集装箱拆拼箱、清洗、修理、制造、租赁;在港区内从事货物驳运,国际货运代理;铁路货物运输代理,铁路工程承建,铁路设备…...

知识宇宙:技术文档该如何写?

名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、技术文档的价值与挑战1. 为什么技术文档如此重要2. 技术文档面临的挑战 二、撰…...

DeepSeek 赋能数字农业:从智慧种植到产业升级的全链条革新

目录 一、数字农业的现状与挑战二、DeepSeek 技术解析2.1 DeepSeek 的技术原理与优势2.2 DeepSeek 在人工智能领域的地位与影响力 三、DeepSeek 在数字农业中的应用场景3.1 精准种植决策3.2 病虫害监测与防治3.3 智能灌溉与施肥管理3.4 农产品质量追溯与品牌建设 四、DeepSeek …...

技嘉主板怎么开启vt虚拟化功能_技嘉主板开启vt虚拟化教程(附intel和amd开启方法)

最近使用技嘉主板的小伙伴们问我&#xff0c;技嘉主板怎么开启vt虚拟。大多数可以在Bios中开启vt虚拟化技术&#xff0c;当CPU支持VT-x虚拟化技术&#xff0c;有些电脑会自动开启VT-x虚拟化技术功能。而大部分的电脑则需要在Bios Setup界面中&#xff0c;手动进行设置&#xff…...

Java 并发编程高级技巧:CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用

Java 并发编程高级技巧&#xff1a;CyclicBarrier、CountDownLatch 和 Semaphore 的高级应用 一、引言 在 Java 并发编程中&#xff0c;CyclicBarrier、CountDownLatch 和 Semaphore 是三个常用且强大的并发工具类。它们在多线程场景下能够帮助我们实现复杂的线程协调与资源控…...

PT5F2307触摸A/D型8-Bit MCU

1. 产品概述 ● PT5F2307是一款51内核的触控A/D型8位MCU&#xff0c;内置16K*8bit FLASH、内部256*8bit SRAM、外部512*8bit SRAM、触控检测、12位高精度ADC、RTC、PWM等功能&#xff0c;抗干扰能力强&#xff0c;适用于滑条遥控器、智能门锁、消费类电子产品等电子应用领域。 …...

矩阵方程$Ax=b$的初步理解.

对于矩阵方程 A x b A\textbf{\textit{x}}\textbf{\textit{b}} Axb&#xff0c;可能就是一学而过&#xff0c;也可能也就会做做题&#xff0c;但是从如何直观地理解它呢?   这个等式可以用多种理解方式&#xff0c;这里就从向量变换角度浅谈一下。其中的 A A A是矩阵&#…...

线性代数中的向量与矩阵:AI大模型的数学基石

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家、CSDN平台优质创作者&#xff0c;高级开发工程师&#xff0c;数学专业&#xff0c;10年以上C/C, C#, Java等多种编程语言开发经验&#xff0c;拥有高级工程师证书&#xff1b;擅长C/C、C#等开发语言&#xff0c;熟悉Java常用开…...

[特殊字符] 使用增量同步+MQ机制将用户数据同步到Elasticsearch

在开发用户搜索功能时&#xff0c;我们通常会将用户信息存储到 Elasticsearch&#xff08;简称 ES&#xff09; 中&#xff0c;以提高搜索效率。本篇文章将详细介绍我们是如何实现 MySQL 到 Elasticsearch 的增量同步&#xff0c;以及如何通过 MQ 消息队列实现用户信息实时更新…...

LeetCode 2942.查找包含给定字符的单词:使用库函数完成

【LetMeFly】2942.查找包含给定字符的单词&#xff1a;使用库函数完成 力扣题目链接&#xff1a;https://leetcode.cn/problems/find-words-containing-character/ 给你一个下标从 0 开始的字符串数组 words 和一个字符 x 。 请你返回一个 下标数组 &#xff0c;表示下标在数…...

【mediasoup】MS_DEBUG_DEV 等日志形式转PLOG输出

输出有问题 MS_DEBUG_DEV("[pacer_updated pacing_kbps:%" PRIu32 ",padding_budget_kbps:%" PRIu32 "]",pacing_bitrate_kbps_,/*cc给出的目标码率 * 系数*/padding_rate_bps / 1000 /*设置值*/);...

打卡第27天:函数的定义与参数

知识点回顾&#xff1a; 1.函数的定义 2.变量作用域&#xff1a;局部变量和全局变量 3.函数的参数类型&#xff1a;位置参数、默认参数、不定参数 4.传递参数的手段&#xff1a;关键词参数 5.传递参数的顺序&#xff1a;同时出现三种参数类型时 作业&#xff1a; 题目1&a…...

python训练营day34

知识点回归&#xff1a; CPU性能的查看&#xff1a;看架构代际、核心数、线程数GPU性能的查看&#xff1a;看显存、看级别、看架构代际GPU训练的方法&#xff1a;数据和模型移动到GPU device上类的call方法&#xff1a;为什么定义前向传播时可以直接写作self.fc1(x) 作业 复习今…...

人工智能在医疗影像诊断上的最新成果:更精准地识别疾病

摘要&#xff1a;本论文深入探讨人工智能在医疗影像诊断领域的最新突破&#xff0c;聚焦于其在精准识别疾病方面的显著成果。通过分析深度学习、多模态影像融合、三维重建与可视化以及智能辅助诊断系统等关键技术的应用&#xff0c;阐述人工智能如何提高医疗影像诊断的准确性和…...

塔能节能平板灯:点亮苏州某零售工厂节能之路

在苏州某零售工厂的运营成本中&#xff0c;照明能耗占据着一定比例。为降低成本、提升能源利用效率&#xff0c;该工厂与塔能科技携手&#xff0c;引入塔能节能平板灯&#xff0c;开启了精准节能之旅&#xff0c;并取得了令人瞩目的成效。 一、工厂照明能耗困境 苏州该零售工厂…...

3DMAX插件UV工具UV Tools命令参数详解

常规: 打开UV工具设置对话框。 右键点击: 隐藏/显示主界面。 添加 为选定对象添加展开修改器。 将从下拉菜单中选择映射通道。 Ctrl+点击: 克隆任何当前的修饰符。 右键点击: 找到第一个未展开的修改器。 地图频道 设置展开映射通道。 Ctrl+Click:添加选定的映射通道的展开…...

Docker 与微服务架构:从单体应用到容器化微服务的迁移实践

随着软件系统规模和复杂性的日益增长,传统的单体应用(Monolithic Application)在开发效率、部署灵活性和可伸缩性方面逐渐暴露出局限性。微服务架构(Microservice Architecture)作为一种将大型应用拆分为一系列小型、独立、松耦合服务的模式,正成为现代企业构建弹性、敏捷…...

《岁月深处的童真》

在那片广袤而质朴的黄土地上&#xff0c;时光仿佛放慢了脚步&#xff0c;悠悠地流淌着。画面的中央&#xff0c;是一个扎着双髻的小女孩&#xff0c;她静静地伫立着&#xff0c;宛如一朵绽放在岁月缝隙中的小花。 小女孩身着一件略显陈旧的中式上衣&#xff0c;布料的纹理间似乎…...

文件夹图像批处理教程

前言 因为经常对图像要做数据清洗&#xff0c;又很费时间去重新写一个&#xff0c;我一直在想能不能写一个通用的脚本或者制作一个可视化的界面对文件夹图像做批量的修改图像大小、重命名、划分数据训练和验证集等等。这里我先介绍一下我因为写过的一些脚本&#xff0c;然后我…...

RL电路的响应

学完RC电路的响应&#xff0c;又过了一段时间了&#xff0c;想必很多人都忘了RC电路响应的一些内容。我们这次学习RL电路的响应&#xff0c;以此同时&#xff0c;其实也是带大家一起回忆一些之前所学的RC电路的响应的一些知识点。所以&#xff0c;这次的学习&#xff0c;其实也…...

30-消息队列

一、消息队列概述 队列又称消息队列&#xff0c;是一种常用于任务间通信的数据结构&#xff0c;队列可以在任务与任务间、 中断和任务间传递信息&#xff0c;实现了任务接收来自其他任务或中断的不固定长度的消息&#xff0c;任务能够从队列里面读取消息&#xff0c;当队列中的…...

跨域解决方案之JSONP

目录 一、JSONP 核心原理 二、JSONP 实现步骤 &#xff08;一&#xff09;客户端代码 &#xff08;二&#xff09;服务器端代码&#xff08;ASP.NET实现&#xff09; 1. ASP.NET Web Forms 实现 2. ASP.NET Core 实现 三、JSONP 优缺点 &#xff08;一&#xff09;优点 …...

【AI测试革命】第七期:AI性能测试的深度实践——从智能建模到自动化调优的全链路升级

在微服务架构与高并发场景普及的当下&#xff0c;性能测试作为保障系统稳定性和用户体验的核心环节&#xff0c;正面临负载模型构建复杂、脚本维护成本高、瓶颈定位效率低等挑战。Copilot凭借代码生成、数据分析和智能决策能力&#xff0c;为性能测试全流程注入新动能&#xff…...

Thinkphp6使用token+Validate验证防止表单重复提交

htm页面加 <input type"hidden" name"__token__" value"{:token()}" /> Validate 官方文档 ThinkPHP官方手册...

AppAgentx 开源AI手机操控使用分享

项目地址: https://appagentx.github.io/?utm_sourceai-bot.cn GitHub仓库: https://github.com/Westlake-AGI-Lab/AppAgentX/tree/main arXiv技术论文:https://arxiv.org/pdf/2503.02268 AppAgentx是什么: AppAgentX 是西湖大学推出的一种自我进化式 GUI 代理框架。它通过…...