Предположим, что простой способ реализации защиты ресурсов может быть реализован с помощью переменной, то есть BOOLEAN. Я приведу пример:
while {resource_protected == TRUE}
{
// resource is protected
}
Теперь мы можем защитить ресурс, установив resource_protected == TRUE
.
Чтобы проверить, доступен ли ресурс, мы просто используем что-то вроде этого:
if {resource_protected == FALSE}
{ // <---- rescheduling possible here!
resource_protected == TRUE; // protect resource
}
else
{
//try again later
}
Но есть две проблемы с этим методом. Во-первых, это создает занятое ожидание , поэтому процессор не может делать другие вещи. Во-вторых, что более важно, этот активный процесс может быть перепланирован (перемещен в очередь ожидания) после он проверяет BOOLEAN, но до он защищает ресурс, устанавливая BOOLEAN в значение TRUE, создавая тем самым иллюзия для других процессов, что ресурс по-прежнему свободен, потому что BOOLEAN еще не установлен. Это позволяет другому процессу запрашивать ресурс. Теперь активный процесс (переведенный из очереди ожидания в очередь из-за перепланирования) защищает ресурс, устанавливая для BOOLEAN значение TRUE (поскольку он не был установлен перепланированным процессом в очереди ожидания). Теперь этот активный процесс перепланирован, и предыдущий процесс снова становится активным, он установит для BOOLEAN значение ИСТИНА (хотя он был установлен в значение ИСТИНА уже во втором процессе), поскольку он уже проверил BOOLEAN. Теперь оба процесса требуют одного и того же ресурса, и вы умрете стариком, пытающимся отладить этот беспорядок.
С семафорами вы можете избежать этого уродливого безобразного беспорядка, потому что он допускает атомы. Атомы - это наборы инструкций, которые кажутся неделимыми с точки зрения других процессов. Таким образом, избегая таких неудач из-за плохой перепланировки.