东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
查看: 2428|回复: 0
打印 上一主题 下一主题

[C/C++] 多线程比单线程的程序耗时还要多:锁用得太频繁

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14441
QQ
跳转到指定楼层
楼主
发表于 2021-8-9 15:50:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式



多线程比单线程的程序耗时还要多:锁用得太频繁




  1. #include <iostream>
  2. #include <list>
  3. #include <string>
  4. #include <chrono>
  5. #include <thread>

  6. class Message
  7. {
  8. private:
  9.     std::string m_data;
  10. public:
  11.     Message(std::string d);
  12.     const std::string& data();
  13. };

  14. Message::Message(std::string d) : m_data(d)
  15. {
  16. }

  17. const std::string& Message::data(){
  18.     return m_data;
  19. }

  20. std::list<Message> global_message_list;


  21. void worker(){
  22.     while(!global_message_list.empty()){
  23.         auto iter = global_message_list.begin();
  24.         //do real work and erase it!
  25.         global_message_list.erase(iter);
  26.     }
  27. }



  28. // 单线程编程

  29. //real        0m11.185s
  30. // user        0m0.186s
  31. // sys        0m0.117s
  32. int main(){

  33.     for(int i=0;i<10000;++i){
  34.         global_message_list.push_back("this is a test"+std::to_string(i));
  35.     }

  36.     worker();

  37.     for(int i=0;i<10000;++i){
  38.         std::this_thread::sleep_for(std::chrono::milliseconds(1));
  39.         global_message_list.push_back("the second "+std::to_string(i));
  40.     }
  41.     worker();

  42.     return 0;
  43. }
复制代码


  1. #include <iostream>
  2. #include <list>
  3. #include <vector>
  4. #include <thread>
  5. #include <atomic>
  6. #include <mutex>


  7. class Message
  8. {
  9. private:
  10.     std::string m_data;
  11. public:
  12.     Message(std::string d);
  13.     const std::string& data();
  14. };

  15. Message::Message(std::string d) : m_data(d)
  16. {
  17. }

  18. const std::string& Message::data(){
  19.     return m_data;
  20. }

  21. std::list<Message> global_message_list;  //所有stl中的容器都是线程不安全的
  22. std::mutex global_mutex;
  23. std::atomic<bool> ready(false);  //原子操作变量
  24. std::atomic<bool> quit(false);


  25. void worker(int i){
  26.     while(!ready){
  27.         //没有准备好 就在循环中等待
  28.     }
  29.     while(!quit){  // 不退出
  30.         std::lock_guard<std::mutex> lock(global_mutex);  //利用lock对象的构造与自动析构
  31.         if(global_message_list.empty()){
  32.             continue;
  33.         }
  34.         auto iter = global_message_list.begin();
  35.         //do real work and erase it!
  36.         global_message_list.erase(iter);

  37.     }
  38. }


  39. // real        0m11.248s
  40. // user        0m0.297s
  41. // sys        0m0.568s

  42. // 发现:多线程比单线程的程序耗时还要多,原因何在?
  43. // 1、锁用得过于频繁

  44. int main(){
  45.     // 数据的准备工作
  46.     for(int i=0;i<10000;++i){
  47.         global_message_list.push_back("this is a test"+std::to_string(i));
  48.     }
  49.     // 创建多个线程来干活
  50.     const int threadCount = 4;
  51.     std::vector<std::thread> pool;
  52.     for(int i=0;i<threadCount;i++){
  53.         //pool.emplace_back(worker, i);
  54.         // 创建线程 非lambda函数方式
  55.         pool.emplace_back(std::thread(worker, i));
  56.     }
  57.     // 主线程给 每个子线程的 一个信号(命令):准备干活了
  58.     ready = true;
  59.    
  60.     // 主线程往全局list放数据
  61.     for(int i=0;i<10000;++i){
  62.         std::lock_guard<std::mutex> lock(global_mutex);
  63.         std::this_thread::sleep_for(std::chrono::milliseconds(1));
  64.         global_message_list.push_back("the second "+std::to_string(i));
  65.     }

  66.     //quit=true;
  67.     while (true)
  68.     {
  69.         std::lock_guard<std::mutex> lock(global_mutex);
  70.         if(global_message_list.empty()){
  71.             // 主线程 发信号给所有的子线程
  72.             // 假设:所有子线程是要把活 全部干完的!
  73.             quit=true;
  74.             break;
  75.         }
  76.     }
  77.    


  78.     for(auto &v : pool){
  79.         if(v.joinable()){
  80.             v.join();
  81.         }
  82.     }

  83.     std::cout << "主线程结束!" << std::endl;

  84.     return 0;
  85. }

复制代码






让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|人工智能工程师的摇篮 ( 湘ICP备2020019608号-1 )

GMT+8, 2024-5-28 17:52 , Processed in 0.165584 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表