潜在的锁安全问题
在src/UtilsCtrl/ThreadPool/Queue/UWorkStealingQueue.h中,对于std::mutex锁的加锁去锁操作仍然应该使用raii,因为,std::deque和std::vector以及模板类型T的拷贝构造,拷贝复制等可能抛出异常,例如,内存不足等,此时,mutex已经被锁,异常后未被解锁,那么当前队列将无法再被访问。应该使用std::unique_lock对mutex锁进行操作,不过初始化时使用std::defer_lock_t进行延迟加锁
你好,感谢关注,非常专业的意见。
是这样的,当时在 wsque 中使用 try lock 的逻辑,主要是希望程序在无法获取mutex 的时候,尽可能保持在用户态的反复多试几次,从而达到加速的效果。
个人理解,如果每一处都上 raii锁,可能会相对降低性能
unique_lock是支持try_lock,lock,unlock,try_lock_for等等的,使用unique_lock最主要的原因是因为锁在被锁住时,发生了异常,将会自动调用unique_lock的析构函数来解锁。
而且unique_lock在构造时使用defer_lock_t来延迟加锁,之后的使用就可以像mutex一样去使用了,例如使用延迟加锁后,然后进行try_lock,unlock操作
性能上来说,内存的话也就栈上多一个bool和一个指针的消耗,指令执行的话,使用unique_lock包装的mutex的try_lock, unlock,也就比原本的mutex多了一次函数跳转,一个bool检测赋值的操作,甚至函数跳转可以被编译器优化成内联等等(msvc是这样的,gcc,clang没去看unique_lock的实现,不了解)。
raii著名的应用就是抛出异常后可以正确的释放或恢复数据
非常专业的意见。我周末有空的时候,会测试一下这两种写法,在CGraph 的一些性能测试用例的情况对比。
如果对这一块有兴趣,也很欢迎您可以针对 ws queue 做一下改动,然后做一下对比测试。我们一般是 8+cpu 的linux 系统,绑定核心跑。 具体os版本和 compile版本不是很care。
如果您对这一块感兴趣的话,非常希望可以添加您的wx,以便今后随时请教和咨询。 我的wx是 ChunelFeng,或者扫描readme 中的二维码。再次感谢您的关注。