网站开发管理制度,网站没被收录,网络搭建结构图,平面设计接单话术今天在评审代码的时候#xff0c;因为位于两个不同的线程中#xff08;一个是周期性事件线程#xff0c;一个是触发式事件线程#xff09;#xff0c;需要对一个资源类的某些属性进行互斥的访问#xff0c;因此采用lock_guard互斥量包装器#xff0c;但是在升级的过程中… 今天在评审代码的时候因为位于两个不同的线程中一个是周期性事件线程一个是触发式事件线程需要对一个资源类的某些属性进行互斥的访问因此采用lock_guard互斥量包装器但是在升级的过程中因为整个系统太大所以在询问了某位同事后得到的答案是在两个不同的地方加上lock_guard有一定的可能性会导致死锁但是后面在测试的过程中又没有问题真的如此吗本文针对lock_guard来做阐述和延申 历史原因为什么要使用lock_gurad有什么优点
传统的C对互斥量加锁是用互斥量本身的锁的即
#include mutexstd::mutex g_mutex;// 加锁
g_mutex.lock();
// 解锁
g_mutex.unlock();此时会有两个不便利处即要手动的解锁如果忘了解锁那就完蛋了因此采用lock_guard
#include mutexstd::mutex g_mutex;{ // 作用域开始std::lock_guardstd::mutex lock(g_mutex);
} // 作用域结束lock_guard以作用域为加解锁单位退出当前作用域自动解锁不必手动解锁。总结一下它的优点
RAII资源获取即初始化语法std::lock_guard 使用对象的构造函数和析构函数来自动管理互斥量的锁定和解锁从而避免了手动管理锁的复杂性。这种自动化的资源管理方式确保在作用域结束时释放锁防止忘记解锁而导致的资源泄漏或死锁异常安全由于 std::lock_guard 使用RAII语法即使在作用域内发生异常也会自动调用析构函数释放锁确保了异常安全性。这样可以避免在异常发生时锁没有被释放而导致的资源泄漏或死锁简单易用std::lock_guard 提供了一种简单而直观的方式来管理互斥量不需要手动调用 lock() 和 unlock() 函数因此代码更加简洁清晰易于理解和维护避免死锁由于 std::lock_guard 在构造时立即锁定互斥量在析构时立即释放互斥量因此减少了出现死锁的可能性。通过使用 std::lock_guard程序员可以更容易地确保正确的加锁和解锁顺序从而避免死锁线程安全性std::lock_guard 是线程安全的可以在多线程环境下安全地使用。它能够确保在同一时间只有一个线程可以访问被互斥量保护的资源从而保证了线程安全性
lock_guard和unique_lock的区别
延迟加锁可以在构造时不立即锁定互斥量在需要时手动调用 lock() 函数来锁定互斥量。这种延迟加锁的特性允许在一段代码中多次锁定和解锁互斥量提供了更多的灵活性
void FunThread()
{std::unique_lockstd::mutex lock(mtx, std::defer_lock); // 延迟加锁此时不加锁lock.lock(); // 加锁//lock.unlock(); // 解锁
}条件等待提供了与条件变量一起使用的功能可以在条件变量的等待和通知过程中自动锁定和解锁互斥量。通过将 std::unique_lock 对象传递给条件变量的wait()和 notify_*() 函数可以轻松实现条件等待的功能
配合条件变量使用的时候必须使用unique_lock因此lock_guard不会自动释放锁试想在wait之前本线程已经持有锁了在等待的时候如果一直持有互斥量那其他线程也会拿不到互斥量执行不了逻辑则会导致永久死锁可见源码 template class _Lock, class _Predicatebool wait(_Lock __lock,stop_token __stoken,_Predicate __p){if (__stoken.stop_requested()){return __p();}std::stop_callback __cb(__stoken, [this] { notify_all(); });shared_ptrmutex __mutex _M_mutex;while (!__p()){unique_lockmutex __my_lock(*__mutex);if (__stoken.stop_requested()){return false;}// *__mutex must be unlocked before re-locking __lock so move// ownership of *__mutex lock to an object with shorter lifetime._Unlock_Lock __unlock(__lock); // 先解锁unique_lockmutex __my_lock2(std::move(__my_lock));_M_cond.wait(__my_lock2);}return true;}{std::unique_lockstd::mutex lock(g_mutex);g_condition.wait(lock, [] { // condition }); // 等待队列不为空的才去获得锁
}所有权转移支持所有权转移允许将互斥量的所有权从一个std::unique_lock对象转移到另一个对象。这使得在一段代码中传递互斥量的所有权变得更加方便
void Fun2(std::unique_lockstd::mutex lock)
{// 手动解锁锁lock.unlock();
}
void Fun1()
{std::unique_lockstd::mutex lock(mtx);std::thread F(Fun2, std::move(lock));
}性能损失与 std::lock_guard 相比std::unique_lock 有一些性能损失因为它需要更多的控制和管理互斥量的状态包括手动加锁、解锁和条件等待。但是这种性能损失通常是微不足道的并且可以通过使用std::defer_lock 参数来避免 还有一个scope_lock在此不做介绍 lock_guard小demo读写队列
/** Author: LiuHao* Date: 2024-03-24 01:40:15* Description: 测试C的互斥量包装器*/#include thread
#include mutex
#include iostream
#include deque
#include vector
#include condition_variablestd::mutex g_mutex; // 互斥量
std::dequeuint8_t g_deque; // 双端队列
std::condition_variable g_condition; // 条件变量namespace LHSpace { // 解决cout不能直接输出uint8_t的值的问题class LHCout {public:template typename Ttypename std::enable_ifstd::is_sameT, uint8_t::value, LHCout::type operator(const T num){std::cout static_castint(num);return *this;}LHCout operator(std::ostream (*manipulator)(std::ostream)){std::cout manipulator;return *this;}};
}demo组成
十个写线程一个循环读线程
写线程函数
void SetPrint(const uint8_t val)
{LHSpace::LHCout lhCout;{std::lock_guardstd::mutex lock(g_mutex);std::cout Write Thread ID: std::this_thread::get_id() std::endl;g_deque.push_back(val); // 末尾添加一个元素std::cout deque push: ;lhCout val std::endl;}g_condition.notify_one(); // 使用条件变量std::this_thread::sleep_for(std::chrono::seconds(1));
}读线程函数
void GetPrint()
{LHSpace::LHCout lhCout;while (true) { // 每一次退出作用域就丢掉锁std::unique_lockstd::mutex lock(g_mutex);g_condition.wait(lock, [] { return !g_deque.empty(); }); // 等待队列不为空的才去获得锁const uint8_t FRONTNUM g_deque.front();g_deque.pop_front();lock.unlock();std::cout Read Thread ID: std::this_thread::get_id() std::endl;std::cout deque pop: ;lhCout FRONTNUM std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(500));}
}创建并启动线程
int main(int argc, const char** argv)
{LHSpace::LHCout lhCout;std::vectorstd::thread writeThreads;for (uint8_t i 0U; i 10U; i) {writeThreads.push_back(std::thread(SetPrint, i)); // 读线程}std::thread getThread(GetPrint); // 读线程for (uint8_t i 0U; i 10U; i) {writeThreads[i].join();}getThread.join();return 0;
}来看看具体运行过程感受一下多线程的魅力
ubuntuVM-8-16-ubuntu:~/tmp$ ./a.out
Write Thread ID: 140363031643712
deque push: 2 # 写
Write Thread ID: 140363023251008
deque push: 3 # 写
Read Thread ID: 140362964502080
deque pop: 2 # 读
Write Thread ID: 140363040036416
deque push: 1 # 写
Write Thread ID: 140363048429120
deque push: 0 # 写
Write Thread ID: 140363014858304
deque push: 4 # 写
Read Thread ID: 140362964502080
deque pop: 3 # 读
# ...
文章转载自: http://www.morning.xxfxxf.cn.gov.cn.xxfxxf.cn http://www.morning.gxtfk.cn.gov.cn.gxtfk.cn http://www.morning.rlbc.cn.gov.cn.rlbc.cn http://www.morning.wmfr.cn.gov.cn.wmfr.cn http://www.morning.wqbbc.cn.gov.cn.wqbbc.cn http://www.morning.pzbjy.cn.gov.cn.pzbjy.cn http://www.morning.xkjqg.cn.gov.cn.xkjqg.cn http://www.morning.fpzpb.cn.gov.cn.fpzpb.cn http://www.morning.lwjlj.cn.gov.cn.lwjlj.cn http://www.morning.myfwb.cn.gov.cn.myfwb.cn http://www.morning.qbjgw.cn.gov.cn.qbjgw.cn http://www.morning.mtxrq.cn.gov.cn.mtxrq.cn http://www.morning.kpxnz.cn.gov.cn.kpxnz.cn http://www.morning.cczrw.cn.gov.cn.cczrw.cn http://www.morning.trplf.cn.gov.cn.trplf.cn http://www.morning.paxkhqq.cn.gov.cn.paxkhqq.cn http://www.morning.jsmyw.cn.gov.cn.jsmyw.cn http://www.morning.kltsn.cn.gov.cn.kltsn.cn http://www.morning.qzmnr.cn.gov.cn.qzmnr.cn http://www.morning.lhptg.cn.gov.cn.lhptg.cn http://www.morning.xqcbz.cn.gov.cn.xqcbz.cn http://www.morning.cfjyr.cn.gov.cn.cfjyr.cn http://www.morning.pycpt.cn.gov.cn.pycpt.cn http://www.morning.pqryw.cn.gov.cn.pqryw.cn http://www.morning.mnwsy.cn.gov.cn.mnwsy.cn http://www.morning.phgz.cn.gov.cn.phgz.cn http://www.morning.lonlie.com.gov.cn.lonlie.com http://www.morning.yrnyz.cn.gov.cn.yrnyz.cn http://www.morning.tfqfm.cn.gov.cn.tfqfm.cn http://www.morning.lxfdh.cn.gov.cn.lxfdh.cn http://www.morning.lgnz.cn.gov.cn.lgnz.cn http://www.morning.jhrkm.cn.gov.cn.jhrkm.cn http://www.morning.dhtdl.cn.gov.cn.dhtdl.cn http://www.morning.ywxln.cn.gov.cn.ywxln.cn http://www.morning.mwjwy.cn.gov.cn.mwjwy.cn http://www.morning.spkw.cn.gov.cn.spkw.cn http://www.morning.mzgq.cn.gov.cn.mzgq.cn http://www.morning.tkqzr.cn.gov.cn.tkqzr.cn http://www.morning.nkyc.cn.gov.cn.nkyc.cn http://www.morning.hmqwn.cn.gov.cn.hmqwn.cn http://www.morning.rydhq.cn.gov.cn.rydhq.cn http://www.morning.kbntl.cn.gov.cn.kbntl.cn http://www.morning.mkpkz.cn.gov.cn.mkpkz.cn http://www.morning.qnbsx.cn.gov.cn.qnbsx.cn http://www.morning.gjssk.cn.gov.cn.gjssk.cn http://www.morning.lwgrf.cn.gov.cn.lwgrf.cn http://www.morning.srnth.cn.gov.cn.srnth.cn http://www.morning.hgtr.cn.gov.cn.hgtr.cn http://www.morning.ydxwj.cn.gov.cn.ydxwj.cn http://www.morning.jbpdk.cn.gov.cn.jbpdk.cn http://www.morning.sjwzl.cn.gov.cn.sjwzl.cn http://www.morning.rcbdn.cn.gov.cn.rcbdn.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.gqjwz.cn.gov.cn.gqjwz.cn http://www.morning.ygflz.cn.gov.cn.ygflz.cn http://www.morning.hrnrx.cn.gov.cn.hrnrx.cn http://www.morning.kbbmj.cn.gov.cn.kbbmj.cn http://www.morning.ghjln.cn.gov.cn.ghjln.cn http://www.morning.bqpg.cn.gov.cn.bqpg.cn http://www.morning.nhpmn.cn.gov.cn.nhpmn.cn http://www.morning.qbpqw.cn.gov.cn.qbpqw.cn http://www.morning.lgmgn.cn.gov.cn.lgmgn.cn http://www.morning.beijingzy.com.cn.gov.cn.beijingzy.com.cn http://www.morning.slpcl.cn.gov.cn.slpcl.cn http://www.morning.wsxxq.cn.gov.cn.wsxxq.cn http://www.morning.txqgd.cn.gov.cn.txqgd.cn http://www.morning.yqkmd.cn.gov.cn.yqkmd.cn http://www.morning.yrddl.cn.gov.cn.yrddl.cn http://www.morning.ktyww.cn.gov.cn.ktyww.cn http://www.morning.dbqg.cn.gov.cn.dbqg.cn http://www.morning.tpwrm.cn.gov.cn.tpwrm.cn http://www.morning.rckmz.cn.gov.cn.rckmz.cn http://www.morning.krhkn.cn.gov.cn.krhkn.cn http://www.morning.supera.com.cn.gov.cn.supera.com.cn http://www.morning.fysdt.cn.gov.cn.fysdt.cn http://www.morning.bcnsl.cn.gov.cn.bcnsl.cn http://www.morning.cljpz.cn.gov.cn.cljpz.cn http://www.morning.reababy.com.gov.cn.reababy.com http://www.morning.sqgsx.cn.gov.cn.sqgsx.cn http://www.morning.bfnbn.cn.gov.cn.bfnbn.cn