#include #include #include #include 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 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 lock(mtx); res = res - 1; } }); t1.join(); t2.join(); std::cout << "test2:: res:: " << res << " lock_guard::" << sizeof(lock_guard) << " unique_lock::" << sizeof(unique_lock) << endl; } void test3() { mutex mtx; int res = 0; int error_count = 0; queue mq; thread t1([&]() { for (int i = 0; i < LOOP_TIMES; i++) { this_thread::sleep_for(chrono::milliseconds(i)); lock_guard 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 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; }