3

我很确定这是一个幼稚的问题,但仍然会问它,因为我在网上找不到太多帮助。我正在使用 pthreads 编写 c++ 代码。以下是其中一种方法的概述

void Method1()
{
    try
    {
    pthread_mutex_lock(&syncLock);
    statement1;
    statement2;
    pthread_mutex_unlock(&syncLock);
    statement3;
    statement4;
    }
    catch(exception& e)
    {
    log error
    }
}

其中 syncLock 是类型pthread_mutex_t并且使用默认初始化进行初始化。

我的问题是,如果在方法的 statement2 中引发异常,则控制直接传递给 catch 语句。在这种情况下,我的互斥锁保持锁定状态。但我也不能简单地在 catch 块中编写解锁语句,因为如果异常来自语句 3,则互斥锁已被解锁,并且在已解锁的互斥锁上调用解锁会导致未定义的行为。

那么有没有办法可以在 catch 语句中检查互斥锁是否已解锁。或者,C++ 中是否有可用的 C# 样式锁定语句替代方案,所以我确信即使从该块中抛出异常,锁定也会被释放

我不倾向于为此目的使用库。一个简单的自定义解决方案将不胜感激

谢谢

4

2 回答 2

6

编写一个小型 RAII 风格的储物柜类:

class lock { 
    pthread_mutex_t &mutex;
public:   
    lock(pthread_mutex_t &m) :mutex(m) { pthread_mutex_lock(&mutex); }
    ~lock() { pthread_mutex_unlock(&mutex); }
};

然后编写如下代码:

void Method1()
{
    try
    {
        { 
            lock l(syncLock);
            statement1;
            statement2;
         }
         statement3;
         statement4;    
    }
    catch(exception& e)
    {
    log error
    }
}

当您退出定义锁的作用域时,锁将通过析构函数销毁,从而调用pthread_mutex_unlock. 无论您是正常退出范围还是通过异常退出,都会发生这种情况。当您进入异常处理程序时,您知道互斥锁已被解锁。

请注意,C++11 已将其内置到标准库中std::lock_guard(并且有许多互斥类型可供使用)。

于 2013-01-11T06:50:57.047 回答
1

使用 pthread_mutex_trylock 如果互斥锁已经被锁定,它会给出忙碌状态。如果它没有锁定,那么它将锁定它。在此解锁互斥锁之后。pthread_mutex_unlock(pthread_mutex_t *mutex);

于 2013-01-11T06:56:17.540 回答