std::lock_guard 简单用法
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int g_count = 0;
mutex g_mutex;
void increment()
{
lock_guard<mutex> lock(g_mutex); // 开启后g_count总是可以输出20000,否则会少于20000
++g_count;
this_thread::sleep_for(chrono::microseconds(2));
}
void run(int times)
{
for (int i = 0; i < times; i++)
{
increment();
}
}
int main()
{
thread th1(run, 10000);
thread th2(run, 10000);
th1.join();
th2.join();
cout << g_count;
return 0;
}
直接使用lock容易不对称导致死锁
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int g_count = 0;
mutex g_mutex;
int increment1()
{
g_mutex.lock();
this_thread::sleep_for(chrono::microseconds(1));
g_count++;
g_mutex.unlock();
return 0;
}
int increment2()
{
g_mutex.lock();
this_thread::sleep_for(chrono::microseconds(1));
if (g_count > 11000)
{
return 0;
}
g_count++;
g_mutex.unlock();
return 0;
}
void run1(int times)
{
for (int i = 0; i < times; i++)
{
increment1();
}
}
void run2(int times)
{
for (int i = 0; i < times; i++)
{
increment2();
}
}
int main()
{
thread th1(run1, 10000);
thread th2(run2, 10000);
th1.join();
th2.join();
cout << g_count;
return 0;
}
使用lock_guard避免死锁
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
int g_count = 0;
mutex g_mutex;
int increment1()
{
lock_guard<mutex> lock(g_mutex);
this_thread::sleep_for(chrono::microseconds(1));
g_count++;
return 0;
}
int increment2()
{
lock_guard<mutex> lock(g_mutex);
this_thread::sleep_for(chrono::microseconds(1));
g_count++;
if (g_count > 11000)
{
return 0;
}
return 0;
}
void run1(int times)
{
for (int i = 0; i < times; i++)
{
increment1();
}
}
void run2(int times)
{
for (int i = 0; i < times; i++)
{
increment2();
}
}
int main()
{
thread th1(run1, 10000);
thread th2(run2, 10000);
th1.join();
th2.join();
cout << g_count;
return 0;
}
防止list下标越界,同样适用于map,set,vector等
#include <iostream>
#include <thread>
#include <mutex>
#include <list>
using namespace std;
class MonitorList
{
private:
mutex g_mutex;
list<int> g_list = {};
public:
void push()
{
lock_guard<mutex> lock(g_mutex); // 不加会导致程序异常
this_thread::sleep_for(chrono::microseconds(1));
g_list.push_back(0);
}
void pop()
{
lock_guard<mutex> lock(g_mutex); // 不加会导致程序异常
this_thread::sleep_for(chrono::microseconds(1));
for (auto it = g_list.begin(); it != g_list.end(); ++it)
{
if (*it % 2 == 0)
{
it = g_list.erase(it);
}
}
}
int size()
{
return g_list.size();
}
};
MonitorList g_MonitorList;
int main()
{
thread th1([](int n)
{
for (int i = 0; i < n; i++)
{
g_MonitorList.push();
}
},
10000);
thread th2([](int n)
{
for (int i = 0; i < n; i++)
{
g_MonitorList.pop();
}
},
3000);
thread th3([](int n)
{
for (int i = 0; i < n; i++)
{
g_MonitorList.pop();
}
},
3000);
th1.join();
th2.join();
th3.join();
cout << g_MonitorList.size() << endl;
return 0;
}