C++ åèæå
- C++11
- C++14
- C++17
- C++20
- C++ ç¼è¯å¨æ¯ææ åµè¡¨
- ç¬ç«ä¸å®¿ä¸»å®ç°
- C++ è¯è¨
- C++ å ³é®è¯
- é¢å¤çå¨
- C++ æ ååºå¤´æä»¶
- å ·åè¦æ±
- åè½ç¹æ§æµè¯ (C++20)
- å·¥å ·åº
- ç±»åæ¯æï¼åºæ¬ç±»åãRTTIãç±»åç¹æ§ï¼
- æ¦å¿µåº (C++20)
- é误å¤ç
- 卿å å管ç
- æ¥æåæ¶é´å·¥å ·
- å符串åº
- 容å¨åº
- è¿ä»£å¨åº
- èå´åº (C++20)
- ç®æ³åº
- æ°å¼åº
- è¾å ¥/è¾åºåº
- æä»¶ç³»ç»åº
- æ¬å°ååº
- æ£å表达å¼åº
- ååæä½åº
- çº¿ç¨æ¯æåº
- std::thread
- std::stop_token
- std::stop_source
- std::stop_callback
- std::this_thread::get_id
- std::shared_timed_mutex
- std::shared_lock
- std::lock_guard
- std::hardware_destructive_interference_size, std::hardware_constructive_interference_size
- std::counting_semaphore, std::binary_semaphore
- std::jthread
- cpp/thread/barrier
- std::future
- std::this_thread::yield
- std::this_thread::sleep_for
- std::this_thread::sleep_until
- std::mutex
- std::recursive_mutex
- std::shared_mutex
- std::timed_mutex
- std::recursive_timed_mutex
- std::scoped_lock
- std::unique_lock
- std::defer_lock_t, std::try_to_lock_t, std::adopt_lock_t
- std::lock
- std::try_lock
- std::defer_lock, std::try_to_lock, std::adopt_lock
- std::once_flag
- std::call_once
- std::condition_variable
- std::condition_variable_any
- std::notify_all_at_thread_exit
- std::cv_status
- std::latch
- std::promise
- std::shared_future
- std::packaged_task
- std::async
- std::launch
- std::future_status
- std::future_error
- std::future_category
- std::future_errc
- 注é
- å®éªæ§ C++ ç¹æ§
- æç¨çèµæº
- ç´¢å¼
- std 符å·ç´¢å¼
- åç¨æ¯æ (C++20)
- C++ å ³é®è¯
ä½ç½®ï¼é¦é¡µ > C++ åèæå >çº¿ç¨æ¯æåº > std::scoped_lock
std::scoped_lock
| å®ä¹äºå¤´æä»¶ <mutex>
|
||
| template< class... MutexTypes > class scoped_lock; |
(C++17 èµ·) | |
ç±» scoped_lock æ¯æä¾ä¾¿å© RAII 飿 ¼æºå¶çäºæ¥å
è£
å¨ï¼å®å¨ä½ç¨ååçå卿é´å æä¸æå¤ä¸ªäºæ¥ã
å建 scoped_lock 对象æ¶ï¼å®è¯å¾åå¾ç»å®äºæ¥çæææãæ§å¶ç¦»å¼å建 scoped_lock 对象çä½ç¨åæ¶ï¼ææ scoped_lock 并以éåºéæ¾äºæ¥ãè¥ç»åºæ°ä¸ªäºæ¥ï¼å使ç¨å
æ»éç®æ³ï¼å¦å以 std::lock ã
scoped_lock ç±»ä¸å¯å¤å¶ã
模æ¿å½¢å
| MutexTypes | - | è¦éå®çäºæ¥ç±»åãç±»åå¿ é¡»æ»¡è¶³å¯éå® (Lockable) è¦æ±ï¼é¤é sizeof...(MutexTypes)==1 ï¼è¯¥æ åµä¸å¯ä¸çç±»åå¿ é¡»æ»¡è¶³åºæ¬å¯éå® (BasicLockable) |
æåç±»å
| Â | |
| æåç±»å | å®ä¹ |
mutex_type (è¥ sizeof...(MutexTypes)==1)
|
Mutex ï¼ MutexTypes... ä¸çåç¬ç±»å
|
æå彿°
| æé scoped_lock ï¼å¯éå°éå®ç»å®çäºæ¥ (å ¬å¼æå彿°) | |
| ææ scoped_lock 对象ï¼è§£éåºå±äºæ¥ (å ¬å¼æå彿°) | |
| operator= [被å é¤] |
ä¸å¯å¤å¶ (å ¬å¼æå彿°) |
示ä¾
以ä¸ç¤ºä¾ç¨ std::scoped_lock éå®äºæ¥å¯¹è䏿»éï¼ä¸ä¸º RAII 飿 ¼ã
è¿è¡æ¤ä»£ç
#include <mutex> #include <thread> #include <iostream> #include <vector> #include <functional> #include <chrono> #include <string>  struct Employee { Employee(std::string id) : id(id) {} std::string id; std::vector<std::string> lunch_partners; std::mutex m; std::string output() const { std::string ret = "Employee " + id + " has lunch partners: "; for( const auto& partner : lunch_partners ) ret += partner + " "; return ret; } };  void send_mail(Employee &, Employee &) { // 模æèæ¶çåä¿¡æä½ std::this_thread::sleep_for(std::chrono::seconds(1)); }  void assign_lunch_partner(Employee &e1, Employee &e2) { static std::mutex io_mutex; { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " and " << e2.id << " are waiting for locks" << std::endl; }  { // ç¨ std::scoped_lock åå¾äºä¸ªéï¼èæ éæ å¿ // å ¶ä»å¯¹ assign_lunch_partner çè°ç¨æ»éæä»¬ // èä¸å®äº¦æä¾ä¾¿å©ç RAII 飿 ¼æºå¶  std::scoped_lock lock(e1.m, e2.m);  // ç价代ç 1 ï¼ç¨ std::lock å std::lock_guard ï¼ // std::lock(e1.m, e2.m); // std::lock_guard<std::mutex> lk1(e1.m, std::adopt_lock); // std::lock_guard<std::mutex> lk2(e2.m, std::adopt_lock);  // ç价代ç 2 ï¼è¥éè¦ unique_lock ï¼ä¾å¦å¯¹äºæ¡ä»¶åéï¼ // std::unique_lock<std::mutex> lk1(e1.m, std::defer_lock); // std::unique_lock<std::mutex> lk2(e2.m, std::defer_lock); // std::lock(lk1, lk2); { std::lock_guard<std::mutex> lk(io_mutex); std::cout << e1.id << " and " << e2.id << " got locks" << std::endl; } e1.lunch_partners.push_back(e2.id); e2.lunch_partners.push_back(e1.id); }  send_mail(e1, e2); send_mail(e2, e1); }  int main() { Employee alice("alice"), bob("bob"), christina("christina"), dave("dave");  // å¨å¹¶è¡çº¿ç¨ä¸ææ´¾ï¼å 为就åé¤ææ´¾åé®ä»¶æ¶èå¾é¿æ¶é´ std::vector<std::thread> threads; threads.emplace_back(assign_lunch_partner, std::ref(alice), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(bob)); threads.emplace_back(assign_lunch_partner, std::ref(christina), std::ref(alice)); threads.emplace_back(assign_lunch_partner, std::ref(dave), std::ref(bob));  for (auto &thread : threads) thread.join(); std::cout << alice.output() << '\n' << bob.output() << '\n' << christina.output() << '\n' << dave.output() << '\n'; }
å¯è½çè¾åºï¼
alice and bob are waiting for locks alice and bob got locks christina and bob are waiting for locks christina and alice are waiting for locks dave and bob are waiting for locks dave and bob got locks christina and alice got locks christina and bob got locks Employee alice has lunch partners: bob christina Employee bob has lunch partners: alice dave christina Employee christina has lunch partners: alice bob Employee dave has lunch partners: bob
ç¼ºé·æ¥å
ä¸åæ´æ¹è¡ä¸ºçç¼ºé·æ¥å追溯å°åºç¨äºä»¥ååºçç C++ æ åã
| DR | åºç¨äº | åºçæ¶çè¡ä¸º | æ£ç¡®è¡ä¸º |
|---|---|---|---|
| LWG 2981 | C++17 | æ¾æä¾æ¥èª scoped_lock<MutexTypes...> çå使¨å¯¼æå¼
|
å·²ç§»é¤ |
åé
| (C++11) |
å®ç°å¯ç§»å¨çäºæ¥ä½æææå
è£
å¨ (类模æ¿) |
| (C++11) |
å®ç°ä¸¥æ ¼åºäºä½ç¨åçäºæ¥ä½æææå
è£
å¨ (类模æ¿) |