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::lock
std::lock
| å®ä¹äºå¤´æä»¶ <mutex>
|
||
| template< class Lockable1, class Lockable2, class... LockableN > void lock( Lockable1& lock1, Lockable2& lock2, LockableN&... lockn ); |
(C++11 èµ·) | |
éå®ç»å®çå¯éå® (Lockable) 对象 lock1 ã lock2 ã ... ã lockn ï¼ç¨å
æ»éç®æ³é¿å
æ»éã
以对 lock ã try_lock å unlock çæªæå®ç³»åè°ç¨éå®å¯¹è±¡ãè¥è°ç¨ lock æ unlock 导è´å¼å¸¸ï¼åå¨éæå对任ä½å·²éç对象è°ç¨ unlock ã
åæ°
| lock1, lock2, ... , lockn | - | è¦éå®çå¯éå® (Lockable) 对象 |
è¿åå¼
ï¼æ ï¼
注æ
Boost æä¾æ¤å½æ°çä¸ä¸ªçæ¬ï¼å®æ¥æ¶ä»¥ä¸å¯¹è¿ä»£å¨å®ä¹çå¯éå® (Lockable) 对象åºåã
std::scoped_lock æä¾æ¤å½æ°ç RAII å
è£
ï¼é叏宿¯è£¸è°ç¨ std::lock æ´å¥½ã
示ä¾
ä¸å示ä¾ç¨ std::lock éå®äºæ¥å¯¹ï¼è䏿»éã
è¿è¡æ¤ä»£ç
#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::lock è·å¾äºä¸ªéï¼è䏿 å¿å¯¹ assign_lunch_partner çå ¶ä»è°ç¨ä¼æ»éæä»¬ { 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); // ç价代ç ï¼è¥éè¦ unique_locks ï¼ä¾å¦å¯¹äºæ¡ä»¶åéï¼ // 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); // C++17 ä¸å¯ç¨çè¾ä¼è§£æ³ // std::scoped_lock lk(e1.m, e2.m); { 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 bob got locks christina and alice are waiting for locks christina and alice got locks dave and bob are waiting for locks dave and bob got locks Employee alice has lunch partners: bob christina Employee bob has lunch partners: alice christina dave Employee christina has lunch partners: bob alice Employee dave has lunch partners: bob
åé
| (C++11) |
è¯å¾éè¿éå¤è°ç¨ try_lock è·å¾äºæ¥ä½çæææ (彿°æ¨¡æ¿) |
| (C++17) |
ç¨äºå¤ä¸ªäºæ¥ä½çå
æ»é RAII å°è£
å¨ (类模æ¿) |