zoukankan      html  css  js  c++  java
  • 原子操作atomic解读

    下面从一个问题引入:

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int x = 0;
    void mythread_one()
    {
        for (int i = 1; i < 1000000; i++)
        {
            x++;
        }
    }
    
    void mythread_two()
    {
        for (int i = 0; i < 1000000; i++)
        {
            x++;
        }
    }
    int main()
    { 
    
        thread  th_one(mythread_one);
        thread  th_two(mythread_two);
        th_one.join();
        th_two.join();
    
        cout << "x的值为:" << x << endl;
    
        return 0;
    }

    执行结果:

    这段程序设置了两个线程,然后对全局变量进行加加操作,但是执行的结果却不是我们真正想要的。

    解决办法可以对访问的数据加锁:

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int x = 0;
    mutex g;
    void mythread_one()
    {
        for (int i = 1; i < 10000000; i++)
        {
            g.lock();
            x++;
            g.unlock();
        }
    }
    
    void mythread_two()
    {
        for (int i = 0; i < 10000000; i++)
        {
            g.lock();
            x++;
            g.unlock();
        }
    }
    int main()
    { 
    
        thread  th_one(mythread_one);
        thread  th_two(mythread_two);
        th_one.join();
        th_two.join();
    
        cout << "x的值为:" << x << endl;
    
        return 0;
    }

    这样的确可以解决问题,但是为了提升效率,C++11引入了原子操作atomic<>,它能够保证在读取数据的时候不会被打断,和加锁机制相比,他的效率更高.

    代码演示:

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int x = 0;
    atomic<int> g = 0;
    void mythread_one()
    {
        for (int i = 1; i < 10000000; i++)
        {
            g++;
        }
    }
    
    void mythread_two()
    {
        for (int i = 0; i < 10000000; i++)
        {
            g++;
        }
    }
    int main()
    { 
    
        thread  th_one(mythread_one);
        thread  th_two(mythread_two);
        th_one.join();
        th_two.join();
    
        cout << "x的值为:" << x << endl;
    
        return 0;
    }

    接下来再看另一个原子操作atomic<bool> ,他用于终止线程的执行:

    // ConsoleApplication5.cpp : 定义控制台应用程序的入口点。
    #include "stdafx.h"
    #include<random>
    #include<iostream>
    #include<vector>
    #include<thread>
    #include<algorithm>
    #include<future>
    using namespace std;
    int x = 0;
    atomic<bool> g_ifend=false;
    void mythread()
    {
        cout << "子线程1开始执行了" << endl;
        while (g_ifend == false)
        {    
            cout << "任务执行中..." << endl;
            this_thread::sleep_for(chrono::seconds(2));
        }
        cout << "子线程任务执行结束" << endl;
    }
    
    
    int main()
    { 
    
        cout << "主线程开始执行了" << endl;
        thread  th(mythread);
        this_thread::sleep_for(chrono::seconds(5));
        g_ifend = true;//让主线程等待5秒,过了5秒,让子线程结束任务
        th.join();
        cout << "主线程执行任务结束了" << endl;
    
    
    
        return 0;
    }
  • 相关阅读:
    xcode 各种项目设置
    poj 2240 floyd算法
    MySQL參数binlog-do-db对binlogs写入的影响
    cocos2D(一)----第一个cocos2D程序
    mahout測试朴素贝叶斯分类样例
    sql for xml query sample
    辛星解读之php中的重点函数第一节之数组函数
    java集合经常出现空指针问题的解决方案
    java常量设置的方式
    java中如果需要精确的计算答案,请避免使用double类型与float类型
  • 原文地址:https://www.cnblogs.com/SunShine-gzw/p/13537730.html
Copyright © 2011-2022 走看看