0

0

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

穿越時空

穿越時空

发布时间:2025-07-19 11:15:02

|

662人浏览过

|

来源于php中文网

原创

c++++创建多线程主要依赖标准库,它提供了一种相对简洁的方式来启动和管理线程。1. c++11引入了库,通过创建std::thread对象并传入函数及参数实现多线程;2. 使用join()确保主线程等待子线程完成;3. 数据竞争可通过互斥锁(std::mutex)、原子操作(std::atomic)和条件变量(std::condition_variable)避免;4. 线程池通过任务队列、线程集合和同步机制实现,提升线程复用效率;5. 常见错误包括死锁、活锁、饥饿、竞争条件和内存泄漏;6. 同步机制应根据场景选择,如保护共享数据用互斥锁,简单类型操作用原子变量,等待条件用条件变量,大量并发用线程池。

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

C++创建多线程主要依赖标准库 ,它提供了一种相对简洁的方式来启动和管理线程。本质上,你是在告诉操作系统,把一部分工作分配给一个新的执行流。

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

解决方案

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

C++11 引入了 库,极大地简化了多线程编程。以下是一个基本的多线程示例:

立即学习C++免费学习笔记(深入)”;

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

void worker_thread(int thread_id) {
  std::cout << "线程 " << thread_id << " 正在执行...\n";
  // 模拟一些耗时操作
  std::this_thread::sleep_for(std::chrono::seconds(2));
  std::cout << "线程 " << thread_id << " 执行完毕!\n";
}

int main() {
  std::thread t1(worker_thread, 1); // 创建线程 t1,执行 worker_thread 函数,传入参数 1
  std::thread t2(worker_thread, 2); // 创建线程 t2,执行 worker_thread 函数,传入参数 2

  std::cout << "主线程继续执行...\n";

  t1.join(); // 等待线程 t1 执行完毕
  t2.join(); // 等待线程 t2 执行完毕

  std::cout << "所有线程执行完毕,程序结束!\n";
  return 0;
}

这个例子展示了如何创建两个线程 t1t2,每个线程都执行 worker_thread 函数。join() 函数的作用是让主线程等待子线程执行完毕。如果不调用 join(),主线程可能会在子线程完成之前结束,导致程序行为不确定。

C++多线程中的数据竞争与如何避免?

数据竞争是指多个线程同时访问和修改同一块内存区域,且至少有一个线程在进行写操作。这会导致不可预测的结果。避免数据竞争的关键在于使用适当的同步机制。

  • 互斥锁 (Mutexes): std::mutex 允许一次只有一个线程访问共享资源。

    #include 
    #include 
    #include 
    
    std::mutex mtx; // 互斥锁
    
    void shared_resource_access(int thread_id) {
      mtx.lock(); // 加锁
      std::cout << "线程 " << thread_id << " 访问共享资源...\n";
      // 访问共享资源的代码
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "线程 " << thread_id << " 释放共享资源...\n";
      mtx.unlock(); // 解锁
    }
    
    int main() {
      std::thread t1(shared_resource_access, 1);
      std::thread t2(shared_resource_access, 2);
    
      t1.join();
      t2.join();
    
      return 0;
    }

    使用 std::lock_guard 可以更安全地管理锁的生命周期,防止忘记解锁:

    E酷购网络商城建站程序
    E酷购网络商城建站程序

    一套傻瓜式的建站程序,由前台购物、后台管理、在线支付三部分组成介绍说明:1.注册与否均可购物(同类程序大多要求注册才能购物),方便了那些懒得注册的客户。降低用户使用门槛,自然可抓住更多潜在商机。2.会员等级和折扣功能。管理员可方便的为会员设置不同等级,不同等级的员会可享受不同的购物折扣。3.站内短信、留言发布,沟通无极限。会员和游客均可发送短信和留言。4.完美融合在线支付功能,无需编程、无需修改源

    下载
    void shared_resource_access(int thread_id) {
      std::lock_guard lock(mtx); // 自动加锁和解锁
      std::cout << "线程 " << thread_id << " 访问共享资源...\n";
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "线程 " << thread_id << " 释放共享资源...\n";
    }
  • 原子操作 (Atomic Operations): std::atomic 提供了一种无需显式锁即可安全访问和修改简单数据类型的方式。

    #include 
    #include 
    #include 
    
    std::atomic counter(0); // 原子计数器
    
    void increment_counter() {
      for (int i = 0; i < 100000; ++i) {
        counter++; // 原子递增操作
      }
    }
    
    int main() {
      std::thread t1(increment_counter);
      std::thread t2(increment_counter);
    
      t1.join();
      t2.join();
    
      std::cout << "计数器最终值: " << counter << "\n";
      return 0;
    }
  • 条件变量 (Condition Variables): std::condition_variable 允许线程在特定条件满足时才继续执行,常与互斥锁一起使用。

C++多线程中的线程池是什么?如何实现一个简单的线程池?

线程池是一种管理和复用线程的技术,可以避免频繁创建和销毁线程的开销。

一个简单的线程池实现思路如下:

  1. 任务队列: 用于存储待执行的任务。
  2. 线程集合: 一组预先创建的线程,它们从任务队列中获取任务并执行。
  3. 同步机制: 使用互斥锁和条件变量来保证线程安全地访问任务队列。
#include 
#include 
#include 
#include 
#include 
#include 
#include  // std::function

class ThreadPool {
public:
  ThreadPool(size_t num_threads) : stop(false) {
    threads.resize(num_threads);
    for (size_t i = 0; i < num_threads; ++i) {
      threads[i] = std::thread([this]() {
        while (true) {
          std::function task;

          {
            std::unique_lock lock(queue_mutex);
            cv.wait(lock, [this]() { return stop || !tasks.empty(); });
            if (stop && tasks.empty()) {
              return;
            }
            task = tasks.front();
            tasks.pop();
          }

          task();
        }
      });
    }
  }

  template
  void enqueue(F&& f) {
    {
      std::unique_lock lock(queue_mutex);
      tasks.emplace(std::forward(f));
    }
    cv.notify_one();
  }

  ~ThreadPool() {
    {
      std::unique_lock lock(queue_mutex);
      stop = true;
    }
    cv.notify_all();
    for (std::thread& thread : threads) {
      thread.join();
    }
  }

private:
  std::vector threads;
  std::queue> tasks;
  std::mutex queue_mutex;
  std::condition_variable cv;
  bool stop;
};

int main() {
  ThreadPool pool(4); // 创建一个包含 4 个线程的线程池

  for (int i = 0; i < 8; ++i) {
    pool.enqueue([i]() {
      std::cout << "任务 " << i << " 正在执行,线程 ID: " << std::this_thread::get_id() << "\n";
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "任务 " << i << " 执行完毕\n";
    });
  }

  std::this_thread::sleep_for(std::chrono::seconds(3)); // 等待任务执行完毕,实际应用中需要更完善的同步机制

  return 0;
}

C++多线程编程中常见的错误和陷阱有哪些?

  • 死锁 (Deadlock): 多个线程相互等待对方释放资源,导致所有线程都无法继续执行。避免死锁的关键在于避免循环依赖,并按照固定的顺序获取锁。
  • 活锁 (Livelock): 线程不断重试相同的操作,但由于某种原因总是失败。活锁通常发生在线程尝试避免死锁时。
  • 饥饿 (Starvation): 一个或多个线程长时间无法获得所需的资源,导致无法执行。
  • 竞争条件 (Race Condition): 程序的行为取决于多个线程执行的相对顺序,导致结果不可预测。
  • 内存泄漏 (Memory Leak): 线程中分配的内存没有被正确释放。

如何选择合适的多线程同步机制?

选择合适的同步机制取决于具体的应用场景。

  • 如果只需要保护少量数据,且更新频率不高,可以使用互斥锁。
  • 如果需要对简单数据类型进行原子操作,可以使用原子操作。
  • 如果线程需要等待特定条件满足,可以使用条件变量。
  • 如果需要执行大量并发任务,可以使用线程池。

总的来说,C++多线程编程需要仔细考虑线程安全问题,并选择合适的同步机制。理解常见的错误和陷阱,可以帮助你编写更健壮和高效的多线程程序。

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

216

2025.10.31

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

472

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

107

2025.12.24

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

107

2025.12.24

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

54

2025.12.01

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

61

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

40

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

32

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 0.6万人学习

Rust 教程
Rust 教程

共28课时 | 4万人学习

Excel 教程
Excel 教程

共162课时 | 10.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号