news 2026/6/10 1:19:13

8.线程的创建方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
8.线程的创建方法

一、纯C++实现线程的方式(C++11及以上)

纯C++的线程能力来自标准库(<thread>),核心只有2类核心方式(本质都是基于std::thread),没有多余的“变种”,语法和平台无关(Windows/Linux通用):

1. 基础方式:直接使用std::thread绑定可执行对象

这是最核心的方式,std::thread创建后立即启动新线程,可绑定函数、lambda、类成员函数等:

#include <thread> #include <iostream> #include <chrono> // 1. 绑定普通函数 void task1(int num) { for (int i = 0; i < 3; ++i) { std::cout << "任务1(线程ID:" << std::this_thread::get_id() << "):" << num + i << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } // 2. 绑定类成员函数 class TaskClass { public: void task2(const std::string& msg) { for (int i = 0; i < 3; ++i) { std::cout << "任务2(线程ID:" << std::this_thread::get_id() << "):" << msg << i << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } }; int main() { std::cout << "主线程ID:" << std::this_thread::get_id() << std::endl; // 方式1:启动普通函数线程 std::thread t1(task1, 10); // 方式2:启动类成员函数线程 TaskClass obj; std::thread t2(&TaskClass::task2, &obj, "测试"); // 等待线程结束(必须join,否则主线程退出会导致程序崩溃) t1.join(); t2.join(); return 0; }
2. 进阶方式:线程池(基于std::thread封装)

纯C++没有内置线程池,需自己封装或用第三方库(如boost::thread_pool),核心是复用线程、减少线程创建销毁的开销,适合大量短任务场景:

// 简化版线程池示例(核心思路) #include <thread> #include <vector> #include <queue> #include <mutex> #include <condition_variable> class ThreadPool { public: ThreadPool(int numThreads) { // 创建指定数量的线程,循环等待任务 for (int i = 0; i < numThreads; ++i) { m_workers.emplace_back([this]() { while (true) { std::function<void()> task; // 加锁取任务 { std::unique_lock<std::mutex> lock(m_mtx); m_cv.wait(lock, [this]() { return m_stop || !m_tasks.empty(); }); if (m_stop && m_tasks.empty()) return; task = std::move(m_tasks.front()); m_tasks.pop(); } // 执行任务 task(); } }); } } // 添加任务到队列 template<class F> void enqueue(F&& f) { { std::unique_lock<std::mutex> lock(m_mtx); m_tasks.emplace(std::forward<F>(f)); } m_cv.notify_one(); // 唤醒一个线程执行任务 } // 销毁线程池 ~ThreadPool() { { std::unique_lock<std::mutex> lock(m_mtx); m_stop = true; } m_cv.notify_all(); // 唤醒所有线程 for (auto& worker : m_workers) { if (worker.joinable()) worker.join(); } } private: std::vector<std::thread> m_workers; // 线程池 std::queue<std::function<void()>> m_tasks; // 任务队列 std::mutex m_mtx; // 互斥锁 std::condition_variable m_cv; // 条件变量 bool m_stop = false; // 停止标志 }; // 使用线程池 int main() { ThreadPool pool(4); // 创建4个线程的线程池 for (int i = 0; i < 10; ++i) { pool.enqueue([i]() { std::cout << "线程池执行任务" << i << ",线程ID:" << std::this_thread::get_id() << std::endl; std::this_thread::sleep_for(std::chrono::milliseconds(100)); }); } return 0; }

二、Qt框架中实现线程的方式(3种核心方式)

Qt基于纯C++扩展了线程能力,核心有3种方式,底层仍依赖操作系统线程,但封装了更贴合Qt生态的接口(信号槽、事件循环)

方式1:继承QThread重写run()(基础方式)
  • 核心:QThread是线程控制器,重写run()函数,run()内的代码在新线程执行;
  • 适用:简单、单一的循环任务(如持续采集传感器数据);
  • 示例:
#include <QThread> #include <QDebug> class SimpleThread : public QThread { Q_OBJECT protected: void run() override { for (int i = 0; i < 3; ++i) { qDebug() << "QThread线程执行:" << i << ",线程ID:" << QThread::currentThreadId(); msleep(500); // Qt封装的延时(避免用std::this_thread) } } }; // 使用 // SimpleThread t; // t.start(); // 启动线程,自动调用run() // t.wait(); // 等待线程结束
方式2:QObject + moveToThread()(Qt官方推荐,主流方式)
  • 核心:将业务逻辑封装在QObject子类中,通过moveToThread()移到QThread,用信号槽触发任务,解耦“线程管理”和“业务逻辑”;
  • 适用:绝大多数场景(网络通信、异步解析、多任务调度);
  • 示例:
#include <QThread> #include <QObject> #include <QDebug> class Worker : public QObject { Q_OBJECT public slots: void doWork() { qDebug() << "moveToThread执行任务,线程ID:" << QThread::currentThreadId(); // 耗时任务逻辑... } }; // 使用 // QThread thread; // Worker* worker = new Worker; // worker->moveToThread(&thread); // thread.start(); // // 信号槽触发任务 // QMetaObject::invokeMethod(worker, "doWork");
方式3:Qt线程池QThreadPool(进阶方式)
  • 核心:Qt内置线程池,无需手动封装,结合QRunnable使用,适合大量短任务;
  • 适用:批量处理小任务(如批量解析数据、批量网络请求);
  • 示例:
#include <QThreadPool> #include <QRunnable> #include <QDebug> class MyRunnable : public QRunnable { public: void run() override { qDebug() << "QThreadPool执行任务,线程ID:" << QThread::currentThreadId(); // 任务逻辑... } }; // 使用 // MyRunnable* runnable = new MyRunnable; // runnable->setAutoDelete(true); // 执行完自动销毁 // QThreadPool::globalInstance()->start(runnable); // 加入全局线程池执行

三、纯C++线程 vs Qt线程:核心差异(是否相同?)

二者底层原理相同(都是调用操作系统的线程接口),但封装形式、生态适配、使用方式完全不同,核心差异如下:

维度

纯C++线程(std::thread)

Qt线程(QThread/QThreadPool)

核心依赖

C++标准库<thread>,跨平台但无Qt生态适配

基于C++扩展,绑定Qt信号槽、事件循环

线程通信

需手动用std::mutex/std::condition_variable,无现成通信机制

天然支持信号槽(线程间安全通信),无需手动处理锁

线程管理

手动join()/detach(),无内置线程池

自动管理(如QThread::start()/wait()),内置QThreadPool

生态适配

无法直接和Qt控件/信号槽交互

完美适配Qt所有模块(UI、网络、文件等)

适用场景

非Qt项目、纯C++跨平台项目

Qt项目(99%的Qt多线程场景)

总结

  1. 纯C++线程:只有2类核心方式(std::thread直接使用、基于std::thread封装线程池),语法通用但需手动处理线程通信和管理;
  2. Qt线程:有3种核心方式(继承QThread、QObject+moveToThread、QThreadPool),底层基于C++但封装了Qt生态特性(信号槽、自动管理),是Qt项目的首选;
  3. 二者底层原理相同(都是操作系统线程),但封装形式和使用场景完全不同——Qt线程是纯C++线程在Qt生态下的“定制增强版”。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 15:46:10

Z-Image-Turbo完整指南:从零到出图,云端GPU省心方案

Z-Image-Turbo完整指南&#xff1a;从零到出图&#xff0c;云端GPU省心方案 引言 作为一名刚转行学习AI的新手&#xff0c;你是否曾被本地环境配置搞得焦头烂额&#xff1f;显卡驱动冲突、CUDA版本不匹配、依赖库缺失...这些技术门槛让很多人在第一步就放弃了。今天我要介绍的…

作者头像 李华
网站建设 2026/6/1 2:06:40

【高并发系统设计必修课】:结构化异常管控的7个关键模式

第一章&#xff1a;高并发异常管控的核心挑战在现代分布式系统中&#xff0c;高并发场景下的异常管控已成为保障服务稳定性的关键环节。面对瞬时流量激增、依赖服务延迟或宕机等问题&#xff0c;系统若缺乏有效的异常处理机制&#xff0c;极易引发雪崩效应&#xff0c;导致整体…

作者头像 李华
网站建设 2026/6/10 13:46:28

HunyuanVideo-Foley开发者大会:腾讯混元技术分享精华回顾

HunyuanVideo-Foley开发者大会&#xff1a;腾讯混元技术分享精华回顾 2025年8月28日&#xff0c;腾讯混元团队在年度开发者大会上正式宣布开源其最新研究成果——HunyuanVideo-Foley&#xff0c;一款端到端的智能视频音效生成模型。这一发布标志着AI在多媒体内容创作领域的又一…

作者头像 李华
网站建设 2026/6/6 14:37:58

数字华夏十年演进(2015–2025)

数字华夏十年演进&#xff08;2015–2025&#xff09; 一句话总论&#xff1a; 2015年数字华夏还“不存在”&#xff08;仅国家大数据战略初步布局&#xff09;&#xff0c;2025年已进化成“全球最强数字中国底座万亿级多模态VLA时空智能大模型量子鲁棒自进化全域政务/民生/产业…

作者头像 李华