多个线程访问同一资源时,为了保证数据的一致性,最简单的方式就是使用 mutex(互斥锁)。
引用 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 的
#include <iostream>lock / unlock
函数。
此例顺带使用了boost::thread_group
来创建一组线程。
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
boost::mutex mutex;
int count = 0;
void Counter() {
mutex.lock();
int i = ++count;
std::cout << "count == " << i << std::endl;
// 前面代码如有异常,unlock 就调不到了。
mutex.unlock();
}
int main() {
// 创建一组线程。
boost::thread_group threads;
for (int i = 0; i < 4; ++i) {
threads.create_thread(&Counter);
}
// 等待所有线程结束。
threads.join_all();
return 0;
}Mutex 2
使用
lock_guard
自动加锁、解锁。原理是 RAII,和智能指针类似。#include <iostream>
#include <boost/thread/lock_guard.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
boost::mutex mutex;
int count = 0;
void Counter() {
// lock_guard 在构造函数里加锁,在析构函数里解锁。
boost::lock_guard<boost::mutex> lock(mutex);
int i = ++count;
std::cout << "count == " << i << std::endl;
}
int main() {
boost::thread_group threads;
for (int i = 0; i < 4; ++i) {
threads.create_thread(&Counter);
}
threads.join_all();
return 0;
}
Mutex 3
使用
#include <iostream>unique_lock
自动加锁、解锁。
unique_lock
与lock_guard
原理相同,但是提供了更多功能(比如可以结合条件变量使用)。
注意:mutex::scoped_lock
其实就是unique_lock<mutex>
的typedef
。
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
boost::mutex mutex;
int count = 0;
void Counter() {
boost::unique_lock<boost::mutex> lock(mutex);
int i = ++count;
std::cout << "count == " << i << std::endl;
}
int main() {
boost::thread_group threads;
for (int i = 0; i < 4; ++i) {
threads.create_thread(&Counter);
}
threads.join_all();
return 0;
}Mutex 4
为输出流使用单独的 mutex。
这么做是因为 IO 流并不是线程安全的!
如果不对 IO 进行同步,此例的输出很可能变成:
count == count == 2count == 41 count == 3
因为在下面这条输出语句中:
std::cout << "count == " << i << std::endl;
输出 "count == " 和 i 这两个动作不是原子性的(atomic),可能被其他线程打断。
#include <iostream>
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/lock_guard.hpp>
boost::mutex mutex;
boost::mutex io_mutex;
int count = 0;
void Counter() {
int i;
{
boost::unique_lock<boost::mutex> lock(mutex);
i = ++count;
}
{
boost::unique_lock<boost::mutex> lock(io_mutex);
std::cout << "count == " << i << std::endl;
}
}
int main() {
boost::thread_group threads;
for (int i = 0; i < 4; ++i) {
threads.create_thread(&Counter);
}
threads.join_all();
return 0;
}编译使用g++ -std=c++11 -o main 2.cpp -lboost_system -lboost_thread