互斥量是一个类,互斥量的使用必须引入头文件#include <mutex>
。互斥量就如同一把锁,在同一时间,多个线程都可以调用lock成员函数尝试给这把锁头加锁,但是只有一个线程可以成功给这把锁加锁,其他没有加锁成功的线程的执行流程就会卡在lock语句行这里不断地尝试去加锁,一直到加锁成功,执行流程才会继续走下去。
互斥量的使用:
#include <mutex>
#include <iostream>
#include <thread>
using namespace std;
mutex my_mutex; // 这是一个互斥量,锁头
int sum = 0; // 这是需要保护的变量
void test() {
cout << "test is exceuteing by thread id:" << this_thread::get_id() << endl;
my_mutex.lock(); // 加锁,确保在同一时刻只有一个线程在修改sum变量,没有加锁成功的线程就会卡在这里,不断尝试去解锁,直到解锁成功,然后再继续执行下去。
cout << "exeuteing by "<< this_thread::get_id() << endl;
sum += 1;
my_mutex.unlock(); // 解锁,对sum变量操作完成后,就解锁,让其他线程可以调用lock函数加锁。
cout << "exection is done by" << this_thread::get_id() << endl;
}
int main(){
cout << "Main thread id: " << this_thread::get_id() << endl;
test();
thread th1(test);
thread th2(test);
thread th3(test);
thread th4(test);
thread th5(test);
th1.join();
th2.join();
th3.join();
th4.join();
th5.join();
cout << "sum is " << sum << endl;
return 0;
}
sum变量是我们想要保护的对象,因为多个线程对sum进行加1时,如果在同一时刻,多个线程同时修改sum变量,那么最终得到的累加结果就有可能是错的。因此会我们可以对sum的操作进行加锁保护,让在同一时刻只有一个线程在操作累加的动作。
锁的范围不宜过大,过大会降低程序的运行性能。当然太小也不行,这可能会导致不能够切实保护到我们想保护的代码块。在lock 与unlock之间的代码块都会受到这把锁的保护。
另外使用锁机制来解决线程之间的协作问题时,一定要小心,避免出现死锁。上面的例子中使用一把锁还是比较简单,当多把锁一起使用时,就可能会因为思考不周导致死锁出现。
关于锁的更多使用可以翻阅lock_guard,unique_lock使用。