Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Консультации по функциям WinAPI


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный ХОСТИНГ на базе Linux x64 и Windows x64

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Лучшие эксперты по данной тематике

Орловский Дмитрий
Статус: Мастер-Эксперт
Рейтинг: 7044
∙ повысить рейтинг »
Коцюрбенко Алексей aka Жерар
Статус: Советник
Рейтинг: 3992
∙ повысить рейтинг »
CradleA
Статус: Бакалавр
Рейтинг: 2057
∙ повысить рейтинг »

/ КОМПЬЮТЕРЫ И СОФТ / Программирование / WinAPI

Номер выпуска:615
Дата выхода:22.12.2013, 04:00
Администратор рассылки:Лысков Игорь Витальевич (Старший модератор)
Подписчиков / экспертов:53 / 24
Вопросов / ответов:1 / 1

Консультация # 187673: Предположим, у нас имеется единственное средство синхронизации - Event. Предложите собственную реализацию критической секции в виде следующего класса (приводится только интерфейсная часть, private-члены - на ваше усмотрение): class CriticalSection { public: CriticalSection(); ~CriticalSection(); void Lo...


Консультация # 187673:

Предположим, у нас имеется единственное средство синхронизации - Event.
Предложите собственную реализацию критической секции в виде следующего класса (приводится только интерфейсная часть, private-члены - на ваше усмотрение):

class CriticalSection
{
public:
CriticalSection();
~CriticalSection();

void Lock();
void Unlock();
};

Дата отправки: 14.12.2013, 03:39
Вопрос задал: Козлов Олег Николаевич (Посетитель)
Всего ответов: 1
Страница онлайн-консультации »


Консультирует Сандров Алекс (Студент):

Здравствуйте, Козлов Олег Николаевич!

Кривое решение, но обо всём по порядку.

1. я сделал установку и снятие критической секции(КС) в конструкторе и деструкторе класса CCriticalSection соотвественно. Стало быть, чтобы зайти в КС достаточно объявить экземпляр класса с уникальным именем KC("MyEvent" в коде) в параметрах конструктора, а чтобы выйти, нужно чтобы сработал деструктор (как вызвать деструктор в нужном месте показано ниже, на примере С4 в функции main).
Почему именно так? Во-первых, тогда не надо явно звать Unlock. Во-вторых, это удобно в программах со сложной логикой, где может быть следующая ситуация: открыли КС, а потом по условию вышли из функции, а КС закрыть забыли. Или слишком много условных выходов, и в каждом условии надо было бы не забывать ставить Unlock() перед return. Данная конструкция избавляет нас от лишнего кода и защищает от ошибок и dead-lock-а.
1.1. тут есть один очень кривой момент - когда удалять handle? Мы за ранее не знаем, кто последний из потоков будет использовать данную КС(и handle для Event внутри). Я завёл отдельный метод, который нужно звать, когда КС уже более не нужна.

2. CCriticalSection - класс КС. Методы Lock и Unlock зовуться в конструкторе и деструкторе соотвественно.
Метод Lock сначала пытается открыть Event по имени, если у него не получается (нет такого Event) он создаёт его.
Фукнция CreateEvent во втором аргументе использует FALSE - это означает, что состояние Event будет сбрасываться(освобождаться) автоматически.
Если поток не создаёт новый Event, то пытаеся получить управление над уже созданным (функция WaitForSingleObject(m_hEvent, INFINITE)), если на этом месте Event уже занят, поток впадает в ожидаение, останавливается на вызове WaitForSingleObject.
После того, как поток полочил Event в управление, он выводит сообщение об этом и выходит. После того, как поток выходит, Event автоматически освобождается, и кто-то из потоков, ждущий на Wa itForSingleObject, получит управление и продолжит свою работу.

3. Главный поток (функция main) входит в КС (CCriticalSection C4("MyEvent")) и создаёт массив потоков (CreateThread) и запоминает в массив(HANDLE hThreads[TCOUNT]). КС в данном случае создана внутри локальной зоны видимости (скобки {// 1 ... }//1), и как только выполнение выйдет за скобки, сработает деструктор C4::~CCriticalSection, который вызовет Unlock и освободит Event, и main выйдет из КС.
3.1 Ещё одно кривое место - мне пришлось использовать напрямую функцию WaitForMultipleObjects для ожидания, пока все потоки закончатся. Я бы мог использовать нашу КС, но тогда main мог захватить КС раньше других потоков, и вся программа закончилась раньше, чем потоки отработали.
3.2 main в конце создаёт ещё одну КС и зовёт CloseHandle(), так как КС больше не будет использоваться.

Проект сделан в среде MS Visual Studio 6.0.

Приложение:

Консультировал: Сандров Алекс (Студент)
Дата отправки: 20.12.2013, 07:49

5
нет комментария
-----
Дата оценки: 20.12.2013, 10:39

Рейтинг ответа:

НЕ одобряю 0 одобряю!


Оценить выпуск | Задать вопрос экспертам

главная страница  |  стать участником  |  получить консультацию
техническая поддержка  |  восстановить логин/пароль

Дорогой читатель!
Команда портала RFPRO.RU благодарит Вас за то, что Вы пользуетесь нашими услугами. Вы только что прочли очередной выпуск рассылки. Мы старались. Пожалуйста, оцените его. Если совет помог Вам, если Вам понравился ответ, Вы можете поблагодарить автора - для этого в каждом ответе есть специальные ссылки. Вы можете оставить отзыв о работе портале. Нам очень важно знать Ваше мнение. Вы можете поближе познакомиться с жизнью портала, посетив наш форум, почитав журнал, который издают наши эксперты. Если у Вас есть желание помочь людям, поделиться своими знаниями, Вы можете зарегистрироваться экспертом. Заходите - у нас интересно!
МЫ РАБОТАЕМ ДЛЯ ВАС!



В избранное