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)

相關文章
相關標籤/搜索