«Вложенный» scoped_lock - PullRequest
       25

«Вложенный» scoped_lock

6 голосов
/ 23 октября 2011

Мой сокращенный, упрощенный класс выглядит следующим образом:

class A
{
    public:
    // ...
    methodA();
    methodB();

    protected:
    mutable boost::mutex m_mutex;
    sometype*  m_myVar;
}

A::methodA( int someParam )
{
    boost::mutex::scoped_lock myLock(m_mutex);
    m_myVar->doSomethingElse();
}

A::methodB( int someParam )
{
    boost::mutex::scoped_lock myLock(m_mutex);
    m_myVar->doSomething();
    this->methodA(someParam);
}

Я хотел бы синхронизировать доступ на m_myVar.При вызове A::methodB() поток сталкивается с блокировкой с одним и тем же мьютексом дважды и, очевидно, блокируется в первой строке A::methodA()

. Есть ли способ заставить scoped_lock не блокировать нить при повторном прохождении?

Конечно, я просто мог бы позвонить m_mutex.unlock().Но это освободило бы другие потоки, ожидающие блокировки, а это совершенно не то, что я хочу.

Есть идеи?

С наилучшими пожеланиями, Тобиас

Ответы [ 3 ]

12 голосов
/ 23 октября 2011

Это то, что boost::recursive_mutex позволяет получить блокировку одним и тем же потоком без блокировки несколько раз.Используйте его вместо boost::mutex

4 голосов
/ 23 октября 2011

Есть разные вещи, которые вы можете сделать здесь.Вы можете использовать рекурсивный мьютекс, который может быть получен несколько раз в одном потоке, или вы можете разделить methodA на частный метод с реализацией без блокировок и открытый метод, который блокирует, а затем вызывает закрытую реализацию.Тогда methodB вызовет внутреннюю реализацию, удерживая блокировку.Поскольку метод является частным, вы можете контролировать все его применения и можете гарантировать, что метод реализации вызывается только при удержании блокировки.

0 голосов
/ 23 октября 2011

Вы можете использовать tryLock в methodA, если попытка не удалась, вы должны получить текущий threadId и продолжить выполнение, только если идентификатор потока совпадает с threadid, который запускает MethodB. В противном случае, если попытка завершится успешно, вы можете продолжить выполнение нормально.

...