Windows для профессионалов


Несколько полезных приемов


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

На каждый разделяемый ресурс используйте отдельную структуру CRITICAL_SECTION

Если в Вашей программе имеется несколько независимых структур данных, создавайте для каждой из них отдельный экземпляр структуры CRITICAL_SECTION. Это лучше, чем защищать все разделяемые ресурсы одной критической секцией. Посмотрите на этот фрагмент кода:

int g_nNums[100]; // один разделяемый ресурс

TCHAR g_cChars[100]; // Другой разделяемый ресурс

CRITICAL_SECTION g_cs, // защищает оба ресурса

DWORD WINAPI ThreadFunc(PVOID pvParam)
{ EnterCriticalSection(&g_cs);
for (int x = 0; x < 100: x++)
{
g_nNums[x] = 0;
g_cChars|x] - TEXT('X');
}

LeaveCriticalSection(&g_cs);
return(0);
}

Здесь создана единственная критическая секция, защищающая оба массива — g_nNums и g_cChars - в период их инициализации. Но эти массивы совершенно различны. И при выполнении данного цикла ни один из потоков не получит доступ ни к одному массиву. Теперь посмотрим, что будет, если ThreadFunc реализовать так:

DWORD WINAPI ThreadFunc(PVOID pvParam)
{
EnterCriticalSection(&g_cs);
for (int x = 0; x < 100; x++)

g_nNums[x] = 0;
for (x = 0; x < 100; x++)

g_cChars[x] = TEXT('X');
LeaveCriticalSection(&g_cs);
return(0);
}

В этом фрагменте массивы инициализируются по отдельности, и теоретически после инициализации g_nNums посторонний поток, которому нужен доступ только к первому массиву, сможет начать исполнение — пока ThreadFunc занимается вторым массивом. Увы, это невозможно: обе структуры данных защищены одной критической секцией. Чтобы выйти из затруднения, создадим две критические секции:

int g_nNum[100]; // разделяемый ресурс

CRITICAL_SECTION g_csNums; // защищает g_nNums

TCHAR g_cChars[100]; // другой разделяемый ресурс




Начало  Назад  Вперед