Быстрое решение для тупика? - PullRequest
0 голосов
/ 15 января 2019

Мой учебник описывает тупик, как показано на рисунке ниже:

enter image description here

, где s и t - семафоры, а

void P(sem_t *s); /* Wrapper function for sem_wait */
void V(sem_t *s); /* Wrapper function for sem_post */

Я могу понять, как это работает, если поток входит в область тупика, он не может прогрессировать дальше и застревает навсегда. И в учебниках говорится о правиле упорядочения замков Mutex: Программа свободна от тупиков, если для каждой пары мьютексов (s, t) в программе каждый поток, содержащий одновременно s и t, блокирует их в одном и том же порядке. Например, мы можем исправить тупик, сначала заблокировав s, а затем каждая нить. На рисунке ниже показан график прогресса: enter image description here

Но у меня просто может быть быстрое исправление, я не уверен, что я прав:

мы можем просто добавить некоторые тривиальные операторы, такие как одиночные ; или int test = 0 между операциями P и V, что создаст вертикальный разрыв между двумя запрещенными областями, так что потоки могут в конечном итоге пройти через разрыв, как показано на рисунке ниже : enter image description here

Является ли мой подход технически правильным?

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Две картинки из книги показывают перекрывающиеся прямоугольники. Перекрывающаяся область соответствует тому факту, что любой поток может одновременно владеть обоими мьютексами. Рисунок, который вы нарисовали, с другой стороны, показывает прямоугольники, которые не перекрываются. Если мы интерпретируем ваше изображение так же, как изображения в книге, то неперекрытие должно означать, что ни один из потоков не может одновременно владеть обоими мьютексами.

Да, реструктуризация кода, чтобы ни один поток не блокировал более одного мьютекса за раз, является гарантированным способом предотвращения взаимоблокировки потоков при получении мьютекса, но это также может усложнить для вашей программы делать все, что вам нужно. Таким образом, существует анти-паттерн Giant Lock .


Re, «Быстрое исправление тупика?»

тупик - это архитектурная проблема . Нет быстрых решений для архитектурных проблем.

0 голосов
/ 15 января 2019

мы можем просто добавить несколько тривиальных операторов, таких как single; или int test = 0 между операциями P и V, что создаст вертикальный зазор между двумя запрещенными областями, так что потоки могут в конечном итоге пройти через этот зазор, как показано на рисунке ниже

первый ";" (что вы ожидаете получить для того, что сгенерировано компилятором?) или int test = 0; не создаст пробел, и даже когда выполнение или потоки асинхронны, вы не можете предполагать что-то об их выполнении, и именно поэтому у вас есть мьютексы кстати

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...