登錄 |創建賬號 |找回密碼
查看: 79|回復: 0

c++多线程输出数字相加

[複製鏈接]

23

主題

6

回帖

130

積分

管理員

Rank: 9Rank: 9Rank: 9

積分
130
發表於 2024-3-23 21:56:02 | 顯示全部樓層 |閱讀模式
ThreadPool.h

  1. #ifndef THREADPOOL_H
  2. #define THREADPOOL_H

  3. #include <vector>
  4. #include <queue>
  5. #include <memory>
  6. #include <thread>
  7. #include <mutex>
  8. #include <condition_variable>
  9. #include <future>
  10. #include <functional>
  11. #include <stdexcept>

  12. class ThreadPool {
  13. public:
  14.     ThreadPool(size_t threads);
  15.     ~ThreadPool();

  16.     // 在类定义内声明并定义enqueue方法
  17.     template<class F, class... Args>
  18.     auto enqueue(F&& f, Args&&... args)
  19.         -> std::future<typename std::result_of<F(Args...)>::type>;

  20. private:
  21.     std::vector<std::thread> workers;
  22.     std::queue<std::function<void()>> tasks;

  23.     std::mutex queue_mutex;
  24.     std::condition_variable condition;
  25.     bool stop;
  26. };

  27. // 在头文件中定义enqueue,确保编译器能够找到模板定义
  28. template<class F, class... Args>
  29. auto ThreadPool::enqueue(F&& f, Args&&... args)
  30. -> std::future<typename std::result_of<F(Args...)>::type> {
  31.     using return_type = typename std::result_of<F(Args...)>::type;

  32.     auto task = std::make_shared< std::packaged_task<return_type()> >(
  33.         std::bind(std::forward<F>(f), std::forward<Args>(args)...)
  34.     );

  35.     std::future<return_type> res = task->get_future();
  36.     {
  37.         std::unique_lock<std::mutex> lock(queue_mutex);

  38.         if (stop)
  39.             throw std::runtime_error("enqueue on stopped ThreadPool");

  40.         tasks.emplace([task]() { (*task)(); });
  41.     }
  42.     condition.notify_one();
  43.     return res;
  44. }

  45. #endif
複製代碼
ThreadPool.cpp
  1. #include "ThreadPool.h"

  2. ThreadPool::ThreadPool(size_t threads)
  3.     : stop(false) {
  4.     for (size_t i = 0; i < threads; ++i)
  5.         workers.emplace_back(
  6.             [this] {
  7.                 for (;;) {
  8.                     std::function<void()> task;

  9.                     {
  10.                         std::unique_lock<std::mutex> lock(this->queue_mutex);
  11.                         this->condition.wait(lock,
  12.                             [this] { return this->stop || !this->tasks.empty(); });
  13.                         if (this->stop && this->tasks.empty())
  14.                             return;
  15.                         task = std::move(this->tasks.front());
  16.                         this->tasks.pop();
  17.                     }

  18.                     task();
  19.                 }
  20.             }
  21.     );
  22. }

  23. ThreadPool::~ThreadPool() {
  24.     {
  25.         std::unique_lock<std::mutex> lock(queue_mutex);
  26.         stop = true;
  27.     }
  28.     condition.notify_all();
  29.     for (std::thread& worker : workers)
  30.         worker.join();
  31. }
複製代碼
main.cpp
  1. #include <iostream>
  2. #include <mutex>
  3. #include <chrono>
  4. #include <random>
  5. #include "ThreadPool.h"


  6. std::mutex cout_mutex; // 用于同步标准输出的互斥锁

  7. int getRandomNumberBetween(int a, int b) {
  8.     // 静态用于性能考虑:初始化一次,避免每次调用都初始化
  9.     static std::random_device rd; // 用于获得种子
  10.     static std::mt19937 gen(rd()); // 标准 mersenne_twister_engine seeded with rd()
  11.     std::uniform_int_distribution<> distrib(a, b);

  12.     return distrib(gen);
  13. }

  14. void taskFunction(int id, int& number) {
  15.     auto start = std::chrono::high_resolution_clock::now();
  16.     std::default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
  17.     std::uniform_int_distribution<int> distribution(100, 300);

  18.     for (int i = 0; i < getRandomNumberBetween(20,70); ++i) {
  19.         ++number;
  20.         std::this_thread::sleep_for(std::chrono::milliseconds(distribution(generator)));
  21.     }

  22.     auto end = std::chrono::high_resolution_clock::now();
  23.     std::chrono::duration<double> diff = end - start;

  24.     // 在任务内部进行输出
  25.     std::lock_guard<std::mutex> guard(cout_mutex); // 使用互斥锁来保护输出
  26.     std::cout << "thread" << id << ", used:" << diff.count() << "s, result:" << number << std::endl;
  27. }


  28. int main() {
  29.     ThreadPool pool(10); // 创建一个拥有10个线程的线程池

  30.     int numbers[10] = {}; // 定义10个数字

  31.     // 统计开始时间
  32.     auto start = std::chrono::high_resolution_clock::now();

  33.     std::vector<std::future<void>> futures;
  34.     for (int i = 0; i < 10; ++i) {
  35.         futures.push_back(pool.enqueue(taskFunction, i + 1, std::ref(numbers[i])));
  36.     }

  37.     // 等待所有任务完成
  38.     for (auto& future : futures) {
  39.         future.get();
  40.     }

  41.     // 统计结束时间
  42.     auto end = std::chrono::high_resolution_clock::now();
  43.     std::chrono::duration<double> diff = end - start;
  44.     std::cout << "all done! total use:" << diff.count() << "s" << std::endl;

  45.     // 注意:这里没有实现“最快的线程”和“最慢的线程”的功能,因为这需要在taskFunction中额外维护线程执行时间的信息,并在所有任务完成后进行比较。
  46.     // 可以通过增加一个结构体来保存每个线程的执行时间和ID,然后在所有任务完成后进行排序来实现。

  47.     return 0;
  48. }
複製代碼
结果:
  1. thread8, used:4.68329s, result:23
  2. thread3, used:5.15709s, result:25
  3. thread7, used:5.38293s, result:27
  4. thread9, used:5.87792s, result:28
  5. thread10, used:6.02598s, result:30
  6. thread5, used:6.2226s, result:29
  7. thread1, used:6.53804s, result:32
  8. thread4, used:6.66759s, result:30
  9. thread2, used:6.92785s, result:35
  10. thread6, used:8.11339s, result:37
  11. all done! total use:8.14531s
複製代碼


回復

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 創建賬號

本版積分規則

Archiver|手機版|小黑屋|九派社區 ( 苏ICP备07501547号-12 )

GMT+8, 2024-5-17 22:04 , Processed in 0.124408 second(s), 30 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回復 返回頂部 返回列表