scoped_lock () - реализация RAII с использованием pthread - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть сокет, разделенный между 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(), соответственно, с некоторыми дополнительными tracelines / logging.

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


Проблема

Проблема, с которой я столкнулсяЯ столкнулся с тем, что мне не нравится в этой схеме - деструктор.

Я старательно сделал для каждой функции обработку ошибок, но от деструктора этого ScopedLock() я не могу сообщитьвызывающая сторона о любых ошибках, которые могут быть возвращены моим m_unlock().

1 Ответ

0 голосов
/ 26 февраля 2019

Это фундаментальная проблема с RAII, но в этом случае вам повезло.Сбой pthread_unlock возможен только в том случае, если вы неправильно настроили мьютекс (EINVAL) или пытаетесь разблокировать мьютекс, проверяющий ошибки, из потока, которому он не принадлежит (EPERM).Эти ошибки являются признаками ошибок в вашем коде, а не ошибками времени выполнения, которые вы должны учитывать.assert ing errorCode==0 - разумная стратегия в этом случае.

...