熱線(xian)電話:0755-23712116
郵箱:contact@legoupos.cn
地址:深圳市寶安(an)區沙井街道(dao)后亭茅洲山工業(ye)園工業(ye)大廈全至科技創新(xin)園科創大廈2層2A
今天和大家說(shuo)說(shuo)C++多(duo)線程中的(de)原(yuan)子(zi)操作。首先為什么會有原(yuan)子(zi)操作呢?這(zhe)純粹就(jiu)是(shi)C++這(zhe)門語(yu)言的(de)特性(xing)(xing)所(suo)決定的(de),C++這(zhe)門語(yu)言是(shi)為性(xing)(xing)能而生的(de),它(ta)(ta)對性(xing)(xing)能的(de)追求(qiu)是(shi)沒有極限的(de),它(ta)(ta)總是(shi)想盡一切辦法提高性(xing)(xing)能。互斥(chi)鎖是(shi)可以實(shi)現數據的(de)同(tong)步,但同(tong)時是(shi)以犧牲(sheng)性(xing)(xing)能為代價的(de)。口說(shuo)無憑,我們做個實(shi)驗就(jiu)知道(dao)了。
我們將一(yi)個數加一(yi)再(zai)減一(yi),循環一(yi)定的次數,開啟20個線程來觀察,這個正(zheng)確(que)的結果應(ying)該是等(deng)于0的。
首先是不加任何互斥鎖同(tong)步
#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;
}
以上程(cheng)序(xu)運(yun)行時相關快的,但是(shi)結果卻是(shi)不正(zheng)確(que)的。
那(nei)么我們將線程加上互斥鎖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();
// 輸出結(jie)果
cout << "result:" << total << endl;
cout << "duration:" << finish - start << "ms" << endl;
return 0;
}
我們可以看到運行結果是(shi)正確的(de),但(dan)是(shi)時間比原來慢太多(duo)了(le)。雖然很無奈,但(dan)這也是(shi)沒有辦法的(de),因為只有在保證(zheng)準確的(de)前提才(cai)能去追求性能。
那有(you)沒(mei)有(you)什么辦法在保證準確的(de)同時,又能提高性(xing)能呢?
原子(zi)操作就橫空出(chu)世(shi)了!
定義原子操作的(de)時候必須引入頭文件
#include <atomic>
那(nei)么如何利用原子(zi)操(cao)作提交計算的(de)性能呢(ni)?實際上很簡(jian)單的(de)。
#include <iostream>
#include <thread>
#include <atomic>
#include <time.h>
#include <mutex>
using namespace std;
#define MAX 100000
#define THREAD_COUNT 20
//原子操(cao)作
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;
}
可(ke)(ke)以看到(dao),我們在這(zhe)里只(zhi)需(xu)要定義atomic_int total(0)就可(ke)(ke)以實現(xian)原子操作了(le),就不(bu)需(xu)要互斥鎖(suo)了(le)。而性能的(de)(de)提(ti)升也是(shi)非(fei)常明(ming)顯(xian)的(de)(de),這(zhe)就是(shi)原子操作的(de)(de)魅力(li)所(suo)在。