Как сделать критический раздел с помощью Boost?

Для моего кросс-платформенного приложения я начал использовать Boost, но я не могу понять, как я могу реализовать код для воспроизведения поведения критического раздела Win32 или .Net lock.

Я хочу написать метод Foo, который можно вызывать из разных потоков для управления операциями записи в общие поля. Рекурсивные вызовы внутри одного потока должны быть разрешены (Foo() → Foo()).

В С# эта реализация очень проста:

object _synch = new object();
void Foo()
{
    lock (_synch)  // one thread can't be lock by him self, but another threads must wait untill
    {
        // do some works
        if (...) 
        {
           Foo();
        }
    }
}

Ответ 1

С boost вы можете использовать boost:: lock_guard < > class:

class test
{
public:
 void testMethod()
 {
  // this section is not locked
  {
   boost::lock_guard<boost::recursive_mutex> lock(m_guard);
   // this section is locked
  }
  // this section is not locked
 }
private:
    boost::recursive_mutex m_guard;
};

PS Эти классы расположены в библиотеке Boost.Thread.

Ответ 2

Здесь перепишите ваш пример, используя Boost.Thread: я удалил комментарии, но в остальном он должен быть переписан от 1 до 1.

boost::recursive_mutex mtx;

void Foo()
{
    boost::lock_guard<boost::recursive_mutex> lock(mtx);
    if (...) 
    {
       Foo();
    }
}

Документацию можно найти здесь.

Обратите внимание, что Boost определяет несколько различных типов мьютексов. Поскольку ваш пример показывает, что блокировка берется рекурсивно, нам нужно использовать как минимум boost::recursive_mutex.

Существуют также различные типы блокировок. В частности, если вы хотите блокировку чтения-записи (чтобы несколько считывателей могли удерживать блокировку одновременно, пока ни один из них не имеет блокировки), вы можете использовать boost::shared_lock вместо lock_guard.