【问题标题】:custom RAII C++ implementation for scoped mutex locks范围互斥锁的自定义 RAII C++ 实现
【发布时间】:2011-12-20 02:33:28
【问题描述】:

我不能使用 boost 或最新的 std::thread 库。要走的路是创建一个范围互斥体的自定义实现。

一句话,当一个类实例被创建一个互斥锁。在类销毁时,互斥锁被解锁。

任何可用的实现?我不想重新发明*。

我需要使用 pthreads。

  • 资源获取正在初始化 == “RAII”

【问题讨论】:

    标签: c++ linux pthreads mutex raii


    【解决方案1】:

    注意这是一个旧答案。 C++11 包含更好的帮助程序,更独立于平台:

    还有其他选项,例如 std::unique_lock、boost::unique_lock

    任何 RAII 教程都可以。

    这里是要点:(也在http://ideone.com/kkB86

    // stub mutex_t: implement this for your operating system
    struct mutex_t 
    { 
        void Acquire() {} 
        void Release() {} 
    };
    
    struct LockGuard
    {
         LockGuard(mutex_t& mutex) : _ref(mutex) 
         { 
             _ref.Acquire();  // TODO operating system specific
         }
    
         ~LockGuard() 
         { 
              _ref.Release(); // TODO operating system specific
         }
       private:
         LockGuard(const LockGuard&); // or use c++0x ` = delete`
    
         mutex_t& _ref;
    };
    
    int main()
    {
        mutex_t mtx;
    
        {
            LockGuard lock(mtx);
            // LockGuard copy(lock); // ERROR: constructor private
            // lock = LockGuard(mtx);// ERROR: no default assignment operator
        }
    
    }
    

    当然,你可以将它泛型化为mutex_t,你可以防止子类化。 由于引用字段,已禁止复制/分配

    编辑对于 pthread:

    struct mutex_t
    {
        public:
            mutex_t(pthread_mutex_t &lock) : m_mutex(lock) {}
    
            void Acquire() { pthread_mutex_lock(&m_mutex);   }
            void Release() { pthread_mutex_unlock(&m_mutex); }
        private:
            pthread_mutex_t& m_mutex;
    };
    

    【讨论】:

    • 我更新了我的问题以请求 pthreads。因此您的 _ref.Acquire() 将是 pthread_mutex_lock(_ref)?
    • 嗯。为您的线程库实现的部分被标记为这样。无论如何,我为 pthread_mutex_t 添加了一个快速实现以供参考。
    • 在我指定操作系统详细信息之前你已经得到了答案:-)
    • 我建议反对pthread_mutex_lock 直接放入锁具。我希望有 一个 正确 RIAA 类,它可以监控许多不同的同步原语。它减少了代码重复,使 LockGuard 可单元测试,如果您更改锁实现等,则不需要您重新编译所有内容。
    • @cateof:您很可能只想初始化和销毁​​互斥锁​​一次,即使您想锁定/解锁多次。初始化和销毁​​与mutex_t 构造和销毁更相关(如果您愿意,但您可能不想通过引用获取互斥锁,而是在内部构造它)......无论如何,这部分问题不应与锁上的 RAII 混在一起。
    最近更新 更多