c++的mutex的库函数还是比较好用的,介绍两种加锁方式,自动的和手动的。
1 自动锁
名字叫做自动锁,但是还是要注意一下加锁位置的,不然线程不知道什么时候解锁,会导致死锁
一般来说我们都会有个信号量来作为标记,每次运行临界区代码之前先看看信号量。
检测信号量一般使用忙等待的方式检测。
大致代码形式如下:
void f()
{
//错误加锁位置
//如何把锁加到这里,那么整个while循环锁都会是锁着的,并且while循环不会结束,锁也就不开,导致死锁
while (1)
{
//正确加锁位置
//把锁加到这个地方,每次进入while循环的代码段时,锁会锁上,
//while循环的代码段经过一个循环结束时,锁会打开,这样就不会死锁了
if (signal)
{
'''
临界区
'''
}
}
}正确样例:
// thread2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <thread>
#include <list>
#include <algorithm>
#include <mutex>
using namespace std;
// a global variable
int flag = 0;
// a global instance of std::mutex to protect global variable
std::mutex myMutex;
void a()
{
int n = 3;
while(n)
{
std::lock_guard<std::mutex> guard(myMutex);
if (flag == 0)
{
cout << "0 is " << flag << endl;
flag = 1;
n--;
}
}
}
void b()
{
int n = 3;
while (n)
{
std::lock_guard<std::mutex> guard(myMutex);
if (flag == 1)
{
cout << "1 is " << flag << endl;
flag = 0;
n--;
}
}
}
int main()
{
std::thread t1(a);
std::thread t2(b);
t1.join();
t2.join();
return 0;
}2 手动锁,如果逻辑比较复杂,想自己设计加锁开锁的时间,那么可以用手动锁
这个就是自己加了。
样例代码:
// thread2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <thread>
#include <list>
#include <algorithm>
#include <mutex>
using namespace std;
// a global variable
int flag = 0;
// a global instance of std::mutex to protect global variable
std::mutex myMutex;
void c()
{
int n = 3;
while (n)
{
if (flag == 0 && myMutex.try_lock())
{
cout << "0 is " << flag << endl;
flag = 1;
n--;
myMutex.unlock();
}
}
}
void d()
{
int n = 3;
while (n)
{
if (flag == 1 && myMutex.try_lock())
{
cout << "1 is " << flag << endl;
flag = 0;
n--;
myMutex.unlock();
}
}
}
int main()
{
std::thread t1(c);
std::thread t2(d);
t1.join();
t2.join();
return 0;
}


京公网安备 11010502036488号