В данном варианте для ухода от жесткой синхронизации используются две управляющие переменные, фиксирующие использование процессами разделяемого ресурса.
int ResourceProc1 = 0; // = 1 – ресурс занят
процессом 1
int ResourceProc2 = 0; // = 1 – ресурс занят
процессом 2
Process_1() {
while (1) {
// повторять, пока ресурс используется процессом 2
while ( ResourceProc2 == 1 );
ResourceProc1 = 1;
< Использование общего ресурса >
ResourceProc1 = 0;
}
}
Process_2()
{
while (1) {
// повторять, пока ресурс используется процессом 1
while ( ResourceProc1 == 1 );
ResourceProc2 = 1;
< Использование общего ресурса >
ResourceProc2 = 0;
}
}
Предложенный способ разделения ресурсов устраняет недостатки жесткой синхронизации, однако при этом теряется гарантия взаимоисключения – оба процесса могут оказаться одновременно в своих критических секциях (это может произойти, например, при переключении между процессами в момент завершения проверки занятости ресурса). Данная проблема возникает вследствие различия моментов проверки и фиксации занятости ресурса.
Следует отметить, что в отдельных случаях взаимоисключение процессов в данном примере может произойти и корректно - все определяется конкретными моментами переключения процессов. Отсюда следует два важных вывода:
- успешность однократного выполнения не может служить доказательством правильности функционирования параллельной программы даже при неизменных параметрах решаемой задачи;
- для выявления ошибочных ситуаций необходима проверка разных временных траекторий выполнения параллельных процессов.