内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
类型擦除类(非模板抽象基类和模板派生类):
#include <type_traits> #include <mutex> #include <chrono> #include <iostream> namespace detail { struct locker_unlocker_base { virtual void lock() = 0; virtual void unlock() = 0; }; template<class Mutex> struct locker_unlocker : public locker_unlocker_base { locker_unlocker(Mutex &m) : m_m{&m} {} virtual void lock() { m_m->lock(); } virtual void unlock() { m_m->unlock(); } Mutex *m_m; }; }
现在te_lock_guard
,类型擦除锁保护,只需在构造时(没有动态内存分配)将正确类型的对象放置--新闻:
class te_lock_guard { public: template<class Mutex> te_lock_guard(Mutex &m) { new (&m_buf) detail::locker_unlocker<Mutex>(m); reinterpret_cast<detail::locker_unlocker_base *>(&m_buf)->lock(); } ~te_lock_guard() { reinterpret_cast<detail::locker_unlocker_base *>(&m_buf)->unlock(); } private: std::aligned_storage<sizeof(detail::locker_unlocker<std::mutex>), alignof(detail::locker_unlocker<std::mutex>)>::type m_buf; };
我检查了性能与标准库的类:
int main() { constexpr std::size_t num{999999}; { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); for(size_t i = 0; i < num; ++i) { std::mutex m; te_lock_guard l(m); } std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl; } { std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now(); for(size_t i = 0; i < num; ++i) { std::mutex m; std::unique_lock<std::mutex> l(m); } std::chrono::steady_clock::time_point end= std::chrono::steady_clock::now(); std::cout << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << std::endl; } }
试试这样:
template<class Mutex> auto make_lock(Mutex& m) { return std::unique_lock<Mutex>(m); } ... std::mutex m; std::recursive_mutex m2; auto lock = make_lock(m); auto lock2 = make_lock(m2);