導言:随着計算機硬體條件的提升,軟體的設計與開發更多的看重其執行速度,而采用多線程并發的執行一些操作對提升效率至關重要。
C++11的出現,給了使用者很大的友善,摒棄了原有的windows線程設計函數,而采用了std::thread來設計線程函數,隻要包含頭檔案<thread.h>就行。
1.1 建立線程
std::thread t(func); //func-線程函數名, t-線程名,将線程函數放到線程t中執行。
t.join();//線程執行開始
注意:線程的開始執行方法又兩種,join(),或者detach().
join()方法: join()函數将阻塞線程直到線程函數結束
detach()方法: detach()函數将線程和線程對象分離,分離後無法再和線程函數聯系,可通過回調傳回其執行結果。
1.2 建立線程+lamada表達式
1.2.1 lamada的格式:[ 捕獲值方式](形參){函數體}
捕獲值方式有以下幾種:
[ &]:引用捕獲,直接引用線程外部函數的值,缺點是:在并發執行過程中,很可能線程所在的類已經析構,而線程函數還在執行,這樣将導緻線程函數引用的值不存在,而導緻崩潰。
[ =]:拷貝方式捕獲,拷貝一份外部函數中的變量值,跟随線程函數執行,這種方式較為穩妥
[ bar]:拷貝外部變量bar的副本供線程函數使用
[ this]:捕獲目前類中的this指針,讓lamada表達式擁有和目前類成員函數同樣的通路權限。即:使用
目前類的成員函數和成員變量。
1.2.2 互斥量
線上程的運作過程中,多個線程競争同一資源的情況下,需要用到互斥鎖來防止資源被破壞
std::mutex m_lock;
例如
void func()
{
m_lock.lock();//加鎖
funcrate();
m_lock.lock();//解鎖
}
還有一個lock_gurd,不需要進行加鎖和解鎖的頻繁操作
void func()
{
std::lock_guard<std::mutex> locker(m_lock);//加鎖,自動解鎖
funcrate();
}
遞歸互斥量:避免一個線程多次擷取互斥量時死鎖
例如:std::recursive_mutex m_mutex;
1.2.3 條件變量(另一種線程同步的方法,它将阻塞一個或多個線程直到收到另外一個線程)
condition_variable, 配合std::unique_lock<std::mutex> 進行wait操作
condition_variable_any, 可配合任意帶有lock、unlock語義的mutex 搭配使用,使用靈活
1.4 lamada+std::thread一起使用
void Func(const std::wstring& file,IAddFileCallback* pCallback)
{
int nNum=10;
std::thread t([=]()
{
shortfunc( file);
nNum++;
if (pCallback)
{
wstring strLocalCachePath = L"";
if (bResult)
strLocalCachePath = m_strLoacalParentPath + strRelativePath;
pCallback->OnFileCallback(strRelativePath, strLocalCachePath, bResult);
}
}
)
t.detach();
}
std::ref(num);//直接拷貝對象,不需要引用
1.5 線程異步擷取傳回值
可以使用是std::future來擷取線程傳回值
reterance:https://www.cnblogs.com/haippy/p/3280643.html
例如:
bool do_check_prime(int x) // 為了展現效果, 該函數故意沒有優化. { for (int i = 2; i < x; ++i) if (x % i == 0) return false; return true; }
int mian()
{
std::future < bool > fut = std::async(do_check_prime, 194232491); std::cout << "Checking...\n"; fut.wait();//等待。。。 std::cout << "\n194232491 "; if (fut.get()) // guaranteed to be ready (and not block) after wait returns std::cout << "is prime.\n"; else std::cout << "is not prime.\n"; return 0; }