Состояние гонки в алгоритме Морриса ⇐ C++
-
Гость
Состояние гонки в алгоритме Морриса
Я почти дословно реализовал алгоритм Морриса для мьютекса без голодания из Маленькой книги семафоров (стр. 85). Примерно в половине случаев он завершается корректно, а в другой половине — зависает в середине выполнения. Это указывает на то, что существует какая-то гонка, но я не могу ее определить.
Я нашел в Интернете другие версии псевдокода алгоритма Морриса, и они кажутся идентичными тому, что находится в Маленькой книге семафоров. На данный момент я предполагаю, что семафоры в C++ могут работать немного иначе, чем семафоры в исследованиях и других языках, но я не уверен. Что вызывает это состояние гонки?
#include #include #include #include #include #include #include std::binary_semaphore t1(1); std::binary_semaphore t2(0); std::мьютекс мьютекс; int комната1 = 0; int комната2 = 0; void func(std::stop_token stop_token, int id){ в то время как (!stop_token.stop_requested()){ мьютекс.блокировка(); комната1 += 1; мьютекс.разблокировка(); t1.приобрести(); комната2 += 1; мьютекс.блокировка(); комната1 -= 1; если (комната1 == 0){ мьютекс.разблокировка(); t2.выпуск(); } еще { мьютекс.разблокировка(); t1.выпуск(); } t2.acquire(); комната2 -= 1; // критическая область { std::osyncstream synced_out(std::cout); synced_out
Я почти дословно реализовал алгоритм Морриса для мьютекса без голодания из Маленькой книги семафоров (стр. 85). Примерно в половине случаев он завершается корректно, а в другой половине — зависает в середине выполнения. Это указывает на то, что существует какая-то гонка, но я не могу ее определить.
Я нашел в Интернете другие версии псевдокода алгоритма Морриса, и они кажутся идентичными тому, что находится в Маленькой книге семафоров. На данный момент я предполагаю, что семафоры в C++ могут работать немного иначе, чем семафоры в исследованиях и других языках, но я не уверен. Что вызывает это состояние гонки?
#include #include #include #include #include #include #include std::binary_semaphore t1(1); std::binary_semaphore t2(0); std::мьютекс мьютекс; int комната1 = 0; int комната2 = 0; void func(std::stop_token stop_token, int id){ в то время как (!stop_token.stop_requested()){ мьютекс.блокировка(); комната1 += 1; мьютекс.разблокировка(); t1.приобрести(); комната2 += 1; мьютекс.блокировка(); комната1 -= 1; если (комната1 == 0){ мьютекс.разблокировка(); t2.выпуск(); } еще { мьютекс.разблокировка(); t1.выпуск(); } t2.acquire(); комната2 -= 1; // критическая область { std::osyncstream synced_out(std::cout); synced_out
Мобильная версия