Алгоритм банкира — это алгоритм распределения ресурсов и предотвращения тупиковых ситуаций , разработанный Эдсгером Дейкстрой , который проверяет безопасность, моделируя распределение заранее определенных максимально возможных объемов всех ресурсов , а затем выполняет проверку «s-state» для проверки возможных условий тупиковой ситуации для всех остальных ожидающих действий, прежде чем принять решение о том, следует ли разрешить продолжение распределения.
Алгоритм был разработан в процессе проектирования операционной системы THE и первоначально описан (на голландском языке ) в EWD108. [1] Когда новый процесс входит в систему, он должен объявить максимальное количество экземпляров каждого типа ресурса, которое он может когда-либо потребовать; очевидно, что это количество не может превышать общее количество ресурсов в системе. Кроме того, когда процесс получает все запрошенные им ресурсы, он должен вернуть их за конечное время.
Чтобы алгоритм Банкира работал, ему необходимо знать три вещи:
Ресурсы могут быть выделены процессу только в том случае, если объем запрошенных ресурсов меньше или равен доступному объему; в противном случае процесс ждет, пока ресурсы не станут доступны.
Некоторые ресурсы, которые отслеживаются в реальных системах, — это память , семафоры и доступ к интерфейсу .
Алгоритм банкира получил свое название из-за того, что этот алгоритм может быть использован в банковской системе для обеспечения того, чтобы у банка не закончились ресурсы, поскольку банк никогда не распределит свои деньги таким образом, что он больше не сможет удовлетворять потребности всех своих клиентов. [2] Используя алгоритм банкира, банк гарантирует, что когда клиенты запрашивают деньги, банк никогда не выйдет из безопасного состояния. Если запрос клиента не заставит банк выйти из безопасного состояния, наличные будут выделены, в противном случае клиент должен ждать, пока какой-либо другой клиент не внесет достаточно средств.
Основные структуры данных, которые необходимо поддерживать для реализации алгоритма Банкира:
Пусть n — число процессов в системе, а m — число типов ресурсов. Тогда нам понадобятся следующие структуры данных:
Примечание: Потребность[i,j] = Макс[i,j] - Выделение[i,j]. n=ma.
Общие системные ресурсы:АБВГД6 5 7 6
Доступные системные ресурсы:АБВГД3 1 1 2
Процессы (выделенные в настоящее время ресурсы): АБВГДП1 1 2 2 1П2 1 0 3 3П3 1 2 1 0
Процессы (максимальные ресурсы): АБВГДП1 3 3 2 2П2 1 2 3 4П3 1 3 5 0
Потребность = максимальные ресурсы - текущие выделенные ресурсыПроцессы (возможно необходимые ресурсы): АБВГДП1 2 1 0 1П2 0 2 0 1П3 0 1 4 0
Состояние (как в приведенном выше примере) считается безопасным, если все процессы могут завершить выполнение (завершить работу). Поскольку система не может знать, когда процесс завершится или сколько ресурсов он запросит к тому времени, система предполагает, что все процессы в конечном итоге попытаются получить заявленные максимальные ресурсы и вскоре после этого завершатся. Это разумное предположение в большинстве случаев, поскольку система не особенно озабочена тем, как долго выполняется каждый процесс (по крайней мере, с точки зрения избежания тупиков). Кроме того, если процесс завершается, не получив максимального ресурса, это только облегчает работу системы. Безопасное состояние считается принимающим решение, будет ли он обрабатывать очередь готовых процессов.
Учитывая это предположение, алгоритм определяет, является ли состояние безопасным , пытаясь найти гипотетический набор запросов от процессов, который позволил бы каждому из них получить максимум ресурсов, а затем завершиться (возвратив свои ресурсы системе). Любое состояние, в котором такого набора не существует, является небезопасным состоянием.
Мы можем показать, что состояние, приведенное в предыдущем примере, является безопасным, показав, что каждый процесс может получить максимум ресурсов, а затем завершиться.
В качестве примера небезопасного состояния рассмотрим, что произойдет, если процесс 2 в начале удерживает 1 единицу ресурса B.
Когда система получает запрос на ресурсы, она запускает алгоритм Банкира, чтобы определить, безопасно ли удовлетворить запрос. Алгоритм довольно прост, если понять разницу между безопасными и небезопасными состояниями.
Решение о том, отклонить или отложить невыполнимый или небезопасный запрос, принимается операционной системой.
Пример
Предположим, что процесс 1 запрашивает 2 единицы ресурса C, начиная с того же состояния, что и в предыдущем примере.
С другой стороны, предположим, что процесс 3 запрашивает 1 единицу ресурса C.
Доступные системные ресурсы АБВГДБесплатно 3 1 0 2
Процессы (выделенные в настоящее время ресурсы): АБВГДП1 1 2 2 1П2 1 0 3 3П3 1 2 2 0
Процессы (максимальные ресурсы): АБВГДП1 3 3 2 2П2 1 2 3 4П3 1 3 5 0
Последний пример: предположим, что из исходного состояния процесс 2 запрашивает 1 единицу ресурса B.
Доступные системные ресурсы: АБВГДБесплатно 3 0 1 2
Процессы (выделенные в настоящее время ресурсы): АБВГДП1 1 2 5 1П2 1 1 3 3П3 1 2 1 0
Процессы (максимальные ресурсы): АБВГДП1 3 3 2 2П2 1 2 3 4П3 1 3 5 0
импортировать numpy как npn_processes = int ( input ( "Количество процессов? " )) n_resources = int ( input ( "Количество ресурсов? " ))available_resources = [ int ( x ) for x in input ( "Заявить вектор? " ) . split ( " " )]current_allocated = np . array ([ [ int ( x ) for x in input ( f "В настоящее время выделено для процесса { i + 1 } ? " ) . split ( " " )] for i in range ( n_processes ) ]) max_demand = np . array ([ [ int ( x ) for x in input ( f "Максимальный спрос от процесса { i + 1 } ? " ) . split ( " " )] for i in range ( n_processes ) ]) total_available = available_resources - np.sum ( current_allocated , axis = 0 ) running = np.ones ( n_processes ) # Массив с n_processes 1, указывающий, запущен ли еще процесс while np.count_nonzero ( running ) > 0 : at_least_one_allocated = False for p in range ( n_processes ): if running [ p ]: if all ( i > = 0 for i in total_available - ( max_demand [ p ] - current_allocated [ p ] )): at_least_one_allocated = True print ( f " { p } is running" ) running [ p ] = 0 total_available += current_allocated [ p ] if not at_least_one_allocated : print ( "Unsafe" ) break # выход else : print ( "Safe" )
Как и другие алгоритмы, алгоритм банкира имеет некоторые ограничения при реализации. В частности, ему необходимо знать, сколько каждого ресурса процесс может запросить. В большинстве систем эта информация недоступна, что делает невозможным реализацию алгоритма банкира. Кроме того, нереалистично предполагать, что количество процессов статично, поскольку в большинстве систем количество процессов меняется динамически. Более того, требование того, чтобы процесс в конечном итоге освободил все свои ресурсы (когда процесс завершается), достаточно для корректности алгоритма, однако этого недостаточно для практической системы. Ожидание в течение часов (или даже дней) для освобождения ресурсов обычно неприемлемо.
{{cite book}}
: CS1 maint: несколько имен: список авторов ( ссылка )