|
// 问题抛出:多线程的坑,使用了共享变量
// http://www.ai111.vip/thread-1242-1-1.html
//解决1、三个线程共享了资源,把共享去掉即可 比较高效与简单的方法
//如果可能,必须要用的方法 不使用共享变量就可以了 多定义一下变量即可啊 最后汇总
// 原则:如果没有必要,线程间不要共享资源
//解决2:如果一定要使用共享变量呢?咋办? 从共享变量作文章 原子操作atomic
//std::atomic<int>
//还是会有问题:变量都是原子操作的变量,但是如果多个组合起来又未必是原子操作了!
//多线程共享变量解决2:原子操作atomic
- #include <iostream>
- //#include <boost/thread/thread.hpp>
- #include <thread>
- #include <vector>
- #include <atomic>
- class Counter{
- public:
- Counter() : m_count(0) {}
- void addCount() {m_count++;} //从内存到寄存器 寄存器加1 写回内存
- int count() const {return m_count;}
- private:
- //int m_count;
- std::atomic<int> m_count; //原子操作变量类型 3个操作合并最小单元的原子操作
- // 原子操作的int类型
- };
- int work(int a){
- //do something
- return a + a;
- }
- template <typename Iter>
- void real_work(Counter& c, double& total_value, Iter b, Iter e){
- for(;b!=e;++b){
- total_value += work(*b);
- c.addCount();
- }
- }
- bool is_work_finished(Counter& c, int max_times){
- if(c.count() >= max_times){
- std::cout << "work工作已经完成啦!\n" << std::endl;
- return true;
- }
- //std::cout << "work工作_没有完成呢" << std::endl;
- return false;
- }
- int main(){
- std::cout << "最大并发数=" << std::thread::hardware_concurrency() << std::endl;
- // Counter c1;
- // std::cout << c1.count()<< std::endl;
- // c1.addCount();
- // c1.addCount();
- // std::cout << c1.count()<< std::endl;
- std::vector<int> vec;
- for(int i=0;i<10000000;++i){
- vec.push_back(rand() % 100);
- }
- //没跑一次的时候来计数
- Counter c1;
- double total_value = 0.0f;
- for(auto v : vec){
- total_value += work(v);
- c1.addCount();
- }
- std::cout << "计数器的执行次数=" << c1.count() << "结果=" << total_value << std::endl;
- //开多线程来做同样的工作 三个线程都会去操作的对象:c2和total_value 共享变量
- Counter c2;
- total_value = 0.0f;
- auto iter1 = vec.begin() + (vec.size() / 3);
- auto iter2 = vec.begin() + (vec.size() / 3 * 2);
- //开一个子线程 后台服务 一定要使用共享变量c2
- //问题在这里:线程之间如何保证数据是一致的?
- std::thread service_back([&c2](){
- while (!is_work_finished(c2, 10000000))
- {
- /* 当返回true的时候 该线程才算执行完毕 否则死循环里 */
- }
-
- });
- //一共三个线程 主线程 子线程t1 子线程t2
- // lambda函数? 知识盲区
- // 引用传进去:c2 total_value
- // 作为值传进去:两个迭代器
- std::thread t1([&c2,&total_value,iter1,iter2](){
- real_work(c2,total_value,iter1,iter2);
- });
- auto end = vec.end();
- std::thread t2([&c2,&total_value,iter2,end](){
- real_work(c2,total_value,iter2,end);
- });
- //主线程里 做第一区间的
- real_work(c2,total_value,vec.begin(),iter1);
- t1.join();
- t2.join();
- std::cout << "multithread_计数器的执行次数=" << c2.count() << "结果=" << total_value << std::endl;
- service_back.join();
- return 0;
- }
复制代码
|
|