C++11多线程编程(四)——原子操做

今天和你们说说C++多线程中的原子操做。首先为何会有原子操做呢?这纯粹就是C++这门语言的特性所决定的,C++这门语言是为性能而生的,它对性能的追求是没有极限的,它老是想尽一切办法提升性能。互斥锁是能够实现数据的同步,但同时是以牺牲性能为代价的。口说无凭,咱们作个实验就知道了。ios

咱们将一个数加一再减一,循环必定的次数,开启20个线程来观察,这个正确的结果应该是等于0的。多线程

首先是不加任何互斥锁同步app

#include <iostream>
#include <thread>
#include <atomic>
#include <time.h>
#include <mutex>
using namespace std;
 
#define MAX 100000
#define THREAD_COUNT 20
int total = 0;
void thread_task()
{
    for (int i = 0; i < MAX; i++)
    {
        total += 1;
        total -= 1;
    }
}
 
int main()
{
    clock_t start = clock();
    thread t[THREAD_COUNT];
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i] = thread(thread_task);
    }
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i].join();
    }
    
    clock_t finish = clock();
    cout << "result:" << total << endl;
    cout << "duration:" << finish - start << "ms" << endl;
    return 0;
}

以上程序运行时相关快的,可是结果倒是不正确的。ide

那么咱们将线程加上互斥锁mutex再来看看。性能

#include <iostream>
#include <thread>
#include <atomic>
#include <time.h>
#include <mutex>
using namespace std;
 
#define MAX 100000
#define THREAD_COUNT 20
 
int total = 0;
mutex mt;
 
void thread_task()
{
    for (int i = 0; i < MAX; i++)
    {
        mt.lock();
        total += 1;
        total -= 1;
        mt.unlock();
    }
}
 
int main()
{
    clock_t start = clock();
    thread t[THREAD_COUNT];
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i] = thread(thread_task);
    }
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i].join();
    }
    
    clock_t finish = clock();
    // 输出结果
    cout << "result:" << total << endl;
    cout << "duration:" << finish - start << "ms" << endl;
 
    return 0;
}

咱们能够看到运行结果是正确的,可是时间比原来慢太多了。虽然很无奈,但这也是没有办法的,由于只有在保证准确的前提才能去追求性能。atom

那有没有什么办法在保证准确的同时,又能提升性能呢?spa

原子操做就横空出世了!线程

定义原子操做的时候必须引入头文件orm

#include <atomic>

那么如何利用原子操做提交计算的性能呢?实际上很简单的。blog

#include <iostream>
#include <thread>
#include <atomic>
#include <time.h>
#include <mutex>
using namespace std;
 
#define MAX 100000
#define THREAD_COUNT 20
 
//原子操做
atomic_int total(0);
 
void thread_task()
{
    for (int i = 0; i < MAX; i++)
    {
        total += 1;
        total -= 1;
    }
}
 
int main()
{
    clock_t start = clock();
    thread t[THREAD_COUNT];
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i] = thread(thread_task);
    }
    for (int i = 0; i < THREAD_COUNT; ++i)
    {
        t[i].join();
    }
    
    clock_t finish = clock();
    // 输出结果
    cout << "result:" << total << endl;
    cout << "duration:" << finish - start << "ms" << endl;
 
    return 0;
}

能够看到,咱们在这里只须要定义atomic_int total(0)就能够实现原子操做了,就不须要互斥锁了。而性能的提高也是很是明显的,这就是原子操做的魅力所在。

更多精彩内容,请关注同名公众:一点月光(alittle-moon)

相关文章
相关标签/搜索