Я читаю Thread Synchronization
из книги «Расширенное программирование в среде unix».
В этом разделе приведен пример использования мьютекса с динамически размещаемый объект. У меня есть некоторые сомнения в том же.
Здесь я делюсь хронологией событий (сверху вниз), чтобы объяснить свои сомнения:
- Thread1 создан.
- Thread1 создает мьютекс-переменную, инициализирует его и помещает в глобальный список, чтобы другие могли его использовать.
- Теперь Thread1 получил блокировку для использования совместно используемой структуры данных, скажем,
ds
. Thread1 нужно проделать очень большой объем работы сds
, т.е. Thread1 собирается получить эту блокировку в течение длительного времени. - Теперь, когда Thread1 все еще получил блокировку, создается Thread2.
- Теперь Thread2 тоже хочет использовать ds.
- Таким образом, Thread2 должен сначала увеличить счетчик, показывающий, что ссылка на ds увеличена. Для этого (согласно книге) сначала необходимо получить блокировку, используя ту же переменную
mutex_t
, прежде чем увеличивать счетчик. - Но поскольку Thread1 уже получил блокировку для этой переменной
mutex_t
, поэтому, когда Thread2 вызываетlock()
перед увеличением счетчика, ему придется подождать, пока Thread1 не разблокирует блокировку.
Сомнения:
- О каком глобальном списке он говорит (означает просто создать какой-либо список и передать ссылку на него всем потокам или любому конкретному списку)?
- Когда Thread1 создал переменную блокировки, он установил счетчик на 1. Затем Thread2 ожидает увеличения этого счетчика до 2. Но предположим ситуацию, в которой после выполнения текущей работы Thread1 не нужно использовать ds. Поэтому перед разблокировкой также уменьшите счетчик или сначала разблокируйте его, а затем вызовите
foo_rele()
, чтобы снова заблокировать и уменьшить счетчик. Теперь возможно, что до того, как Thread2 увеличит счетчик, Thread1 уменьшит его. Если да (по моему мнению), то моя структура данных будет уничтожена? Так что я думаю, что в этом примере книги есть небольшая ошибка. Было бы лучше, если бы мы использовали разные mutex_var для увеличения счетчика?