mutex就是互斥量的意思,在c++中使用互斥量需要包含#include
当多个线程同时范围统一个资源的的时候,就会造成线程的不安全情况。
但线程t1,t2同时操作整形globaVariableInt时,正常情况globaVariableInt++再–,理应输入的是0,当这时候我们可以看到打印的不是0,而且是1083。
#include
#include
#include
#include //1、添加互斥量头文件
using namespace std;
int globaVariableInt = 0;
void task1() {
for (int i = 0; i < 1000000; i++)
{
mtx1.lock();//3、上锁操作,避免其他线程访问代码
globaVariableInt++;
globaVariableInt--;
mtx1.unlock();//4、执行完代码,解锁操作
}
}
int main()
{
std::thread t1(task1);
std::thread t2(task1);
t1.join();
t2.join();
std::cout << "当前globaVariableInt值为" << globaVariableInt << endl;
return 0;
}
这个时候,我们就可以使用互斥量(mute)来抱住线程安全。
这个适合,我们给操作内容上添加上锁lock()和解锁unlock()。
std::mutex mtx1;//2、创建一个全局的互斥量
void task1() {
for (int i = 0; i < 1000000; i++)
{
mtx1.lock();//3、上锁操作,避免其他线程访问代码
globaVariableInt++;
globaVariableInt--;
mtx1.unlock();//4、执行完代码,解锁操作
}
}
在实际使用过程中,我们可能会因为忘记解锁的操作,就会造成死锁。所以在创建互斥量(mute)后,推荐使用 std::lock_guard()与std::unique_lock();
void task2() {
for (int i = 0; i < 1000000; i++)
{
//避免忘记解锁,可以使用lock_guard unique_lock
std::lock_guard<mutex> lock1(mtx1);
globaVariableInt++;
globaVariableInt--;
//生命周期结束后,自动解锁。
}
}
void task2() {
for (int i = 0; i < 1000000; i++)
{
//避免忘记解锁,可以使用lock_guard unique_lock
//std::lock_guard lock1(mtx1);
std::unique_lock<std::mutex> lock2(mtx2);
lock2.unlock();//相比lock_guard更加灵活,可以在作用域内手动解锁
globaVariableInt++;
globaVariableInt--;
}
}
#include
#include
#include
#include
#include //1、引用原子类型
using namespace std;
//2、定义一个原子类型
std::atomic<int> globaVariableInt2 = 0;
//定义一个原子类型,不用上锁的方式,
void task4() {
for (int i = 0; i < 1000000; i++)
{
globaVariableInt2++;
globaVariableInt2--;
}
}
int main()
{
/*std::thread t1(task1);
std::thread t2(task1);*/
std::thread t1(task4);
std::thread t2(task4);
t1.join();
t2.join();
std::cout << "当前globaVariableInt2值为" << globaVariableInt2 << endl;
return 0;
}