C++基础 | 线程`std::thread`

什么是std::thread

std::thread是C++11中引入的一个类,用于表示和管理线程。通过std::thread,我们可以创建一个新的线程来执行指定的任务。线程是操作系统调度的基本单位,多个线程可以并发执行,从而提高程序的效率。


创建线程

基本用法

要创建一个线程,只需实例化一个std::thread对象,并传入一个可调用对象(如函数、Lambda表达式或函数对象)作为参数。

#include <iostream>
#include <thread>

void hello() {
    std::cout << "Hello from thread!\n";
}

int main() {
    std::thread t(hello); // 创建一个线程,执行hello函数
    t.join(); // 等待线程结束
    return 0;
}

在这个示例中,我们创建了一个线程t,它执行hello函数。join()方法用于等待线程执行完毕。


使用Lambda表达式

我们也可以使用Lambda表达式来创建线程。

#include <iostream>
#include <thread>

int main() {
    std::thread t([]() {
        std::cout << "Hello from Lambda thread!\n";
    });
    t.join();
    return 0;
}

带参数的线程函数

线程函数可以接受参数,只需在创建线程时传递相应的参数即可。

#include <iostream>
#include <thread>

void print_message(const std::string& message) {
    std::cout << message << '\n';
}

int main() {
    std::thread t(print_message, "Hello from thread with arguments!");
    t.join();
    return 0;
}

线程的管理

join()detach()

  • join():等待线程执行完毕。调用join()后,主线程会阻塞,直到子线程完成。
  • detach():将线程与std::thread对象分离,线程在后台独立运行。分离后的线程不能再被join()
#include <iostream>
#include <thread>
#include <chrono>

void task() {
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::cout << "Task completed!\n";
}

int main() {
    std::thread t(task);
    t.detach(); // 分离线程
    std::cout << "Main thread continues...\n";
    std::this_thread::sleep_for(std::chrono::seconds(2)); // 等待子线程完成
    return 0;
}

线程的移动语义

std::thread支持移动语义,可以将一个线程的所有权从一个std::thread对象转移到另一个。

#include <iostream>
#include <thread>

void task() {
    std::cout << "Task executed!\n";
}

int main() {
    std::thread t1(task);
    std::thread t2 = std::move(t1); // 将t1的所有权转移给t2
    t2.join();
    return 0;
}

线程同步

多线程编程中,线程之间的共享资源可能会导致数据竞争问题。为了解决这个问题,C++提供了多种同步机制,如互斥锁(std::mutex)和条件变量(std::condition_variable)。


使用std::mutex

std::mutex用于保护共享资源,确保同一时间只有一个线程可以访问该资源。

#include <iostream>
#include <thread>
#include <mutex>
#include <vector>

std::mutex mtx;
int shared_data = 0;

void increment() {
    for (int i = 0; i < 10000; ++i) {
        std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁
        ++shared_data;
    }
}

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(increment);
    }
    for (auto& t : threads) {
        t.join();
    }
    std::cout << "Final value of shared_data: " << shared_data << '\n'; // 输出:100000
    return 0;
}

使用std::condition_variable

std::condition_variable用于线程间的通信,允许线程等待某些条件成立。

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

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

void print_id(int id) {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []() { return ready; }); // 等待条件成立
    std::cout << "Thread " << id << " is running!\n";
}

int main() {
    std::thread threads[10];
    for (int i = 0; i < 10; ++i) {
        threads[i] = std::thread(print_id, i);
    }

    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true; // 设置条件为true
    }
    cv.notify_all(); // 通知所有等待的线程

    for (auto& t : threads) {
        t.join();
    }
    return 0;
}

线程池的实现

虽然C++标准库没有直接提供线程池,但我们可以使用std::thread和其他工具(如std::queuestd::function)来实现一个简单的线程池。

#include <iostream>
#include <thread>
#include <vector>
#include <queue>
#include <functional>
#include <mutex>
#include <condition_variable>

class ThreadPool {
public:
    ThreadPool(size_t num_threads) {
        for (size_t i = 0; i < num_threads; ++i) {
            workers.emplace_back([this] {
                while (true) {
                    std::function<void()> task;
                    {
                        std::unique_lock<std::mutex> lock(this->queue_mutex);
                        this->condition.wait(lock, [this] { return this->stop || !this->tasks.empty(); });
                        if (this->stop && this->tasks.empty()) {
                            return;
                        }
                        task = std::move(this->tasks.front());
                        this->tasks.pop();
                    }
                    task();
                }
            });
        }
    }

    template <class F>
    void enqueue(F&& f) {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            tasks.emplace(std::forward<F>(f));
        }
        condition.notify_one();
    }

    ~ThreadPool() {
        {
            std::unique_lock<std::mutex> lock(queue_mutex);
            stop = true;
        }
        condition.notify_all();
        for (std::thread& worker : workers) {
            worker.join();
        }
    }

private:
    std::vector<std::thread> workers;
    std::queue<std::function<void()>> tasks;
    std::mutex queue_mutex;
    std::condition_variable condition;
    bool stop = false;
};

int main() {
    ThreadPool pool(4);

    for (int i = 0; i < 8; ++i) {
        pool.enqueue([i] {
            std::cout << "Task " << i << " is running on thread " << std::this_thread::get_id() << '\n';
            std::this_thread::sleep_for(std::chrono::seconds(1));
        });
    }

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【devops】Macos 轻量化docker解决方案 orbstack | 不用Docker Desktop启动docker服务

一、orbstack OrbStack is the fast, light, and easy way to run Docker containers and Linux machines. It’s a supercharged WSL and Docker Desktop alternative, all in one easy-to-use app. 二、orbstack 的可视化

RabbitMQ消息队列 发送和接受

步骤 1: 安装 RabbitMQ 首先&#xff0c;需要安装 RabbitMQ&#xff0c;并确保它在运行中。 下载erlang语言包OTP。官网地址&#xff1a;Downloads - Erlang/OTP Rabbitmq官网下载地址&#xff1a;Downloading and Installing RabbitMQ — RabbitMQ 安装MQ注意事项&#xf…

2025最新版Node.js下载安装~保姆级教程

1. node中文官网地址&#xff1a;http://nodejs.cn/download/ 2.打开node官网下载压缩包&#xff1a; 根据操作系统不同选择不同版本&#xff08;win7系统建议安装v12.x&#xff09; 我这里选择最新版win 64位 3.安装node ①点击对话框中的“Next”&#xff0c;勾选同意后点…

Spring Boot 3.4 中 MockMvcTester 的新特性解析

引言 在 Spring Boot 3.4 版本中&#xff0c;引入了一个全新的 MockMvcTester 类&#xff0c;使 MockMvc 测试可以直接支持 AssertJ 断言。本文将深入探讨这一新特性&#xff0c;分析它如何优化 MockMvc 测试并提升测试的可读性。 Spring MVC 示例 为了演示 MockMvcTester 的…

WEB攻防-文件下载文件读取文件删除目录遍历目录穿越

目录 一、文件下载漏洞 1.1 文件下载案例&#xff08;黑盒角度&#xff09; 1.2 文件读取案例&#xff08;黑盒角度&#xff09; 二、文件删除 三、目录遍历与目录穿越 四、审计分析-文件下载漏洞-XHCMS 五、审计分析-文件读取漏洞-MetInfo-函数搜索 六、审计分析-…

01.Docker 概述

Docker 概述 1. Docker 的主要目标2. 使用Docker 容器化封装应用程序的意义3. 容器和虚拟机技术比较4. 容器和虚拟机表现比较5. Docker 的组成6. Namespace7. Control groups8. 容器管理工具9. docker 的优缺点10. 容器的相关技术 docker 官网: http://www.docker.com 帮助文档…

IDEA中常见问题汇总

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

基于蜘蛛蜂优化算法的无人机集群三维路径规划Matlab实现

代码下载&#xff1a;私信博主回复基于蜘蛛蜂优化算法的无人机集群三维路径规划Matlab实现 《基于蜘蛛蜂优化算法的无人机集群三维路径规划》 摘要 本研究针对无人机集群三维路径规划问题&#xff0c;提出了一种基于蜘蛛蜂优化算法的解决方案。以5个无人机构成的集群为研究对…

路由过滤方法与常用工具

路由过滤 定义&#xff1a;路由器在发布或者接收消息时&#xff0c;可能需要对路由信息进行过滤。 作用&#xff1a;控制路由的传播与生成&#xff1b;节省设备和链路资源消耗&#xff0c;保护网络安全。 举例&#xff1a;学习汇总后的路由&#xff0c;而不学习汇总时的明细路由…

仿 RabbitMQ 实现的简易消息队列

文章目录 项目介绍开放环境第三⽅库介绍ProtobufMuduo库 需求分析核⼼概念实现内容 消息队列系统整体框架服务端模块数据管理模块虚拟机数据管理模块交换路由模块消费者管理模块信道&#xff08;通信通道&#xff09;管理模块连接管理模块 客户端模块 公共模块日志类其他工具类…

【天梯赛】L1-104 九宫格(C++)

易忽略的错误&#xff1a;开始习惯性地看到n就以为是n*n数组了&#xff0c;实际上应该是9*9的固定大小数组&#xff0c;查了半天没查出来 题面 L1-104 九宫格 - 团体程序设计天梯赛-练习集 代码实现 #include<bits/stdc.h> using namespace std; //易错&#xff1a;开…

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层

CSS 小技巧 —— CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层 1. 两个元素实现 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><title>纯 CSS 实现 Tooltip 功能-鼠标 hover 之后出现弹层</titl…

【转载】开源鸿蒙OpenHarmony社区运营报告(2025年1月)

●截至2025年1月31日&#xff0c;开放原子开源鸿蒙&#xff08;OpenAtom OpenHarmony&#xff0c;简称“开源鸿蒙”或“OpenHarmony”&#xff09;社区累计超过8200名贡献者&#xff0c;共63家成员单位&#xff0c;产生51.2万多个PR、2.9万多个Star、10.5万多个Fork、68个SIG。…

03:Spring之Web

一&#xff1a;Spring整合web环境 1&#xff1a;web的三大组件 Servlet&#xff1a;核心组件&#xff0c;负责处理请求和生成响应。 Filter&#xff1a;用于请求和响应的预处理和后处理&#xff0c;增强功能。 Listener&#xff1a;用于监听 Web 应用中的事件&#xff0c;实…

ASP.NET Core 如何使用 C# 向端点发出 POST 请求

使用 C#&#xff0c;将 JSON POST 到 REST API 端点&#xff1b;如何从 REST API 接收 JSON 数据。 本文需要 ASP .NET Core&#xff0c;并兼容 .NET Core 3.1、.NET 6和.NET 8。 要从端点获取数据&#xff0c;请参阅本文。 使用 . 将 JSON 数据发布到端点非常容易HttpClien…

大语言模型需要的可观测性数据的关联方式

可观测性数据的关联方式及其优缺点 随着现代分布式架构和微服务的普及&#xff0c;可观测性&#xff08;Observability&#xff09;已经成为确保系统健康、排查故障、优化性能的重要组成部分。有效的可观测性数据关联方式不仅能够帮助我们实时监控系统的运行状态&#xff0c;还…

渗透利器:Burp Suite 联动 XRAY 图形化工具.(主动扫描+被动扫描)

Burp Suite 联动 XRAY 图形化工具.&#xff08;主动扫描被动扫描&#xff09; Burp Suite 和 Xray 联合使用&#xff0c;能够将 Burp 的强大流量拦截与修改功能&#xff0c;与 Xray 的高效漏洞检测能力相结合&#xff0c;实现更全面、高效的网络安全测试&#xff0c;同时提升漏…

C语言_通讯录

“我若成佛&#xff0c;天下无魔&#xff1b;我若成魔&#xff0c;佛奈我何。” “小爷是魔&#xff0c;那又如何&#xff1f;” 下面我和一起来攻克通讯录的难关&#xff01;&#xff01; 明确通讯录的基本结构 实现一个通讯录: 人的信息: 名字年龄性别电话地址 实现通讯录的…

STM32 Flash详解教程文章

目录 Flash基本概念理解 Flash编程接口FPEC Flash擦除/写入流程图 Flash选项字节基本概念理解 Flash电子签名 函数读取地址下存放的数据 Flash的数据处理限制部分 编写不易&#xff0c;请勿搬运&#xff0c;感谢理解&#xff01;&#xff01;&#xff01; Flash基本概念…

Flutter项目试水

1基本介绍 本文章在构建您的第一个 Flutter 应用指导下进行实践 可作为项目实践的辅助参考资料 Flutter 是 Google 的界面工具包&#xff0c;用于通过单一代码库针对移动设备、Web 和桌面设备构建应用。在此 Codelab 中&#xff0c;您将构建以下 Flutter 应用。 该应用可以…