Вход/Регистрация
Программирование на Visual C++. Архив рассылки
вернуться

Jenter Алекс

Шрифт:

Критические секции

Объект-критическая секция помогает программисту выделить участок кода, где поток получает доступ к разделяемому ресурсу, и предотвратить одновременное использование ресурса. Перед использованием ресурса поток входит в критическую секцию (вызывает функцию EnterCriticalSection). Если после этого какой-либо другой поток попытается войти в ту же самую критическую секцию, его выполнение приостановится, пока первый поток не покинет секцию с помощью вызова LeaveCriticalSection. Похоже на взаимоисключение, но используется только для потоков одного процесса.

Существует также функция TryEnterCriticalSection, которая проверяет, занята ли критическая секция в данный момент. С ее помощью поток в процессе ожидания доступа к ресурсу может не блокироваться, а выполнять какие-то полезные действия.

Защищенный доступ к переменным

Существует ряд функций, позволяющих работать с глобальными переменными из всех потоков не заботясь о синхронизации, т.к. эти функции сами за ней следят. Это функции InterlockedIncrement/InterlockedDecrement, InterlockedExchange,InterlockedExchangeAdd и InterlockedCompareExchange. Например, функция InterlockedIncrement увеличивает значение 32-битной переменной на единицу – удобно использовать для различных счетчиков. Более подробно об этих функциях см. в документации.

Пример

Как известно, теория лучше всего познается на примерах. Давайте рассмотрим небольшой пример работы с объектом-взаимоисключением. Для простоты я использовал консольное Win32 приложение, но как вы понимаете, это совершенно не обязательно.

#include <windows.h>

#include <iostream.h>

void main {

 DWORD res;

 // создаем объект-взаимоисключение

 HANDLE mutex = CreateMutex(NULL, FALSE, "APPNAME-MTX01");

 // если он уже существует, CreateMutex вернет дескриптор существующего объекта,

 // а GetLastError вернет ERROR_ALREADY_EXISTS

 // в течение 20 секунд пытаемся захватить объект

 cout<<"Trying to get mutex...\n";

 cout.flush;

 res = WaitForSingleObject(mutex, 20000);

 if (res == WAIT_OBJECT_0) // если захват удался

 {

// ждем 10 секунд

cout<<"Got it! Waiting for 10 secs…\n";

cout.flush;

Sleep(10000);

// освобождаем объект

cout<<"Now releasing the object.\n";

cout.flush;

ReleaseMutex(mutex);

 }

 // закрываем дескриптор

 CloseHandle(mutex);

}

Для проверки работы мьютекса запустите сразу два экземпляра этого приложения. Первый экземпляр сразу захватит объект и освободит его только через 10 секунд. Только после этого второму экземпляру удастся захватить объект. В данном примере объект используется для синхронизации между процессами, поэтому он обятельно должен иметь имя.

Cинхронизация в MFC

Библиотека MFC содержит специальные классы для синхронизации потоков (CMutex, CEvent, CCriticalSection и CSemaphore). Эти классы соответствуют объектам синхронизации WinAPI и являются производными от класса CSyncObject. Чтобы понять, как их использовать, достаточно просто взглянуть на конструкторы и методы этих классов – Lock и Unlock. Фактически эти классы – всего лишь обертки для объектов синхронизации.

Eсть еще один способ использования этих классов – написание так называемых потоково-безопасных классов (thread-safe classes). Потоково-безопасный класс – это класс, представляющий какой либо ресурс в вашей программе. Вся работа с ресурсом осуществляется только через этот класс, который содержит все необходимые для этого методы. Причем класс спроектирован таким образом, что его методы сами заботятся о синхронизации, так что в приложении он используется как обычный класс. Объект синхронизации MFC добавляется в этот класс в качестве закрытого члена класса, и все функции этого класса, осуществляющие доступ к ресурсу, согласуют с ним свою работу.

С классами синхронизации MFC можно работать как напрямую, используя методы Lock и Unlock, так и через промежуточные классы CSingleLock и CMultiLock (хотя на мой взгляд, работать через промежуточные классы несколько неудобно. Но использование класса СMultiLock необходимо, если вы хотите следить за состоянием сразу нескольких объектов).

Заключение

Игнорируя возможности многозадачности, которые предоставляет Windows, вы игнорируете преимущества этой операционной системы. Как вы могли убедиться, многозадачность – это вовсе не так сложно, как кажется на первый взгляд.

  • Читать дальше
  • 1
  • ...
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: