1、原子变量
C++11提供了原子类型std::atomic<T>,可以使用任意类型作为模板参数,使用原子变量就不需要使用互斥量来保护该变量,用起来更加简洁。
举个例子,如果要做一个计数器,使用mutex时和使用原子变量依次如下:
//使用mutex struct Counter { int value; std::mutex mutex; void increment() { std::lock_guard<std::mutex> lock(mutex); ++value; } void decrement() { std::lock_guard<std::mutex> lock(mutex); --value; } int get() { return value; } }; int main() { return 0; } //使用原子变量 #include <atomic> struct Counter { std::atomic<int> value; void increment() { ++value; } void decrement() { --value; } int get() { return value; } };
2、call_once/once_flag
单调函数就是在多线程环境中,保证某个函数只被调用一次,比如要初始化某个对象,而这个对象只能被初始化一次,就可以使用std::call_once来保证函数在多线程环境中只被调用一次。使用std::call_once时,需要一个once_flag作为call_once的入参。
作为call_once的入参。 #include <thread> #include <iostream> #include <mutex> std::once_flag flag; void do_once() { std::call_once(flag, [](){ std::cout << "Called once." << std::endl; }); } int main() { std::thread t1(do_once); std::thread t2(do_once); std::thread t3(do_once); t1.join(); t2.join(); t3.join(); return 0; } //输出: Called once.