首页 > 解决方案 > scoped_lock() - 使用 pthread 的 RAII 实现

问题描述

我有一个在 4 个线程之间共享的套接字,我想使用RAII原则来获取和释放互斥锁。


地面现实

  1. 我正在使用 pthread 库。
  2. 我无法使用 Boost。
  3. 我不能使用比 C++03 更新的东西。
  4. 我不能使用例外。

的背景

不必每次在使用前锁定套接字的互斥锁,然后立即解锁互斥锁,我想我可以编写一个scoped_lock()锁定互斥锁的函数,一旦超出范围,它会自动解锁互斥锁。

因此,很简单,我在构造函数中进行了锁定,在析构函数中进行了解锁,如此处所示。

ScopedLock::ScopedLock(pthread_mutex_t& mutex, int& errorCode)
: m_Mutex(mutex)
{
    errorCode = m_lock();
}

ScopedLock::~ScopedLock()
{
    errorCode = m_unlock();
}

其中m_lock()m_unlock()分别是围绕pthread_mutex_lock()pthread_mutex_unlock()函数的两个包装函数,带有一些额外的跟踪线/日志记录。

这样,我就不必编写至少两个解锁语句,一个用于好情况,一个用于坏情况(至少一个,在某些情况下可能是更多的坏路径)。


问题

我遇到的问题和我不喜欢这个方案的地方是析构函数。

我已经认真地为每个函数完成了错误处理,但是从 this 的析构函数中ScopedLock(),我无法通知调用者任何可能返回 my 的错误m_unlock()

标签: c++error-handlingpthreadsc++03raii

解决方案


这是 RAII 的一个基本问题,但在这种情况下,你很幸运。pthread_unlock仅当您错误地设置互斥锁 ( EINVAL) 或尝试从不拥有它的线程解锁错误检查互斥锁 ( ) 时才会失败EPERM。这些错误表示代码中的错误,而不是您应该考虑的运行时错误。assert在这种情况下, ingerrorCode==0是一种合理的策略。


推荐阅读