东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[C/C++] 多线程编程:尽量减少锁空间

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

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





多线程编程:尽量减少锁空间


//http://www.ai111.vip/thread-1247-1-1.html  继续改进 减少锁空间
// 多线程编程:尽量减少锁空间



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


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

  17. Message::Message(std::string d=std::string()) : m_data(d)
  18. {
  19. }

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

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

  28. //http://www.ai111.vip/thread-1247-1-1.html  继续改进 减少锁空间
  29. // 多线程编程:尽量减少锁空间


  30. void worker(int i){
  31.     while(!ready){
  32.         //没有准备好 就在循环中等待
  33.     }
  34.     while(!quit){  // 不退出
  35.         //std::this_thread::sleep_for(std::chrono::milliseconds(1));
  36.         Message msg;
  37.         {   
  38.             //将锁空间 尽量压缩在这块代码内
  39.             std::lock_guard<std::mutex> lock(global_mutex);  //利用lock对象的构造与自动析构
  40.             if(global_message_list.empty()){
  41.                 continue;
  42.             }
  43.             auto iter = global_message_list.begin();
  44.             msg = std::move(*iter);  // move是干啥的?
  45.             global_message_list.erase(iter);
  46.         }
  47.         //do real work and erase it!  干的工作:计算字符串的长度并求和
  48.         //真正干活的 有atomic原子操作 所以不需要 临界区mutex加锁了
  49.         total_size += strlen(msg.data().c_str());

  50.     }
  51. }


  52. // real        0m11.248s
  53. // user        0m0.297s
  54. // sys        0m0.568s

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

  57. int main(){
  58.     // 数据的准备工作
  59.     for(int i=0;i<10000;++i){
  60.         global_message_list.push_back("this is a test"+std::to_string(i));
  61.     }

  62.     // 创建多个线程来干活
  63.     const int threadCount = 4;
  64.     std::vector<std::thread> pool;
  65.     for(int i=0;i<threadCount;i++){
  66.         //pool.emplace_back(worker, i);
  67.         // 创建线程 非lambda函数方式
  68.         pool.emplace_back(std::thread(worker, i));
  69.     }
  70.     // 主线程给 每个子线程的 一个信号(命令):准备干活了
  71.     ready = true;
  72.    
  73.     // 主线程往全局list放数据
  74.     for(int i=0;i<10000;++i){
  75.         std::this_thread::sleep_for(std::chrono::milliseconds(1));
  76.         // 减少锁空间
  77.         std::lock_guard<std::mutex> lock(global_mutex);
  78.         global_message_list.push_back("the second "+std::to_string(i));
  79.     }

  80.     //quit=true;
  81.     while (true)
  82.     {
  83.         std::lock_guard<std::mutex> lock(global_mutex);
  84.         if(global_message_list.empty()){
  85.             // 主线程 发信号给所有的子线程
  86.             // 假设:所有子线程是要把活 全部干完的!
  87.             quit=true;
  88.             break;
  89.         }
  90.     }
  91.    


  92.     for(auto &v : pool){
  93.         if(v.joinable()){
  94.             v.join();
  95.         }
  96.     }

  97.     std::cout << "主线程结束!" << std::endl;
  98.     std::cout << "统计所有字符串的总长度=" << total_size << std::endl;

  99. //     统计所有字符串的总长度=327780

  100. // real        0m10.843s
  101. // user        0m13.613s
  102. // sys        0m25.811s


  103.     return 0;
  104. }

复制代码




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

使用道具 举报

0

主题

98

帖子

200

积分

中级会员

Rank: 3Rank: 3

积分
200
沙发
发表于 2021-11-23 19:33:13 | 只看该作者
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 14:46 , Processed in 0.177145 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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