柚子快報(bào)邀請碼778899分享:C++多線程學(xué)習(xí)04
柚子快報(bào)邀請碼778899分享:C++多線程學(xué)習(xí)04
參考
參考資料地址:戀戀風(fēng)辰官方博客
判斷是否占有鎖
#include
#include
#include
#include
//unique_lock 基本用法
std::mutex mtx;
int shared_data = 0;
void use_unique()
{
// lock可自動解鎖,也可手動解鎖
std::unique_lock
std::cout << "use unique lock, lock success" << std::endl;
shared_data++;
lock.unlock();
}
// 可以通過unique_lock的owns_lock判斷是否占有鎖
void owns_lock()
{
std::unique_lock
shared_data++;
if (lock.owns_lock()) {
std::cout << "owns lock" << std::endl;
}
else {
std::cout << "doesn't own lock" << std::endl;
}
lock.unlock();
if (lock.owns_lock()) {
std::cout << "owns lock" << std::endl;
}
else {
std::cout << "doesn't own lock" << std::endl;
}
}
int main()
{
// 1. 判斷是否占有鎖
owns_lock();
std::cout << "Finished! \n";
}
測試同時使用owns_lock和defer_lock
// 也可以延遲加鎖
void defer_lock()
{
std::unique_lock
lock.lock();
// 這里可以選擇手動解析釋放,也可以等作用域結(jié)束自動釋放
lock.unlock();
}
// 同時使用owns和defer
void use_own_defer()
{
std::unique_lock
// 判斷是否擁有鎖
if (lock.owns_lock()) {
std::cout << "Main thread has the lock \n";
}
else {
std::cout << "Main thread dose not have the lock \n";
}
std::thread t([]() {
std::unique_lock
if (lock.owns_lock()) {
std::cout << "Thread has the lock \n";
}
else {
std::cout << "Thread dose not have the lock. \n";
}
lock.lock();
if (lock.owns_lock()) {
std::cout << "Thread has the lock. \n";
}
else {
std::cout << "Thread dose not have the lock \n";
}
lock.unlock();
});
t.join();
}
int main()
{
// 2. 測試同時使用owns_lock和defer_lock
use_own_defer();
// 子線程會卡在加鎖的邏輯上, 導(dǎo)致程序阻塞
std::cout << "Finished! \n";
}
unique_lock也支持領(lǐng)養(yǎng)鎖
// unique_lock同樣支持領(lǐng)養(yǎng)
void use_own_adopt()
{
mtx.lock();
std::unique_lock
if (lock.owns_lock()) {
std::cout << "owns lock" << std::endl;
}
else {
std::cout << "dose not have the lock \n";
}
lock.unlock();
}
int main()
{
// 3. lock_guard一樣,unique_lock也支持領(lǐng)養(yǎng)鎖
// 管理自動釋放
use_own_adopt();
std::cout << "Finished! \n";
}
測試鎖的控制權(quán)轉(zhuǎn)移
// 轉(zhuǎn)移互斥量所有權(quán)
// 互斥量本身不支持move,但是unique_lock支持
std::unique_lock
{
std::unique_lock
shared_data++;
return lock;
}
void use_return()
{
std::unique_lock
shared_data++;
}
int main()
{
/*
一旦mutex被unique_lock管理,加鎖和釋放的操作就交給unique_lock,
不能調(diào)用mutex加鎖和解鎖,因?yàn)殒i的使用權(quán)已經(jīng)交給unique_lock.
unique_lock支持移動,當(dāng)一個mutex被轉(zhuǎn)移給unique_lock后,可以通過unique_ptr轉(zhuǎn)移其歸屬權(quán).
*/
// 4. 測試鎖的控制權(quán)轉(zhuǎn)移
use_return();
std::cout << "Finished! \n";
}
測試鎖的粒度
// 測試鎖的粒度
void precision_lock()
{
std::unique_lock
shared_data++;
lock.unlock();
// 耗時操作不要放在鎖內(nèi)執(zhí)行
std::this_thread::sleep_for(std::chrono::seconds(1));
lock.lock();
shared_data++;
}
int main()
{
/*
鎖的粒度表示加鎖的精細(xì)程度,一個鎖的粒度要足夠大,保證可以鎖住要訪問的共享數(shù)據(jù)。
同時一個鎖的粒度要足夠小,保證非共享數(shù)據(jù)不被鎖住影響性能。
而unique_ptr則很好的支持手動解鎖。
*/
// 5. 測試鎖的粒度
precision_lock();
std::cout << "Finished! \n";
}
測試遞歸鎖
// 遞歸鎖測試
class RecursiveDemo
{
public:
RecursiveDemo()
{
std::cout << "Init Recursive Demo! \n";
}
/* 模擬查詢學(xué)生信息 */
bool QueryStudent(std::string name)
{
std::lock_guard
#if 0
std::lock_guard
#endif
auto iter_find = _students_info.find(name);
if (iter_find == _students_info.end())
return false;
return true;
}
void AddScore(std::string name, int score) {
std::lock_guard
#if 0
std::lock_guard
#endif
if (!QueryStudent(name)) {
_students_info.insert(std::make_pair(name, score));
return;
}
std::cout << "Add score! Student: " << name << std::endl;
_students_info[name] = _students_info[name] + score;
}
private:
std::map
std::recursive_mutex _recursive_mtx;
std::mutex _mtx;
};
// 測試遞歸鎖
void test_recursive()
{
std::shared_ptr
stu_demo->AddScore("Peter", 85);
stu_demo->AddScore("Peter", 85);
}
int main()
{
/*
關(guān)于共享鎖: 讀操作不互斥,讀與寫,寫與寫互斥.
C++ 17標(biāo)準(zhǔn)shared_mutex
C++14提供了 shared_time_mutex
C++11無上述互斥,想使用可以利用boost庫
*/
// 6. 遞歸鎖,嵌套導(dǎo)致卡死
test_recursive();
std::cout << "Finished! \n";
}
柚子快報(bào)邀請碼778899分享:C++多線程學(xué)習(xí)04
推薦文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。