1. thread
2.mutex和std::lock_guard的使用
头文件是#include <mutex>,mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。
但使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程。示例:
#include <iostream> #include <thread> #include <mutex> #include <stdlib.h> int cnt = 20; std::mutex m; void t1() { while (cnt > 0) { std::lock_guard<std::mutex> lockGuard(m); // std::m.lock(); if (cnt > 0) { //sleep(1); --cnt; std::cout << cnt << std::endl; } // std::m.unlock(); } } void t2() { while (cnt > 0) { std::lock_guard<std::mutex> lockGuard(m); // std::m.lock(); if (cnt > 0) { --cnt; std::cout << cnt << std::endl; } // std::m.unlock(); } } int main(void) { std::thread th1(t1); std::thread th2(t2); th1.join(); //等待t1退出 th2.join(); //等待t2退出 std::cout << "here is the main()" << std::endl; return 0; }
因为lock_guard是基于作用域的,因此可以通过{}(花括号可以看作是作用域标识符,表示某些变量的作用域,决定他们的生命周期),来定义临界区的大小。
这边举个花括号决定作用域的例子:
void fun()
{ int a; { std::lock_guard<std::mutex> lockGuard(m); int b; a=0;//正确,a在作用域内 } b=0; //错误,b的生命周期在上个{}结束了 }