Mutex 线程锁
避免C++多线程对同一数据写入和读取,产生的错误
1. 锁 std::mutex
1.创建std::mutex mtx 对象 用mtx.lock()上锁 mtx.unlock() 解锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #include <iostream> #include <thread> #include <vector> #include <mutex> #include <chrono> #include <stdexcept>
int counter = 0; std::mutex mtx;
void increase(int time) { for (int i = 0; i < time; i++) { mtx.lock(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); counter++; mtx.unlock(); } }
int main(int argc, char** argv) { std::thread t1(increase, 10000); std::thread t2(increase, 10000); t1.join(); t2.join(); std::cout << "counter:" << counter << std::endl; return 0; }
|
使用std::mutex 有个问题.如果一个线程里中有有异常,返回的异常的时候没有 解锁,导致其他线程的锁死。所以引入:std::lock_guard
2. std::lock_guard
声明lock_guard 后自动进行lock() 上锁,离开作用域后会自动unlock() 解锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <iostream> #include <thread> #include <vector> #include <mutex> #include <chrono> #include <stdexcept>
int counter = 0; std::mutex mtx;
void increase_proxy(int time, int id) { for (int i = 0; i < time; i++) { std::lock_guard<std::mutex> lk(mtx); if (id == 1) { throw std::runtime_error("throw excption...."); } std::this_thread::sleep_for(std::chrono::milliseconds(1)); counter++; } }
void increase(int time, int id) { try { increase_proxy(time, id); } catch (const std::exception& e){ std::cout << "id:" << id << ", " << e.what() << std::endl; } }
int main(int argc, char** argv) { std::thread t1(increase, 10000, 1); std::thread t2(increase, 10000, 2); t1.join(); t2.join(); std::cout << "counter:" << counter << std::endl; return 0; }
|
如果想在线程里执行多次的lock() 和unlock() 就需要引入std::unique_lock,离开作用域自动解锁,支持条件判断,就需要使用std::unique_lock
3. std::unique_lock
1.普通用法
1 2 3 4 5 6 7 8 9 10 11 12 13
| std::mutex mtx;
void func() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); lock.lock(); lock.unlcok() lock.lock() }
|
2.延迟加锁
1 2 3 4 5 6 7 8 9
| std::mutex mtx;
void func() { std::unique_lock<std::mutex> lock(mtx, std::defer_lock); lock.lock(); }
|
3.加锁判断
1 2 3 4 5 6 7 8 9 10
| std::mutex mtx; std::condition_variable cv; bool ready = false;
void wait_thread() { std::unique_lock<std::mutex> lock(mtx); cv.wait(lock, []{ return ready; }); }
|
4. std::shared_lock() 共享锁多个线程共享 用在读取数据