Я уже заблокировал мьютекс? - PullRequest
2 голосов
/ 27 февраля 2020

Функция работает с переменными, которые должны быть защищены мьютексом от параллельных потоков.
Вызывающий эту функцию блокирует мьютекс, выполняет другие действия и вызывает эту функцию.

Теперь ситуация возникла необходимость в том, чтобы эта функция вызывалась из другого фрагмента кода.
Конечно, этот код также может блокировать мьютекс, но я подумал, что, возможно, функция может увидеть, должна ли она блокировать мьютекс или нет.

Что Мне нужна функция, которая сообщает мне, заблокировал ли текущий поток мьютекс. Тогда функция может go включиться без блокировки. В противном случае он заблокируется.

int need_to_lock = !my_thread_has_locked_the_mutex(&mutex);

if (need_to_lock)
    mutex_lock(&mutex);

access variables;

if (need_to_lock)
    mutex_unlock(&mutex);

Существует ли my_thread_has_locked_the_mutex? Я ничего не смог найти.

Редактировать в комментарии

Я не знал о рекурсивных мьютексах. Кажется, они делают то, о чем я думал.
То, что я сейчас использую, - это нерекурсивный мьютекс, который блокируется, если заблокирован дважды из одного потока.

1 Ответ

3 голосов
/ 27 февраля 2020

Почему бы просто не использовать вместо этого рекурсивный мьютекс? Рекурсивный мьютекс по существу похож на обычный мьютекс, но может быть заблокирован несколько раз одним потоком (то есть рекурсивно).

В некоторых библиотеках мьютексы по умолчанию являются рекурсивными. С C pthreads вам нужно включить рекурсивные мьютексы, соответствующим образом инициализировав свои мьютексы:

pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(mutex, &attr);

Другой подход - разделить вашу функцию на два варианта: один, который должен вызываться с удержанным мьютексом, и тот, который должен быть вызван без удержания мьютекса. Обычное соглашение об именах заключается в добавлении _locked к первому или _unlocked ко второму. Разблокированная функция просто блокирует мьютекс и затем вызывает заблокированную функцию, поэтому здесь не будет никакого реального дублирования кода.

...