C++如何创建多线程 C++多线程编程的实现方式介绍

来源:Android社区作者:阿里山老登头衔:草根站长
导读:本期聚焦于小伙伴创作的《C++如何创建多线程 C++多线程编程的实现方式介绍》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何创建多线程 C++多线程编程的实现方式介绍》有用,将其分享出去将是对创作者最好的鼓励。

C++11标准引入了原生的多线程支持,不再需要依赖操作系统提供的线程接口,开发者可以通过标准库中的thread类轻松创建和管理多线程,同时配套提供了互斥锁、条件变量等同步工具,让多线程编程更加规范和便捷。

C++如何创建多线程 C++多线程编程的实现方式介绍

C++多线程的基础创建方式

使用标准库的thread类创建线程非常简单,只需要包含<thread>头文件,实例化thread对象时传入线程执行的函数即可,线程会在创建后自动启动执行。

无参数线程的创建

如果线程执行的函数不需要参数,直接传入函数名即可,示例代码如下:

#include <iostream>
#include <thread>

// 线程执行的函数
void thread_task() {
    std::cout << "子线程正在执行" << std::endl;
}

int main() {
    // 创建线程,传入线程函数
    std::thread t(thread_task);
    // 等待子线程执行完成,避免主线程提前退出导致程序异常
    t.join();
    std::cout << "主线程执行完成" << std::endl;
    return 0;
}

带参数线程的创建

如果线程函数需要参数,可以在thread构造函数中函数名之后依次传入参数,参数会以拷贝的方式传递给线程函数,示例代码如下:

#include <iostream>
#include <thread>
#include <string>

// 带参数的线程函数
void thread_task_with_param(std::string name, int count) {
    for (int i = 0; i < count; ++i) {
        std::cout << name << "执行第" << i + 1 << "次任务" << std::endl;
    }
}

int main() {
    // 创建带参数的线程,传入函数名和两个参数
    std::thread t(thread_task_with_param, "子线程A", 3);
    t.join();
    return 0;
}

线程的分离与等待

thread对象提供了两个核心管理方法,分别是join()detach(),用于控制主线程和子线程的执行关系。

  • join():主线程会阻塞等待当前子线程执行完成,之后才会继续往下执行,适合需要获取子线程执行结果的场景。
  • detach():将子线程和主线程分离,子线程会在后台独立运行,主线程不再需要等待子线程结束,分离后的线程资源会在执行完成后自动回收,需要注意的是分离后的线程不能再调用join()。

如果thread对象销毁前既没有调用join()也没有调用detach(),程序会直接终止,因此必须合理处理线程的生命周期。

多线程同步常用工具

多个线程同时操作共享资源时,很容易出现数据竞争问题,C++标准库提供了一系列同步工具来解决这个问题。

互斥锁mutex

互斥锁用于保护共享资源,同一时间只能有一个线程持有锁,其他线程需要等待锁释放后才能获取,最常用的是std::mutex,配合std::lock_guard可以自动管理锁的获取和释放,避免忘记解锁导致死锁。

下面是一个使用互斥锁保护共享计数器的示例:

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

// 共享计数器
int counter = 0;
// 互斥锁
std::mutex mtx;

// 线程函数,每次执行计数器加1
void increment_task(int times) {
    for (int i = 0; i < times; ++i) {
        // 自动加锁,作用域结束自动解锁
        std::lock_guard<std::mutex> lock(mtx);
        ++counter;
    }
}

int main() {
    // 创建两个子线程
    std::thread t1(increment_task, 1000);
    std::thread t2(increment_task, 1000);
    // 等待两个子线程执行完成
    t1.join();
    t2.join();
    // 输出最终计数器的值,理论上是2000
    std::cout << "最终计数器值:" << counter << std::endl;
    return 0;
}

条件变量condition_variable

条件变量用于线程之间的通知机制,一个线程可以等待某个条件满足,另一个线程在条件满足时通知等待的线程继续执行,需要和互斥锁配合使用。

下面是一个生产者消费者模型的简单示例:

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

// 共享队列
std::queue<int> data_queue;
// 互斥锁
std::mutex mtx;
// 条件变量
std::condition_variable cv;
// 结束标志
bool finished = false;

// 生产者线程函数
void producer() {
    for (int i = 0; i < 5; ++i) {
        {
            std::lock_guard<std::mutex> lock(mtx);
            data_queue.push(i);
            std::cout << "生产数据:" << i << std::endl;
        }
        // 通知消费者线程
        cv.notify_one();
    }
    {
        std::lock_guard<std::mutex> lock(mtx);
        finished = true;
    }
    cv.notify_all();
}

// 消费者线程函数
void consumer() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        // 等待条件:队列不为空或者生产结束
        cv.wait(lock, []{ return !data_queue.empty() || finished; });
        // 如果队列为空且生产结束,退出循环
        if (data_queue.empty() && finished) {
            break;
        }
        // 取出队首数据
        int data = data_queue.front();
        data_queue.pop();
        lock.unlock();
        std::cout << "消费数据:" << data << std::endl;
    }
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join();
    t2.join();
    return 0;
}

常见问题与注意事项

  • 线程函数的参数如果是引用类型,需要使用std::ref包装,否则thread会拷贝参数,无法修改外部变量。
  • 不要对同一个thread对象多次调用join()或者detach(),会导致程序异常。
  • 避免使用全局变量作为共享资源,尽量将共享资源和同步工具封装到类中,管理生命周期。
  • 如果线程中会抛出异常,需要确保异常不会导致锁没有释放,使用std::lock_guard或者std::unique_lock可以有效避免这个问题。

C++多线程thread互斥锁条件变量修改时间:2026-06-18 21:57:18

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。