Я пытаюсь реализовать семафор с мьютексом, чтобы узнать больше о параллельных примитивах и шаблонах и о том, как писать правильные параллельные программы.
Вот ресурс, который я нашел:
http://webhome.csc.uvic.ca/~mcheng/460/notes/gensem.pdf
Решение № 1 помечено как «неправильное» на странице 9. Я реализовал алгоритм здесь . Запуск этой программы несколько раз может привести к зависанию потоков. Я провел некоторый анализ и понял, что может произойти следующая последовательность операций с мьютексом d
:
// d was initialized as locked
d.unlock(); // d is unlocked
d.unlock(); // d is still unlocked (unaffected)
d.lock(); // d is locked
d.lock(); // d is still locked (deadlock)
Это приведет к тупику последнего d.lock()
.
Решение № 2 решило эту проблему, обеспечив переход от сигнального потока к активному потоку путем повторного использования мьютекса m
. Я реализовал эту версию здесь .
В этом решении после d.unlock()
, m
остается заблокированным, что означает последующее
Операции post()
будут заблокированы до разблокирования m
. Тогда d.lock()
вызывается после m.unlock()
, убедившись, что d
находится в заблокированном состоянии перед
разрешить выполнение последующих post()
операций.
Хотя я понимаю, как это решение решает проблему, мне трудно утверждать, что это правильно с точки зрения других потенциальных проблем. Существуют ли какие-либо общие правила и рекомендации, которым мы можем следовать, чтобы гарантировать, спорить или даже доказывать правильность программ, подобных этой?
Я хочу задать этот вопрос из-за следующих 2 решений из записки. Я реализовал решение # 3 и решение # 4 , но у обоих были замороженные потоки при тестировании несколько раз. Я не уверен, что это проблема моей реализации или само решение неверно.
Буду признателен, если вы просто проанализируете правильность этих решений, но я бы больше, чем когда-либо, хотел бы найти способ рассуждать о любых алгоритмах такого рода и проверять их правильность.