std::lock_guard
std::lock_guard<std::mutex> lk(frame_mutex);
std::unique_lock<std::mutex> lk(frame_mutex);
std::lock_guard是RAII模板类
的简单实现,功能简单。
它是与mutex配合使用,把锁放到lock_guard中时,mutex自动上锁,lock_guard析构时,同时把mutex解锁。
#include <thread> #include <mutex> int g_i = 0; std::mutex g_i_mutex; // protects g_i void safe_increment() { std::lock_guard<std::mutex> lock(g_i_mutex); ++g_i; // g_i_mutex is automatically released when lock // goes out of scope } int main() { std::thread t1(safe_increment); std::thread t2(safe_increment); t1.join(); t2.join(); }
unique_lock使用实例
#include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock #include <vector> std::mutex mtx; // mutex for critical section std::once_flag flag; void print_block (int n, char c) { //unique_lock有多组构造函数, 这里std::defer_lock不设置锁状态 std::unique_lock<std::mutex> my_lock (mtx, std::defer_lock); //尝试加锁, 如果加锁成功则执行 //(适合定时执行一个job的场景, 一个线程执行就可以, 可以用更新时间戳辅助) if(my_lock.try_lock()){ for (int i=0; i<n; ++i) std::cout << c; std::cout << '\n'; } } void run_one(int &n){ std::call_once(flag, [&n]{n=n+1;}); //只执行一次, 适合延迟加载; 多线程static变量情况 } int main () { std::vector<std::thread> ver; int num = 0; for (auto i = 0; i < 10; ++i){ ver.emplace_back(print_block,50,'*'); ver.emplace_back(run_one, std::ref(num)); } for (auto &t : ver){ t.join(); } std::cout << num << std::endl; return 0; }
std::unique_lock<std::mutex> lk(frame_mutex);
可以自动解锁,也可以手动解锁
lk.unlock();
mutex基本的加解锁
#include <thread> #include <mutex> #include <vector> #include <iostream> #include <algorithm> std::mutex my_lock; void add(int &num, int &sum){ while(true){ std::lock_guard<std::mutex> lock(my_lock); if (num < 100){ //运行条件 num += 1; sum += num; } else { //退出条件 break; } } } int main(){ int sum = 0; int num = 0; std::vector<std::thread> ver; //保存线程的vector for(int i = 0; i < 20; ++i){ std::thread t = std::thread(add, std::ref(num), std::ref(sum)); ver.emplace_back(std::move(t)); //保存线程 } std::for_each(ver.begin(), ver.end(), std::mem_fn(&std::thread::join)); //join std::cout << sum << std::endl; }