最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11 并發(fā)指南之Lock 詳解

 更新時間:2020年02月06日 11:15:50   作者:Haippy  
這篇文章主要介紹了C++11 并發(fā)指南之Lock 詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

在 《 C++11 并發(fā)指南三(std::mutex 詳解) 》一文中我們主要介紹了 C++11 標(biāo)準(zhǔn)中的互斥量(Mutex),并簡單介紹了一下兩種鎖類型。本節(jié)將詳細(xì)介紹一下 C++11 標(biāo)準(zhǔn)的鎖類型。

C++11 標(biāo)準(zhǔn)為我們提供了兩種基本的鎖類型,分別如下:

  • std::lock_guard,與 Mutex RAII 相關(guān),方便線程對互斥量上鎖。
  • std::unique_lock,與 Mutex RAII 相關(guān),方便線程對互斥量上鎖,但提供了更好的上鎖和解鎖控制。

另外還提供了幾個與鎖類型相關(guān)的 Tag 類,分別如下:

  • std::adopt_lock_t,一個空的標(biāo)記類,定義如下:
struct adopt_lock_t {};

該類型的常量對象adopt_lock(adopt_lock 是一個常量對象,定義如下:

constexpr adopt_lock_t adopt_lock {};,// constexpr 是 C++11 中的新關(guān)鍵字)

通常作為參數(shù)傳入給 unique_lock 或 lock_guard 的構(gòu)造函數(shù)。

std::defer_lock_t,一個空的標(biāo)記類,定義如下:

struct defer_lock_t {};

該類型的常量對象 defer_lock(defer_lock 是一個常量對象,定義如下:

constexpr defer_lock_t defer_lock {};,// constexpr 是 C++11 中的新關(guān)鍵字)

通常作為參數(shù)傳入給 unique_lock 或 lock_guard 的構(gòu)造函數(shù)。

std::try_to_lock_t,一個空的標(biāo)記類,定義如下:

struct try_to_lock_t {};

該類型的常量對象 try_to_lock(try_to_lock 是一個常量對象,定義如下:

constexpr try_to_lock_t try_to_lock {};,// constexpr 是 C++11 中的新關(guān)鍵字)

通常作為參數(shù)傳入給 unique_lock 或 lock_guard 的構(gòu)造函數(shù)。后面我們會詳細(xì)介紹以上三種 Tag 類型在配合 lock_gurad 與 unique_lock 使用時的區(qū)別。

std::lock_guard 介紹

std::lock_gurad 是 C++11 中定義的模板類。定義如下:

template <class Mutex> class lock_guard;

lock_guard 對象通常用于管理某個鎖(Lock)對象,因此與 Mutex RAII 相關(guān),方便線程對互斥量上鎖,即在某個 lock_guard 對象的聲明周期內(nèi),它所管理的鎖對象會一直保持上鎖狀態(tài);而 lock_guard 的生命周期結(jié)束之后,它所管理的鎖對象會被解鎖(注:類似 shared_ptr 等智能指針管理動態(tài)分配的內(nèi)存資源 )。

模板參數(shù) Mutex 代表互斥量類型,例如 std::mutex 類型,它應(yīng)該是一個基本的 BasicLockable 類型,標(biāo)準(zhǔn)庫中定義幾種基本的 BasicLockable 類型,分別 std::mutex, std::recursive_mutex, std::timed_mutex,std::recursive_timed_mutex (以上四種類型均已在上一篇博客中介紹)以及 std::unique_lock(本文后續(xù)會介紹 std::unique_lock)。(注:BasicLockable 類型的對象只需滿足兩種操作,lock 和 unlock,另外還有 Lockable 類型,在 BasicLockable 類型的基礎(chǔ)上新增了 try_lock 操作,因此一個滿足 Lockable 的對象應(yīng)支持三種操作:lock,unlock 和 try_lock;最后還有一種 TimedLockable 對象,在 Lockable 類型的基礎(chǔ)上又新增了 try_lock_for 和 try_lock_until 兩種操作,因此一個滿足 TimedLockable 的對象應(yīng)支持五種操作:lock, unlock, try_lock, try_lock_for, try_lock_until)。

在 lock_guard 對象構(gòu)造時,傳入的 Mutex 對象(即它所管理的 Mutex 對象)會被當(dāng)前線程鎖住。在lock_guard 對象被析構(gòu)時,它所管理的 Mutex 對象會自動解鎖,由于不需要程序員手動調(diào)用 lock 和 unlock 對 Mutex 進(jìn)行上鎖和解鎖操作,因此這也是最簡單安全的上鎖和解鎖方式,尤其是在程序拋出異常后先前已被上鎖的 Mutex 對象可以正確進(jìn)行解鎖操作,極大地簡化了程序員編寫與 Mutex 相關(guān)的異常處理代碼。

值得注意的是,lock_guard 對象并不負(fù)責(zé)管理 Mutex 對象的生命周期,lock_guard 對象只是簡化了 Mutex 對象的上鎖和解鎖操作,方便線程對互斥量上鎖,即在某個 lock_guard 對象的聲明周期內(nèi),它所管理的鎖對象會一直保持上鎖狀態(tài);而 lock_guard 的生命周期結(jié)束之后,它所管理的鎖對象會被解鎖。

std::lock_guard 構(gòu)造函數(shù)

lock_guard 構(gòu)造函數(shù)如下表所示:

locking (1)
explicit lock_guard (mutex_type& m);
adopting (2)
lock_guard (mutex_type& m, adopt_lock_t tag);
copy [deleted](3)
lock_guard (const lock_guard&) = delete;

locking 初始化
lock_guard 對象管理 Mutex 對象 m,并在構(gòu)造時對 m 進(jìn)行上鎖(調(diào)用 m.lock())。

adopting初始化
lock_guard 對象管理 Mutex 對象 m,與 locking 初始化(1) 不同的是, Mutex 對象 m 已被當(dāng)前線程鎖住。

拷貝構(gòu)造
lock_guard 對象的拷貝構(gòu)造和移動構(gòu)造(move construction)均被禁用,因此 lock_guard 對象不可被拷貝構(gòu)造或移動構(gòu)造。

我們來看一個簡單的例子(參考):

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::lock_guard, std::adopt_lock

std::mutex mtx;      // mutex for critical section

void print_thread_id (int id) {
 mtx.lock();
 std::lock_guard<std::mutex> lck(mtx, std::adopt_lock);
 std::cout << "thread #" << id << '\n';
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(print_thread_id,i+1);

 for (auto& th : threads) th.join();

 return 0;
}

在 print_thread_id 中,我們首先對 mtx 進(jìn)行上鎖操作(mtx.lock();),然后用 mtx 對象構(gòu)造一個 lock_guard 對象(std::lock_guard<std::mutex> lck(mtx, std::adopt_lock);),注意此時 Tag 參數(shù)為 std::adopt_lock,表明當(dāng)前線程已經(jīng)獲得了鎖,此后 mtx 對象的解鎖操作交由 lock_guard 對象 lck 來管理,在 lck 的生命周期結(jié)束之后,mtx 對象會自動解鎖。lock_guard 最大的特點(diǎn)就是安全易于使用,請看下面例子(參考),在異常拋出的時候通過 lock_guard 對象管理的 Mutex 可以得到正確地解鎖。

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::lock_guard
#include <stdexcept>   // std::logic_error

std::mutex mtx;

void print_even (int x) {
 if (x%2==0) std::cout << x << " is even\n";
 else throw (std::logic_error("not even"));
}

void print_thread_id (int id) {
 try {
  // using a local lock_guard to lock mtx guarantees unlocking on destruction / exception:
  std::lock_guard<std::mutex> lck (mtx);
  print_even(id);
 }
 catch (std::logic_error&) {
  std::cout << "[exception caught]\n";
 }
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(print_thread_id,i+1);

 for (auto& th : threads) th.join();

 return 0;
}

std::unique_lock 介紹

但是 lock_guard 最大的缺點(diǎn)也是簡單,沒有給程序員提供足夠的靈活度,因此,C++11 標(biāo)準(zhǔn)中定義了另外一個與 Mutex RAII 相關(guān)類 unique_lock,該類與 lock_guard 類相似,也很方便線程對互斥量上鎖,但它提供了更好的上鎖和解鎖控制。

顧名思義,unique_lock 對象以獨(dú)占所有權(quán)的方式( unique owership)管理 mutex 對象的上鎖和解鎖操作,所謂獨(dú)占所有權(quán),就是沒有其他的 unique_lock 對象同時擁有某個 mutex 對象的所有權(quán)。

在構(gòu)造(或移動(move)賦值)時,unique_lock 對象需要傳遞一個 Mutex 對象作為它的參數(shù),新創(chuàng)建的 unique_lock 對象負(fù)責(zé)傳入的 Mutex 對象的上鎖和解鎖操作。

std::unique_lock 對象也能保證在其自身析構(gòu)時它所管理的 Mutex 對象能夠被正確地解鎖(即使沒有顯式地調(diào)用 unlock 函數(shù))。因此,和 lock_guard 一樣,這也是一種簡單而又安全的上鎖和解鎖方式,尤其是在程序拋出異常后先前已被上鎖的 Mutex 對象可以正確進(jìn)行解鎖操作,極大地簡化了程序員編寫與 Mutex 相關(guān)的異常處理代碼。

值得注意的是,unique_lock 對象同樣也不負(fù)責(zé)管理 Mutex 對象的生命周期,unique_lock 對象只是簡化了 Mutex 對象的上鎖和解鎖操作,方便線程對互斥量上鎖,即在某個 unique_lock 對象的聲明周期內(nèi),它所管理的鎖對象會一直保持上鎖狀態(tài);而 unique_lock 的生命周期結(jié)束之后,它所管理的鎖對象會被解鎖,這一點(diǎn)和 lock_guard 類似,但 unique_lock 給程序員提供了更多的自由,我會在下面的內(nèi)容中給大家介紹 unique_lock 的用法。

另外,與 lock_guard 一樣,模板參數(shù) Mutex 代表互斥量類型,例如 std::mutex 類型,它應(yīng)該是一個基本的 BasicLockable 類型,標(biāo)準(zhǔn)庫中定義幾種基本的 BasicLockable 類型,分別 std::mutex, std::recursive_mutex, std::timed_mutex,std::recursive_timed_mutex (以上四種類型均已在上一篇博客中介紹)以及 std::unique_lock(本文后續(xù)會介紹 std::unique_lock)。(注:BasicLockable 類型的對象只需滿足兩種操作,lock 和 unlock,另外還有 Lockable 類型,在 BasicLockable 類型的基礎(chǔ)上新增了 try_lock 操作,因此一個滿足 Lockable 的對象應(yīng)支持三種操作:lock,unlock 和 try_lock;最后還有一種 TimedLockable 對象,在 Lockable 類型的基礎(chǔ)上又新增了 try_lock_for 和 try_lock_until 兩種操作,因此一個滿足 TimedLockable 的對象應(yīng)支持五種操作:lock, unlock, try_lock, try_lock_for, try_lock_until)。

std::unique_lock 構(gòu)造函數(shù)

std::unique_lock 的構(gòu)造函數(shù)的數(shù)目相對來說比 std::lock_guard 多,其中一方面也是因為 std::unique_lock 更加靈活,從而在構(gòu)造 std::unique_lock 對象時可以接受額外的參數(shù)。總地來說,std::unique_lock 構(gòu)造函數(shù)如下:

default (1)
unique_lock() noexcept;
locking (2)
explicit unique_lock(mutex_type& m);
try-locking (3)
unique_lock(mutex_type& m, try_to_lock_t tag);
deferred (4)
unique_lock(mutex_type& m, defer_lock_t tag) noexcept;
adopting (5)
unique_lock(mutex_type& m, adopt_lock_t tag);
locking for (6)
template <class Rep, class Period>
unique_lock(mutex_type& m, const chrono::duration<Rep,Period>& rel_time);
locking until (7)
template <class Clock, class Duration>
unique_lock(mutex_type& m, const chrono::time_point<Clock,Duration>& abs_time);
copy [deleted] (8)
unique_lock(const unique_lock&) = delete;
move (9)
unique_lock(unique_lock&& x);

下面我們來分別介紹以上各個構(gòu)造函數(shù):

(1) 默認(rèn)構(gòu)造函數(shù)
新創(chuàng)建的 unique_lock 對象不管理任何 Mutex 對象。
(2) locking 初始化
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象 m,并嘗試調(diào)用 m.lock() 對 Mutex 對象進(jìn)行上鎖,如果此時另外某個 unique_lock 對象已經(jīng)管理了該 Mutex 對象 m,則當(dāng)前線程將會被阻塞。
(3) try-locking 初始化
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象 m,并嘗試調(diào)用 m.try_lock() 對 Mutex 對象進(jìn)行上鎖,但如果上鎖不成功,并不會阻塞當(dāng)前線程。
(4) deferred 初始化
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象 m,但是在初始化的時候并不鎖住 Mutex 對象。 m 應(yīng)該是一個沒有當(dāng)前線程鎖住的 Mutex 對象。
(5) adopting 初始化
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象 m, m 應(yīng)該是一個已經(jīng)被當(dāng)前線程鎖住的 Mutex 對象。(并且當(dāng)前新創(chuàng)建的 unique_lock 對象擁有對鎖(Lock)的所有權(quán))。
(6) locking 一段時間(duration)
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象 m,并試圖通過調(diào)用 m.try_lock_for(rel_time) 來鎖住 Mutex 對象一段時間(rel_time)。
(7) locking 直到某個時間點(diǎn)(time point)
新創(chuàng)建的 unique_lock 對象管理 Mutex 對象m,并試圖通過調(diào)用 m.try_lock_until(abs_time) 來在某個時間點(diǎn)(abs_time)之前鎖住 Mutex 對象。
(8) 拷貝構(gòu)造 [被禁用]
unique_lock 對象不能被拷貝構(gòu)造。
(9) 移動(move)構(gòu)造
新創(chuàng)建的 unique_lock 對象獲得了由 x 所管理的 Mutex 對象的所有權(quán)(包括當(dāng)前 Mutex 的狀態(tài))。調(diào)用 move 構(gòu)造之后, x 對象如同通過默認(rèn)構(gòu)造函數(shù)所創(chuàng)建的,就不再管理任何 Mutex 對象了。
綜上所述,由 (2) 和 (5) 創(chuàng)建的 unique_lock 對象通常擁有 Mutex 對象的鎖。而通過 (1) 和 (4) 創(chuàng)建的則不會擁有鎖。通過 (3),(6) 和 (7) 創(chuàng)建的 unique_lock 對象,則在 lock 成功時獲得鎖。

關(guān)于unique_lock 的構(gòu)造函數(shù),請看下面例子(參考):

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::lock, std::unique_lock
             // std::adopt_lock, std::defer_lock
std::mutex foo,bar;

void task_a () {
 std::lock (foo,bar);     // simultaneous lock (prevents deadlock)
 std::unique_lock<std::mutex> lck1 (foo,std::adopt_lock);
 std::unique_lock<std::mutex> lck2 (bar,std::adopt_lock);
 std::cout << "task a\n";
 // (unlocked automatically on destruction of lck1 and lck2)
}

void task_b () {
 // foo.lock(); bar.lock(); // replaced by:
 std::unique_lock<std::mutex> lck1, lck2;
 lck1 = std::unique_lock<std::mutex>(bar,std::defer_lock);
 lck2 = std::unique_lock<std::mutex>(foo,std::defer_lock);
 std::lock (lck1,lck2);    // simultaneous lock (prevents deadlock)
 std::cout << "task b\n";
 // (unlocked automatically on destruction of lck1 and lck2)
}


int main ()
{
 std::thread th1 (task_a);
 std::thread th2 (task_b);

 th1.join();
 th2.join();

 return 0;
}

std::unique_lock 移動(move assign)賦值操作

std::unique_lock 支持移動賦值(move assignment),但是普通的賦值被禁用了,

move (1)
unique_lock& operator= (unique_lock&& x) noexcept;
copy [deleted] (2)
unique_lock& operator= (const unique_lock&) = delete;

移動賦值(move assignment)之后,由 x 所管理的 Mutex 對象及其狀態(tài)將會被新的 std::unique_lock 對象取代。

如果被賦值的對象之前已經(jīng)獲得了它所管理的 Mutex 對象的鎖,則在移動賦值(move assignment)之前會調(diào)用 unlock 函數(shù)釋放它所占有的鎖。

調(diào)用移動賦值(move assignment)之后, x 對象如同通過默認(rèn)構(gòu)造函數(shù)所創(chuàng)建的,也就不再管理任何 Mutex 對象了。請看下面例子(參考):

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock

std::mutex mtx;      // mutex for critical section

void print_fifty (char c) {
 std::unique_lock<std::mutex> lck;     // default-constructed
 lck = std::unique_lock<std::mutex>(mtx); // move-assigned
 for (int i=0; i<50; ++i) { std::cout << c; }
 std::cout << '\n';
}

int main ()
{
 std::thread th1 (print_fifty,'*');
 std::thread th2 (print_fifty,'$');

 th1.join();
 th2.join();

 return 0;
}

std::unique_lock 主要成員函數(shù)

本節(jié)我們來看看 std::unique_lock 的主要成員函數(shù)。由于 std::unique_lock 比 std::lock_guard 操作靈活,因此它提供了更多成員函數(shù)。具體分類如下:

  1. 上鎖/解鎖操作:lock,try_lock,try_lock_for,try_lock_until 和 unlock
  2. 修改操作:移動賦值(move assignment)(前面已經(jīng)介紹過了),交換(swap)(與另一個 std::unique_lock 對象交換它們所管理的 Mutex 對象的所有權(quán)),釋放(release)(返回指向它所管理的 Mutex 對象的指針,并釋放所有權(quán))
  3. 獲取屬性操作:owns_lock(返回當(dāng)前 std::unique_lock 對象是否獲得了鎖)、operator bool()(與 owns_lock 功能相同,返回當(dāng)前 std::unique_lock 對象是否獲得了鎖)、mutex(返回當(dāng)前 std::unique_lock 對象所管理的 Mutex 對象的指針)。

std::unique_lock::lock請看下面例子(參考):

上鎖操作,調(diào)用它所管理的 Mutex 對象的 lock 函數(shù)。如果在調(diào)用  Mutex 對象的 lock 函數(shù)時該 Mutex 對象已被另一線程鎖住,則當(dāng)前線程會被阻塞,直到它獲得了鎖。

該函數(shù)返回時,當(dāng)前的 unique_lock 對象便擁有了它所管理的 Mutex 對象的鎖。如果上鎖操作失敗,則拋出 system_error 異常。

// unique_lock::lock/unlock
#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::defer_lock

std::mutex mtx;      // mutex for critical section

void print_thread_id (int id) {
 std::unique_lock<std::mutex> lck (mtx,std::defer_lock);
 // critical section (exclusive access to std::cout signaled by locking lck):
 lck.lock();
 std::cout << "thread #" << id << '\n';
 lck.unlock();
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(print_thread_id,i+1);

 for (auto& th : threads) th.join();

 return 0;
}

std::unique_lock::try_lock

上鎖操作,調(diào)用它所管理的 Mutex 對象的 try_lock 函數(shù),如果上鎖成功,則返回 true,否則返回 false。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <vector>     // std::vector
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::defer_lock

std::mutex mtx;      // mutex for critical section

void print_star () {
 std::unique_lock<std::mutex> lck(mtx,std::defer_lock);
 // print '*' if successfully locked, 'x' otherwise: 
 if (lck.try_lock())
  std::cout << '*';
 else          
  std::cout << 'x';
}

int main ()
{
 std::vector<std::thread> threads;
 for (int i=0; i<500; ++i)
  threads.emplace_back(print_star);

 for (auto& x: threads) x.join();

 return 0;
}

std::unique_lock::try_lock_for

上鎖操作,調(diào)用它所管理的 Mutex 對象的 try_lock_for 函數(shù),如果上鎖成功,則返回 true,否則返回 false。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <chrono>     // std::chrono::milliseconds
#include <thread>     // std::thread
#include <mutex>     // std::timed_mutex, std::unique_lock, std::defer_lock

std::timed_mutex mtx;

void fireworks () {
 std::unique_lock<std::timed_mutex> lck(mtx,std::defer_lock);
 // waiting to get a lock: each thread prints "-" every 200ms:
 while (!lck.try_lock_for(std::chrono::milliseconds(200))) {
  std::cout << "-";
 }
 // got a lock! - wait for 1s, then this thread prints "*"
 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
 std::cout << "*\n";
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(fireworks);

 for (auto& th : threads) th.join();

 return 0;
}

std::unique_lock::try_lock_until

上鎖操作,調(diào)用它所管理的 Mutex 對象的 try_lock_for 函數(shù),如果上鎖成功,則返回 true,否則返回 false。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <chrono>     // std::chrono::milliseconds
#include <thread>     // std::thread
#include <mutex>     // std::timed_mutex, std::unique_lock, std::defer_lock

std::timed_mutex mtx;

void fireworks () {
 std::unique_lock<std::timed_mutex> lck(mtx,std::defer_lock);
 // waiting to get a lock: each thread prints "-" every 200ms:
 while (!lck.try_lock_for(std::chrono::milliseconds(200))) {
  std::cout << "-";
 }
 // got a lock! - wait for 1s, then this thread prints "*"
 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
 std::cout << "*\n";
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(fireworks);

 for (auto& th : threads) th.join();

 return 0;
}

std::unique_lock::unlock

解鎖操作,調(diào)用它所管理的 Mutex 對象的 unlock 函數(shù)。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::defer_lock

std::mutex mtx;      // mutex for critical section

void print_thread_id (int id) {
 std::unique_lock<std::mutex> lck (mtx,std::defer_lock);
 // critical section (exclusive access to std::cout signaled by locking lck):
 lck.lock();
 std::cout << "thread #" << id << '\n';
 lck.unlock();
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(print_thread_id,i+1);

 for (auto& th : threads) th.join();

 return 0;
}

std::unique_lock::release

返回指向它所管理的 Mutex 對象的指針,并釋放所有權(quán)。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <vector>     // std::vector
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock

std::mutex mtx;
int count = 0;

void print_count_and_unlock (std::mutex* p_mtx) {
 std::cout << "count: " << count << '\n';
 p_mtx->unlock();
}

void task() {
 std::unique_lock<std::mutex> lck(mtx);
 ++count;
 print_count_and_unlock(lck.release());
}

int main ()
{
 std::vector<std::thread> threads;
 for (int i=0; i<10; ++i)
  threads.emplace_back(task);

 for (auto& x: threads) x.join();

 return 0;
}

std::unique_lock::owns_lock

返回當(dāng)前 std::unique_lock 對象是否獲得了鎖。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <vector>     // std::vector
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::try_to_lock

std::mutex mtx;      // mutex for critical section

void print_star () {
 std::unique_lock<std::mutex> lck(mtx,std::try_to_lock);
 // print '*' if successfully locked, 'x' otherwise: 
 if (lck.owns_lock())
  std::cout << '*';
 else          
  std::cout << 'x';
}

int main ()
{
 std::vector<std::thread> threads;
 for (int i=0; i<500; ++i)
  threads.emplace_back(print_star);

 for (auto& x: threads) x.join();

 return 0;
}

std::unique_lock::operator bool()

與 owns_lock 功能相同,返回當(dāng)前 std::unique_lock 對象是否獲得了鎖。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <vector>     // std::vector
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::try_to_lock

std::mutex mtx;      // mutex for critical section

void print_star () {
 std::unique_lock<std::mutex> lck(mtx,std::try_to_lock);
 // print '*' if successfully locked, 'x' otherwise: 
 if (lck)
  std::cout << '*';
 else          
  std::cout << 'x';
}

int main ()
{
 std::vector<std::thread> threads;
 for (int i=0; i<500; ++i)
  threads.emplace_back(print_star);

 for (auto& x: threads) x.join();

 return 0;
}

std::unique_lock::mutex

返回當(dāng)前 std::unique_lock 對象所管理的 Mutex 對象的指針。

請看下面例子(參考):

#include <iostream>    // std::cout
#include <thread>     // std::thread
#include <mutex>     // std::mutex, std::unique_lock, std::defer_lock

class MyMutex : public std::mutex {
 int _id;
public:
 MyMutex (int id) : _id(id) {}
 int id() {return _id;}
};

MyMutex mtx (101);

void print_ids (int id) {
 std::unique_lock<MyMutex> lck (mtx);
 std::cout << "thread #" << id << " locked mutex " << lck.mutex()->id() << '\n';
}

int main ()
{
 std::thread threads[10];
 // spawn 10 threads:
 for (int i=0; i<10; ++i)
  threads[i] = std::thread(print_ids,i+1);

 for (auto& th : threads) th.join();

 return 0;
}

好了,本文先介紹到這里,我們基本上介紹完了 C++11 多線程編程中兩種最基本的鎖類型,后面我會繼續(xù)更新有關(guān) C++11 并發(fā)編程的博客,希望感興趣的同學(xué)繼續(xù)關(guān)注 ;-)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解C++ 編寫String 的構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值函數(shù)

    詳解C++ 編寫String 的構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值函數(shù)

    這篇文章主要介紹了詳解C++ 編寫String 的構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)、析構(gòu)函數(shù)和賦值函數(shù)的相關(guān)資料,這里提供實(shí)例幫助大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08
  • 基于C++內(nèi)存分配、函數(shù)調(diào)用與返回值的深入分析

    基于C++內(nèi)存分配、函數(shù)調(diào)用與返回值的深入分析

    本篇文章是對C++中的內(nèi)存分配、函數(shù)調(diào)用與返回值進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語言結(jié)構(gòu)體的全方面解讀

    C語言結(jié)構(gòu)體的全方面解讀

    C 數(shù)組允許定義可存儲相同類型數(shù)據(jù)項的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲不同類型的數(shù)據(jù)項
    2021-10-10
  • c++編寫String類代碼實(shí)例

    c++編寫String類代碼實(shí)例

    這篇文章主要介紹了c++編寫String類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • C++11 并發(fā)指南之std::thread 詳解

    C++11 并發(fā)指南之std::thread 詳解

    這篇文章主要介紹了C++11 并發(fā)指南之std::thread 詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • C++實(shí)現(xiàn)LeetCode(647.回文子字符串)

    C++實(shí)現(xiàn)LeetCode(647.回文子字符串)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(647.回文子字符串),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • 淺談c++中“::”和“:” 冒號的意思

    淺談c++中“::”和“:” 冒號的意思

    這篇文章主要介紹了淺談c++中“::”和“:” 冒號的意思,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • C++實(shí)現(xiàn)通訊錄系統(tǒng)項目實(shí)戰(zhàn)

    C++實(shí)現(xiàn)通訊錄系統(tǒng)項目實(shí)戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)通訊錄系統(tǒng)項目實(shí)戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Linux網(wǎng)絡(luò)編程之socket文件傳輸示例

    Linux網(wǎng)絡(luò)編程之socket文件傳輸示例

    這篇文章主要介紹了Linux網(wǎng)絡(luò)編程之socket文件傳輸示例,對于基于Linux平臺的C程序員來說有一定的借鑒價值,需要的朋友可以參考下
    2014-08-08
  • 深入探究C語言中的二叉樹

    深入探究C語言中的二叉樹

    樹是一種非線性的數(shù)據(jù)結(jié)構(gòu),它是由n(n>=0)個有限結(jié)點(diǎn)組成一個具有層次關(guān)系的集合。把它叫做樹是因 為它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。本文將帶你深入探究C語言中的二叉樹,感興趣的同學(xué)跟著小編一起學(xué)習(xí)吧
    2023-05-05

最新評論

上虞市| 阳曲县| 建瓯市| 射洪县| 巴林右旗| 桐梓县| 广河县| 湘乡市| 湟中县| 鱼台县| 湘阴县| 大埔区| 砀山县| 确山县| 渑池县| 寻甸| 无锡市| 正蓝旗| 平和县| 宝兴县| 盐边县| 利川市| 马山县| 公主岭市| 蓬莱市| 巴林左旗| 宣威市| 休宁县| 岫岩| 普安县| 遂川县| 淮北市| 右玉县| 田东县| 闽侯县| 奎屯市| 上杭县| 湘西| 介休市| 成安县| 绥化市|