«Правильным» решением является наличие флага «бесперебойного режима», который имеет следующие свойства:
- атомарное чтение и запись (у вас это есть с оператором test-and-set);
- Ваше приложение не может быть прервано ни при каких условиях (перепланирование потока и т. Д.), Пока это установлено.
У вас есть один удерживающий поток под мьютексом и n ожидающих потоков, которые помещаются в очередь (любой вид списка, но я предпочитаю очередь.) При блокировке мьютекса вы переходите в непрерывный режим путем атомного тестирования / установки вашего флаг (вращаться или спать, пока флаг установлен), и либо получить мьютекс, либо войти в очередь для этого (в последнем случае текущий поток не может повторно войти в очередь готовности планировщика.) При разблокировке вы переходите в режим бесперебойного и освободить мьютекс к следующему потоку в очереди, если таковой имеется.
Я думаю, что libpthread и такие реализовали мьютексы таким образом. Само по себе это не сложно, но решения либо окончательно верны, либо неверны.
Надеюсь, это имеет смысл!