东方耀AI技术分享

 找回密码
 立即注册

QQ登录

只需一步,快速开始

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

[C/C++] 问题抛出:多线程的坑,使用了共享变量

[复制链接]

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

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





问题抛出:多线程的坑,使用了共享变量




  1. #include <iostream>
  2. //#include <boost/thread/thread.hpp>
  3. #include <thread>
  4. #include <vector>

  5. // 问题抛出:多线程的坑,使用了共享变量

  6. class Counter{
  7. public:
  8.     Counter() : m_count(0) {}
  9.     void addCount() {m_count++;}
  10.     int count() const {return m_count;}
  11. private:
  12.     int m_count;
  13. };

  14. int work(int a){
  15.     //do something
  16.     return a + a;
  17. }


  18. template <typename Iter>
  19. void real_work(Counter& c, double& total_value, Iter b, Iter e){
  20.     for(;b!=e;++b){
  21.         total_value += work(*b);
  22.         c.addCount();
  23.     }
  24. }
  25.     // auto real_work = [&c2, &total_value](auto b, auto e){
  26.     //     for(;b!=e;++b){
  27.     //         total_value += work(*b);
  28.     //         c2.addCount();
  29.     //     }
  30.     // };


  31. int main(){

  32.     std::cout << "最大并发数=" << std::thread::hardware_concurrency() << std::endl;
  33.     // Counter c1;
  34.     // std::cout << c1.count()<< std::endl;
  35.     // c1.addCount();
  36.     // c1.addCount();
  37.     // std::cout << c1.count()<< std::endl;
  38.     std::vector<int> vec;
  39.     for(int i=0;i<10000000;++i){
  40.         vec.push_back(rand() % 100);
  41.     }
  42.     //没跑一次的时候来计数
  43.     Counter c1;
  44.     double total_value = 0.0f;
  45.     for(auto v : vec){
  46.         total_value += work(v);
  47.         c1.addCount();
  48.     }
  49.     std::cout << "计数器的执行次数=" << c1.count() << "结果=" << total_value << std::endl;

  50.     //开多线程来做同样的工作   三个线程都会去操作的对象:c2和total_value 共享变量
  51.     Counter c2;
  52.     total_value = 0.0f;
  53.     auto iter1 = vec.begin() + (vec.size() / 3);
  54.     auto iter2 = vec.begin() + (vec.size() / 3 * 2);
  55.     //一共三个线程  主线程 子线程t1 子线程t2  
  56.     // lambda函数?  知识盲区
  57.     // 引用传进去:c2 total_value
  58.     // 作为值传进去:两个迭代器
  59.     std::thread t1([&c2,&total_value,iter1,iter2]{
  60.         real_work(c2,total_value,iter1,iter2);
  61.     });
  62.     auto end = vec.end();
  63.     std::thread t2([&c2,&total_value,iter2,end]{
  64.         real_work(c2,total_value,iter2,end);
  65.     });
  66.     //主线程里 做第一区间的  
  67.     real_work<std::vector<int>::iterator>(c2,total_value,vec.begin(),iter1);
  68.     // for(auto iter=vec.begin(); iter!=iter1; iter++){
  69.     //     total_value += work(*iter);
  70.     //     c2.addCount();
  71.     // }

  72.     t1.join();
  73.     t2.join();

  74.     std::cout << "multithread_计数器的执行次数=" << c2.count() << "结果=" << total_value << std::endl;



  75.    
  76.     return 0;
  77. }
复制代码


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

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14439
QQ
沙发
 楼主| 发表于 2021-8-6 15:33:22 | 只看该作者
  1. cmake_minimum_required (VERSION 2.8)
  2. project (main)

  3. #SET(CMAKE_CXX_STANDARD 11)
  4. #SET(CMAKE_C_STANDARD 11)

  5. #aux_source_directory(. ALL_SRCS)                        # 添加当前目录下所有的源文件
  6. set(ALL_SRCS "17_std_thread.cpp")
  7. #add_subdirectory(lib)                                                # 添加lib子目录
  8. add_executable(main ${ALL_SRCS})        # 指定生成目标,注意这里要用${ALL_SRCS}!!!
  9. message(WARNING "我说:lib目录里的文件编译成动态库再由main函数调用")
  10. #target_link_libraries(main power)        # 添加链接库,power是在lib子目录的CMakeLists中定义的

  11. find_package(FFTW3f)
  12. target_link_libraries(main -lboost_system -lboost_thread -lfftw3f -lpthread)
复制代码
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

1365

主题

1856

帖子

1万

积分

管理员

Rank: 10Rank: 10Rank: 10

积分
14439
QQ
板凳
 楼主| 发表于 2021-8-6 15:48:29 | 只看该作者
  1. #include <iostream>
  2. //#include <boost/thread/thread.hpp>
  3. #include <thread>
  4. #include <vector>

  5. //解决1、三个线程共享了资源,把共享去掉即可 比较高效与简单的方法
  6. //如果可能,必须要用的方法 不使用共享变量就可以了 多定义一下变量即可啊 最后汇总
  7. // 原则:如果没有必要,线程间不要共享资源

  8. class Counter{
  9. public:
  10.     Counter() : m_count(0) {}
  11.     void addCount() {m_count++;}
  12.     int count() const {return m_count;}
  13. private:
  14.     int m_count;
  15. };

  16. int work(int a){
  17.     //do something
  18.     return a + a;
  19. }


  20. template <typename Iter>
  21. void real_work(Counter& c, double& total_value, Iter b, Iter e){
  22.     for(;b!=e;++b){
  23.         total_value += work(*b);
  24.         c.addCount();
  25.     }
  26. }


  27. int main(){

  28.     std::cout << "最大并发数=" << std::thread::hardware_concurrency() << std::endl;
  29.     // Counter c1;
  30.     // std::cout << c1.count()<< std::endl;
  31.     // c1.addCount();
  32.     // c1.addCount();
  33.     // std::cout << c1.count()<< std::endl;
  34.     std::vector<int> vec;
  35.     for(int i=0;i<10000000;++i){
  36.         vec.push_back(rand() % 100);
  37.     }
  38.     //没跑一次的时候来计数
  39.     Counter c1;
  40.     double total_value = 0.0f;
  41.     for(auto v : vec){
  42.         total_value += work(v);
  43.         c1.addCount();
  44.     }
  45.     std::cout << "计数器的执行次数=" << c1.count() << "结果=" << total_value << std::endl;

  46.     //开多线程来做同样的工作   三个线程都会去操作的对象:c2和total_value 共享变量
  47.     Counter c2,c3,c4;
  48.     total_value = 0.0f;
  49.     double total_value1 = 0.0f;
  50.     double total_value2 = 0.0f;
  51.     auto iter1 = vec.begin() + (vec.size() / 3);
  52.     auto iter2 = vec.begin() + (vec.size() / 3 * 2);
  53.     //一共三个线程  主线程 子线程t1 子线程t2  
  54.     // lambda函数?  知识盲区
  55.     // 引用传进去:c2 total_value
  56.     // 作为值传进去:两个迭代器
  57.     std::thread t1([&c3,&total_value1,iter1,iter2]{
  58.         real_work(c3,total_value1,iter1,iter2);
  59.     });
  60.     auto end = vec.end();
  61.     std::thread t2([&c4,&total_value2,iter2,end]{
  62.         real_work(c4,total_value2,iter2,end);
  63.     });
  64.     //主线程里 做第一区间的  
  65.     real_work<std::vector<int>::iterator>(c2,total_value,vec.begin(),iter1);
  66.     // for(auto iter=vec.begin(); iter!=iter1; iter++){
  67.     //     total_value += work(*iter);
  68.     //     c2.addCount();
  69.     // }

  70.     t1.join();
  71.     t2.join();

  72.     std::cout << "multithread_计数器的执行次数=" << c2.count()+c3.count()+c4.count() << "结果=" << total_value+total_value1+total_value2 << std::endl;
  73.    
  74.     return 0;
  75. }
复制代码
让天下人人学会人工智能!人工智能的前景一片大好!
回复

使用道具 举报

0

主题

23

帖子

56

积分

注册会员

Rank: 2

积分
56
地板
发表于 2021-8-13 20:08:54 | 只看该作者
不断充实自己,不断解放自己
回复

使用道具 举报

0

主题

98

帖子

200

积分

中级会员

Rank: 3Rank: 3

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-19 12:21 , Processed in 0.201665 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

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