Если бы синхронизирующих объектов не было, а операционная система не умела отслеживать особые собьпия, потоку пришлось бы самостоятельно синхронизировать ссбя с ними, применяя метод, который я как раз и собираюсь продемонстрировать Но поскольку в операционную систему встроена поддержка синхронизации объек тов, никогда не применяйте этот метод.
Суть его в том, что поток синхронизирует себя с завершением какой-либо задачи в другом потоке, постоянно просматривая значение переменной, доступной обоим поюкам Возьмем пример
volatile BOOL q_fFinishedCalculation = FALSE;
int WINAPI WinMain( )
{
CreateThread( , RecalcFunc, );
... // ждем завершения пересчета
while (!g_fFinishedCalculation)
...
}
DWORD WINAPI RecalcFunc(PVOID pvParam)
{ // выполняем пересчет
g_fFinishedCalculation = TRUE;
return(0);
}
Как видите, первичный поток (он исполняет функцию WinMain) при синхрониза ции по такому событию, как завершение функции RecalcFunc, никогда нс впадает в спячку, Поэтому система по-прежнсму выделяет ему процессорное время за счет дру гих потоков, занимающихся чем-то более полезным.
Другая проблема, связанная с подобным методом опроса, в том, что булева пере менная g_fFinishedCalculation может не получить значения TRUE — например, если у первичного потока более высокий приоритет, чем у потока, выполняющего функцию RecalcFunc. В этом случае система никогда не предоставит процессорное время по току RecalcFunc, а он никогда не выполнит оператор, присваивающий значение TRUE переменной g_fFinishedCalculation Если бы мы не опрашивали поток, выполняющий функцию WinMain, а просто отправили в спячку, это позволило бы системе отдать его долю процессорного времени потокам с более низким приоритетом, в частности потоку RecalcFunc.
Вполне допускаю, что опрос иногда удобен. В конце концов, именно это и дела ется при спин-блокировке Но есть два способа его реализации корректный и некор ректный Общее правило таково- избегайте применения спин-блокировки и опроса. Вместо этого пользуйтесь функциями, которые переводят Ваш поток в состояние ожидания до освобождения нужного ему ресурса. Как это правильно сделать, я объяс ню в следующем разделе.