原子操作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;
}

 

posted @ 2020-08-20 20:33  sunshine_gzw  阅读(384)  评论(0编辑  收藏  举报