• 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 }

    二、死锁

    仅在存在两个互斥量以上才会出现死锁的现象。例如线程A获得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线程A和B都永远处于挂起状态了。通俗来讲,就是我在等你解锁我才能解锁,你在等我解锁你才能解锁。

     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),意思是给这两个互斥量同时上锁。

  • 相关阅读:
    集合类提供的的方法
    集合相关常识
    day12练习题
    Django(重点)
    cookie和session
    admin的配置
    Django安装和配置环境变量
    django ORM创建数据库方法
    前端学习之jquery
    数据库基础
  • 原文地址:https://www.cnblogs.com/main404/p/11221104.html
Copyright © 2020-2023  润新知