千家信息网

c++互斥量mutex和锁的应用

发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,本篇内容介绍了"c++互斥量mutex和锁的应用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!多线程
千家信息网最后更新 2025年12月02日c++互斥量mutex和锁的应用

本篇内容介绍了"c++互斥量mutex和锁的应用"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

多线程中,多个线程对共享的数据进行访问,应该是最常见的应用。

如果多个线程都只是对共享数据进行读操作,还不会有问题,但是如果有的线程读数据,有的线程写数据,这时候就会出现问题。比如A线程写数据,但是写的这个过程进行到一半,B线程就去读,这个时候程序就会崩溃。这个时候就需要互斥量的出场啦!

mutex:
mutex互斥量是一个类,这个类有有一个lock()方法,和一个unlock()方法。如果第一次运行了lock()这个方法,而没有运行unlock()这个方法,第二次再运行lock()这个方法时,程序就会卡停在这里,只有当运行了unlock()这个方法运行后,第二个lock()方法才会运行通过。就是运用这种"锁"的机制就可以保证两段代码独立运行。

例子:

#include  #include  #include  #include    class A { public:     void WriteFunction()     {         for (int i = 0; i < 1000; ++i)         {                          std::cout << "向队列中添加一个元素" << std::endl;             my_deque.push_back(i);                      }     }     void ReadFunction()     {         for (int i = 0; i < 1000; ++i)         {                          if(!my_deque.empty())             {                 std::cout << "读出队列的第一个元素: " << my_deque.front() << std::endl;                 my_deque.pop_front();             }                      }     } private:     std::deque my_deque;        }; int main() {     A a;     std::thread my_thread_1(&A::WriteFunction, std::ref(a));       std::thread my_thread_2(&A::ReadFunction, std::ref(a));       my_thread_1.join();     my_thread_2.join();     std::cout << "Hello World!\n"; }



上面这段代码运行时,会出现错误的。原因就是上面提到的:读写可能会同时操作,出现错误。

修改的代码:

#include  #include  #include  #include    class A { public:     void WriteFunction()     {         for (int i = 0; i < 1000; ++i)         {             my_mutex_1.lock();             std::cout << "向队列中添加一个元素" << std::endl;             my_deque.push_back(i);             my_mutex_1.unlock();         }     }     void ReadFunction()     {         for (int i = 0; i < 1000; ++i)         {             my_mutex_1.lock();             if(!my_deque.empty())             {                 std::cout << "读出队列的第一个元素: " << my_deque.front() << std::endl;                 my_deque.pop_front();             }             my_mutex_1.unlock();         }     } private:     std::deque my_deque;     std::mutex my_mutex_1;   }; int main() {     A a;     std::thread my_thread_1(&A::WriteFunction, std::ref(a));       std::thread my_thread_2(&A::ReadFunction, std::ref(a));       my_thread_1.join();     my_thread_2.join();     std::cout << "Hello World!\n"; }



上面这段代码,我们运用了互斥量和锁的方法,解决了上面的问题。

注意事项:
lock()和unlock()必须同时成对出现,不可以多写,也不可以少写,要不认会出现不知名的错误。

std::lock_guard()
这是一个类模板,具体的用法可以看下面的代码。

这个类模板的作用就是替代lock()和unlock()。lock()和unlock()必须同时出现,而std::lock_guard() 只需要出现一个就行。

先来看代码:

#include  #include  #include  #include    class A { public:     void WriteFunction()     {         for (int i = 0; i < 1000; ++i)         {             std::lock_guard my_lock_guard(my_mutex_1);             std::cout << "向队列中添加一个元素" << std::endl;             my_deque.push_back(i);         }     }     void ReadFunction()     {         for (int i = 0; i < 1000; ++i)         {             {//其实这个大括号不用写,因为这里恰巧有for循环的大括号                 std::lock_guard my_lock_guard(my_mutex_1);                 if (!my_deque.empty())                 {                     std::cout << "读出队列的第一个元素: " << my_deque.front() << std::endl;                     my_deque.pop_front();                 }               }                      }     } private:     std::deque my_deque;     std::mutex my_mutex_1;   }; int main() {     A a;     std::thread my_thread_1(&A::WriteFunction, std::ref(a));       std::thread my_thread_2(&A::ReadFunction, std::ref(a));       my_thread_1.join();     my_thread_2.join();     std::cout << "Hello World!\n"; }

上面的代码我们用std::lock_guard my_lock_guard(my_mutex_1);这句代码代替了lock()和unlock().

我一般这样使用:将需要保护的代码段用一个大括号括起来,然后在大括号括起来的代码的第一句定义std::lock_guard()。

这样做的原理:std::lock_guard my_lock_guard(my_mutex_1);我们定义的std::lock_guard()对象只在这个大括号的作用域内有效。当进入这个作用域时,我们会构造std::lock_guard()对象,在std::lock_guard()的构造函数中其实是执行了lock()这个方法,当退出这个作用域的时候,std::lock_guard()对象将会被析构,而在std::lock_guard()的析构函数中实际是调用了unlock()。这样的操作十分巧妙。

"c++互斥量mutex和锁的应用"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0