scoped_lock() - 使用 pthread 的 RAII 实现
scoped_lock() - an RAII implementation using pthread
我有一个在 4 个线程之间共享的套接字,我想使用 RAII 原则来获取和释放互斥锁。
现实情况
- 我正在使用 pthread 库。
- 我无法使用 Boost。
- 我不能使用比 C++03 更新的任何东西。
- 我不能使用例外。
背景
我想我可以编写一个 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()
函数的两个简单的包装函数,还有一些额外的 tracelines/logging.
这样一来,我就不必至少写两条解锁语句,一条用于好的情况,一条用于坏的情况(至少一条,在某些情况下可能是更糟糕的路径)。
问题
我遇到的问题和我不喜欢这个方案的地方是析构函数。
我已经为每个函数努力完成了错误处理,但是从这个 ScopedLock()
的析构函数中,我无法通知调用者任何可能返回我的 m_unlock()
的错误。
这是 RAII 的一个基本问题,但在这种情况下,你很幸运。 pthread_unlock
仅当您错误地设置了互斥量 (EINVAL
) 或您试图从不拥有它的线程中解锁错误检查互斥量 (EPERM
) 时才会失败。这些错误表明您的代码中存在错误,而不是您应该考虑的运行时错误。在这种情况下,assert
ing errorCode==0
是一个合理的策略。
我有一个在 4 个线程之间共享的套接字,我想使用 RAII 原则来获取和释放互斥锁。
现实情况
- 我正在使用 pthread 库。
- 我无法使用 Boost。
- 我不能使用比 C++03 更新的任何东西。
- 我不能使用例外。
背景
我想我可以编写一个 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()
函数的两个简单的包装函数,还有一些额外的 tracelines/logging.
这样一来,我就不必至少写两条解锁语句,一条用于好的情况,一条用于坏的情况(至少一条,在某些情况下可能是更糟糕的路径)。
问题
我遇到的问题和我不喜欢这个方案的地方是析构函数。
我已经为每个函数努力完成了错误处理,但是从这个 ScopedLock()
的析构函数中,我无法通知调用者任何可能返回我的 m_unlock()
的错误。
这是 RAII 的一个基本问题,但在这种情况下,你很幸运。 pthread_unlock
仅当您错误地设置了互斥量 (EINVAL
) 或您试图从不拥有它的线程中解锁错误检查互斥量 (EPERM
) 时才会失败。这些错误表明您的代码中存在错误,而不是您应该考虑的运行时错误。在这种情况下,assert
ing errorCode==0
是一个合理的策略。