103 lines
2.5 KiB
C++
103 lines
2.5 KiB
C++
#include <thread>
|
||
#include <mutex>
|
||
#include <queue>
|
||
#include <iostream>
|
||
using namespace std;
|
||
#define LOOP_TIMES 100
|
||
void test1() {
|
||
mutex mtx;
|
||
int res = 0;
|
||
thread t1([&]() {
|
||
for (int i = 0; i < LOOP_TIMES;i++) {
|
||
this_thread::sleep_for(chrono::milliseconds(1));
|
||
res = res + 1;
|
||
}
|
||
});
|
||
thread t2([&]() {
|
||
for (int i = 0; i < LOOP_TIMES; i++) {
|
||
this_thread::sleep_for(chrono::milliseconds(1));
|
||
mtx.lock();
|
||
res = res - 1;
|
||
mtx.unlock();
|
||
}
|
||
});
|
||
t1.join();
|
||
t2.join();
|
||
std::cout << "test1:: res:: " << res << " mutexsize::" << sizeof(mutex) << endl;
|
||
}
|
||
void test2() {
|
||
recursive_mutex mtx;
|
||
int res = 0;
|
||
thread t1([&]() {
|
||
for (int i = 0; i < LOOP_TIMES / 10; i++) {
|
||
this_thread::sleep_for(chrono::milliseconds(i));
|
||
lock_guard<recursive_mutex> lock(mtx);
|
||
res = res + 1;
|
||
}
|
||
});
|
||
thread t2([&]() {
|
||
for (int i = 0; i < LOOP_TIMES / 10; i++) {
|
||
this_thread::sleep_for(chrono::milliseconds(i));
|
||
unique_lock<recursive_mutex> lock(mtx);
|
||
res = res - 1;
|
||
}
|
||
});
|
||
t1.join();
|
||
t2.join();
|
||
std::cout << "test2:: res:: " << res << " lock_guard::" << sizeof(lock_guard<mutex>)
|
||
<< " unique_lock::" << sizeof(unique_lock<mutex>) << endl;
|
||
}
|
||
void test3() {
|
||
mutex mtx;
|
||
int res = 0;
|
||
int error_count = 0;
|
||
queue<int> mq;
|
||
thread t1([&]() {
|
||
for (int i = 0; i < LOOP_TIMES; i++) {
|
||
this_thread::sleep_for(chrono::milliseconds(i));
|
||
lock_guard<mutex> lock(mtx);
|
||
mq.push(i / 2);
|
||
res = res + 1;
|
||
}
|
||
});
|
||
thread t2([&]() {
|
||
int a = 0;
|
||
for (int i = 0; i < LOOP_TIMES;) {
|
||
this_thread::sleep_for(chrono::milliseconds(a));
|
||
unique_lock<mutex> lock(mtx);
|
||
if (mq.empty()) {
|
||
error_count++;
|
||
continue;
|
||
}
|
||
i++;
|
||
a = mq.front();
|
||
mq.pop();
|
||
res = res - 1;
|
||
}
|
||
});
|
||
t1.join();
|
||
t2.join();
|
||
std::cout << "test3:: res:: " << res << " error_count::" << error_count << endl;
|
||
}
|
||
int main() {
|
||
/*
|
||
进程是房子,线程是住在房子里的人,厕所、厨房...是房子里的共享资源。
|
||
*/
|
||
test1();
|
||
test2();
|
||
/*
|
||
mutex 原子性 排队性
|
||
//保证资源的正确使用,如一个厕所只能一个人用
|
||
//递归锁可以让前面的人重复上锁,避免函数递归时解锁出错
|
||
//排队等待前一个人离开,才能使用
|
||
//超时锁,可以先进入自旋,超时后阻塞
|
||
*/
|
||
test3();
|
||
/*
|
||
锁 如果存在单向依赖,无法保证资源是否存在,会空转CPU
|
||
生产者知道什么时候有资源,消费者知道什么时候没有资源
|
||
消费者上锁等待,生产者解锁通知, 锁只能自己锁自己解锁
|
||
*/
|
||
|
||
return 0;
|
||
} |