C++多线程基础学习笔记(五)

一、互斥量

1.1 互斥量的基本概念

简单来说,一个锁就是一个互斥量,既然是锁,就有两种状态:加锁和解锁,通过加锁>>>操作共享数据>>>解锁的方式,实现保护共享数据。

1.2 互斥量的用法

作用:在给某段代码加锁后,如果其他其他线程需要先等带该段代码执行完,然后解锁后才能继续执行。

头文件 :#include <mutex>

成员函数:lock()   //加锁,unlock()  //解锁

注意点:lock()与unlock()的使用必须成对存在。

 1 #include <iostream>
 2 #include <mutex>
 3 using namespace std;
 4 int num = 0;
 5 mutex my_mutex;         //创建一个互斥量
 6 void print1()
 7 {
 8     for (int i = 0; i < 50; i++)
 9     {
10         my_mutex.lock();
11         cout << "thread_1:" << num++ << endl;
12         my_mutex.unlock();
13     }
14 }
15 void print2()
16 {
17     for (int i = 0; i < 50; i++)
18     {
19         my_mutex.lock();
20         cout << "thread_2:" << num++ << endl;
21         my_mutex.unlock();
22     }
23 }
24 
25 int main()
26 {
27     thread thread_1(print1);      //打印0-49
28     thread thread_2(print2);      //打印49-99
29     thread_1.join();
30     thread_2.join();
31     system("pause");
32     return 0;
33 }

还有一种方法,可实现加锁和解锁两个步骤,即用std::lock_guard<mutex> myguard (my_mutex)来代替lock()和unlock(),其原理是,在std::lock_guard构造函数里执行了lock(),在析构函数里执行了unlock()。

 1 #include <iostream>
 2 #include <mutex>
 3 using namespace std;
 4 int num = 0;
 5 mutex my_mutex;
 6 void print1()
 7 {
 8     for (int i = 0; i < 50; i++)
 9     {
10         lock_guard<mutex> myguard(my_mutex);
11         cout << "thread_1:" << num++ << endl;
12     }
13 }
14 void print2()
15 {
16     for (int i = 0; i < 50; i++)
17     {
18         lock_guard<mutex> myguard(my_mutex);
19         cout << "thread_2:" << num++ << endl;
20     }
21 }
22 
23 int main()
24 {
25     thread thread_1(print1);      //打印0-49
26     thread thread_2(print2);      //打印49-99
27     thread_1.join();
28     thread_2.join();
29     system("pause");
30     return 0;
31 }

二、死锁

仅在存在两个互斥量以上才会出现死锁的现象。通俗来讲,就是我在等你解锁我才能解锁,你在等我解锁你才能解锁。

 1 #include <iostream>
 2 #include <mutex>
 3 using namespace std;
 4 int num = 0;
 5 mutex my_mutex1;    
 6 mutex my_mutex2;
 7 void print1()
 8 {
 9     for (int i = 0; i < 500; i++)
10     {
11         my_mutex1.lock();
12         /*这里同通常有一段代码,也是用来操作共享数据*/
13         my_mutex2.lock();
14         cout << "thread_1:" << num++ << endl;
15         my_mutex1.unlock();
16         my_mutex2.unlock();
17     }
18 }
19 void print2()
20 {
21     for (int i = 0; i < 500; i++)
22     {
23         my_mutex2.lock();
24         my_mutex1.lock();
25         cout << "thread_2:" << num++ << endl;
26         my_mutex1.unlock();
27         my_mutex2.unlock();
28     }
29 }
30 
31 int main()
32 {
33     thread thread_1(print1);      //打印0-49
34     thread thread_2(print2);      //打印49-99
35     thread_1.join();
36     thread_2.join();
37     system("pause");
38     return 0;
39 }

运行结果发现也不会出现任何奔溃出错现象,但是就一直卡在那里,不会继续运行下去了。

解决死锁的方法其实也很简单,只要保证互斥量加锁的顺序一致就可以了。或者使用std::lock(mutex1,mutex2),意思是给这两个互斥量同时上锁。

猜你喜欢

转载自www.cnblogs.com/main404/p/11221104.html