引用 cppreference 的先容:

The mutex class is a synchronization primitive that can be used to protect shared data from being simultaneously accessed by multiple threads.

Mutex 1

直接操作 mutex,即直接调用 mutex 的 lock / unlock 函数。

phpmutexlockC 并发编程二Mutex互斥锁 jQuery

#include <iostream>#include <mutex>#include <thread>#include <vector>std::mutex g_mutex;int g_count = 0;void Counter() { g_mutex.lock(); int i = ++g_count; std::cout << "count: " << i << std::endl; // 前面代码如有非常,unlock 就调不到了。
g_mutex.unlock();}int main() { const std::size_t SIZE = 4; // 创建一组线程。
std::vector<std::thread> v; v.reserve(SIZE); for (std::size_t i = 0; i < SIZE; ++i) { v.emplace_back(&Counter); } // 等待所有线程结束。
for (std::thread& t : v) { t.join(); } return 0;}

可惜的是,STL 没有供应 boost::thread_group 这样代表一组线程的工具,通过 std::vector 固然也能达到目的,但是代码不足简洁。

Mutex 2

利用 lock_guard 自动加锁、解锁。
事理是 RAII,和智能指针类似。

#include <iostream>#include <mutex>#include <thread>#include <vector>std::mutex g_mutex;int g_count = 0;void Counter() { // lock_guard 在布局函数里加锁,在析构函数里解锁。
std::lock_guard<std::mutex> lock(g_mutex); int i = ++g_count; std::cout << "count: " << i << std::endl;}int main() { const std::size_t SIZE = 4; std::vector<std::thread> v; v.reserve(SIZE); for (std::size_t i = 0; i < SIZE; ++i) { v.emplace_back(&Counter); } for (std::thread& t : v) { t.join(); } return 0;}
Mutex 3

利用 unique_lock 自动加锁、解锁。
unique_lock 与 lock_guard 事理相同,但是供应了更多功能(比如可以结合条件变量利用)。
把稳:mutex::scoped_lock 实在便是 unique_lock<mutex> 的 typedef。

至于 unique_lock 和 lock_guard 详细比较,可移步 StackOverflow。

#include <iostream>#include <mutex>#include <thread>#include <vector>std::mutex g_mutex;int g_count = 0;void Counter() { std::unique_lock<std::mutex> lock(g_mutex); int i = ++g_count; std::cout << "count: " << i << std::endl;}int main() { const std::size_t SIZE = 4; std::vector<std::thread> v; v.reserve(SIZE); for (std::size_t i = 0; i < SIZE; ++i) { v.emplace_back(&Counter); } for (std::thread& t : v) { t.join(); } return 0;}Mutex 4

为输出流利用单独的 mutex。
这么做是由于 IO 流并不是线程安全的!
如果不对 IO 进行同步,此例的输出很可能变成:

count == count == 2count == 41count == 3

由于不才面这条输出语句中:

std::cout << "count == " << i << std::endl;

输出 "count == " 和 i 这两个动作不是原子性的(atomic),可能被其他线程打断。

#include <iostream>#include <mutex>#include <thread>#include <vector>std::mutex g_mutex;std::mutex g_io_mutex;int g_count = 0;void Counter() { int i; { std::unique_lock<std::mutex> lock(g_mutex); i = ++g_count; } { std::unique_lock<std::mutex> lock(g_io_mutex); std::cout << "count: " << i << std::endl; }}int main() { const std::size_t SIZE = 4; std::vector<std::thread> v; v.reserve(SIZE); for (std::size_t i = 0; i < SIZE; ++i) { v.emplace_back(&Counter); } for (std::thread& t : v) { t.join(); } return 0;}