欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > C++中锁的使用

C++中锁的使用

2025/9/24 21:26:38 来源:https://blog.csdn.net/weixin_45778713/article/details/144424503  浏览:    关键词:C++中锁的使用

        多线程环境下使用竞态资源时要使用锁来保证线程安全的实现。锁的实现有三种,互斥锁,自旋锁和原子管理,

        互斥锁的原理是当线程A加锁后,线程B尝试加锁发现被占用,线程B由唤醒状态切换为睡眠状态,当线程A解锁后,会通知内核,内核再通知线程B,线程B再由睡眠状态切换为唤醒状态。

        互斥锁代码如下:

#include <iostream>
#include <mutex>
#include <memory>
#include <thread>class testClass {
public:void showNum(){std::lock_guard<std::mutex> lock(_mutex);std::cout << "当前数字是" << num << std::endl;}void NumIncrease(){std::lock_guard<std::mutex> lock(_mutex);num++;}private:int num = 0;std::mutex _mutex;
};void increaseNum(std::shared_ptr<testClass> test)
{for (int i = 0; i < 1000; i++){test->NumIncrease();}test->showNum();
}int main()
{std::shared_ptr<testClass> test = std::make_shared<testClass>();std::thread t0(increaseNum, test);std::thread t1(&increaseNum, test);std::thread t2(&increaseNum, test);std::thread t3(&increaseNum, test);std::thread t4(&increaseNum, test);std::thread t5(&increaseNum, test);std::thread t6(&increaseNum, test);std::thread t7(&increaseNum, test);std::thread t8(&increaseNum, test);std::thread t9(&increaseNum, test);t0.join();t1.join();t2.join();t3.join();t4.join();t5.join();t6.join();t7.join();t8.join();t9.join();return 0;
}

程序输出如下:

 

注释掉锁之后

程序输出如下

下面介绍自旋锁:自旋锁没有直接调用的库,需要使用atomic手动实现

        自旋锁代码如下:

#include <iostream>
#include <mutex>
#include <memory>
#include <thread>
#include <atomic>//自旋锁类class Spinlock {
public:// 尝试获取锁void lock() {// 使用原子操作来设置锁标志,如果失败则自旋等待while (lock_flag.test_and_set(std::memory_order_acquire)) {}// 锁已被当前线程获取}// 释放锁void unlock() {lock_flag.clear(std::memory_order_release);}private:std::atomic_flag lock_flag = ATOMIC_FLAG_INIT;		//原子标志表示锁
};class testClass {
public:void showNum(){std::lock_guard<Spinlock> lock(_mutex);std::cout << "当前数字是" << num << std::endl;}void NumIncrease(){std::lock_guard<Spinlock> lock(_mutex);num++;}private:int num = 0;Spinlock _mutex;
};void increaseNum(std::shared_ptr<testClass> test)
{for (int i = 0; i < 1000; i++){test->NumIncrease();}test->showNum();
}int main()
{std::shared_ptr<testClass> test = std::make_shared<testClass>();std::thread t0(increaseNum, test);std::thread t1(&increaseNum, test);std::thread t2(&increaseNum, test);std::thread t3(&increaseNum, test);std::thread t4(&increaseNum, test);std::thread t5(&increaseNum, test);std::thread t6(&increaseNum, test);std::thread t7(&increaseNum, test);std::thread t8(&increaseNum, test);std::thread t9(&increaseNum, test);t0.join();t1.join();t2.join();t3.join();t4.join();t5.join();t6.join();t7.join();t8.join();t9.join();return 0;
}

输出如下:

        

输出结果表明可以实现锁的功能,具体实现通过原子变量atomitic实现,代码中的std::memory_order_acquire功能理解的时候参考了下面UP主的视频。通俗来说就是保证汇编时编译器优化打乱的顺序,再标记点之后线程安全。

【量子速读 C++ Concurrency in Action 第五章 Memory Order】 https://www.bilibili.com/video/BV1br4y197in/

        

递归锁(可重入锁)代码如下:

//定义一个递归锁,在函数中使用递归锁保证线程安全,创建多个线程调用函数。#include <iostream>
#include <thread>
#include <mutex>
#include <vector>//定义一个递归锁
std::recursive_mutex recursiveMutex;
//std::mutex _mutex;void recursiveFunction(int count)
{std::lock_guard<std::recursive_mutex> lock(recursiveMutex);//std::lock_guard<std::mutex> lock(_mutex);std::cout << "当前线程是" << std::this_thread::get_id() << ",计数是" << count << std::endl;if (count > 0){//递归调用自身recursiveFunction(count-1);}
}int main()
{int thread_num = 5;int count = 6;//创建线程向量std::vector<std::thread> threadVec;for (int i = 0; i < thread_num; i++){threadVec.emplace_back(recursiveFunction, count);}for (auto& it : threadVec){it.join();}return 0;
}

程序输出如下

代码中将递归锁改为互斥锁后,作为对比

程序输出如下

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词