Нужно ли синхронизировать доступ к РУЧКЕ в Windows?

У меня есть РУЧКА на таймер ожидания которые могут использоваться многими запущенными потоками в моей службе Windows для таких API, как CreateWaitableTimer, WaitForSingleObject, SetWaitableTimer а также CancelWaitableTimer.

Мой вопрос заключается в том, нужно ли синхронизировать доступ (чтение / запись) к самому РУЧКУ через мьютекс или критическую секцию?

РЕДАКТИРОВАТЬ: Хорошо, я думаю, мне нужно уточнить (с кодом):

//Say, I have a global handle
HANDLE ghWaitableTimer = NULL;      //Originally set to NULL

...

//Thread one
if(!ghWaitableTimer)
{
ghWaitableTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
}

...

//Thread two
if(ghWaitableTimer)
{
::SetWaitableTimer(ghWaitableTimer, &liWhen, 0, NULL, NULL, FALSE);
}

...

//Thread three
if(ghWaitableTimer)
{
::WaitForSingleObject(ghWaitableTimer, INFINITE);
}

Или мне нужно сделать это:

//Say, I have a global handle
HANDLE ghWaitableTimer = NULL;      //Originally set to NULL
CRITICAL_SECTION CriticalSection;   //Must be initialized before it's used

...

//Thread one
::EnterCriticalSection(&CriticalSection);

if(!ghWaitableTimer)
{
ghWaitableTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
}

::LeaveCriticalSection(&CriticalSection);

...

//Thread two
::EnterCriticalSection(&CriticalSection);
HANDLE hTimer = ghWaitableTimer;
::LeaveCriticalSection(&CriticalSection);

if(hTimer)
{
::SetWaitableTimer(hTimer, &liWhen, 0, NULL, NULL, FALSE);
}

...

//Thread three
::EnterCriticalSection(&CriticalSection);
HANDLE hTimer = ghWaitableTimer;
::LeaveCriticalSection(&CriticalSection);

if(hTimer)
{
::WaitForSingleObject(hTimer, INFINITE);
}

-6

Решение

Синхронизация необходима только для чтения глобальной переменной из нескольких потоков, если значение этой переменной может измениться. Если вы создаете один объект таймера, и значение дескриптора никогда не меняется после этого, вам не нужна синхронизация для считывания его значения.

1

Другие решения

С помощью ожидаемые таймеры, т.е. запуск таймера с заданным дескриптором таймера и ожидание запуска с этим дескриптором, не должны поддерживаться мьютексами и т. д.

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

Если этого недостаточно для рассуждений, здесь первое предложение страницы Синхронизация объектов:

Объект синхронизации — это объект, дескриптор которого можно указать в
одна из функций ожидания для координации выполнения нескольких
потоки.

…и подкатегории упомянутой страницы, например. Мьютекс, Семафор,
а также Таймер ожидания; все на одном уровне.

тем не мение, то, что я только что сказал, действительно только для его использования, как описано в первом предложении. Общим для этих действий является то, что у вас уже есть дескриптор таймера (который не изменяется указанными действиями). Создание новый дескриптор таймера и присвоение его переменной изменяет значение переменной …

Итак, у вас есть две проблемы:
1) Как вы думаете, что произойдет, если поток 2 запускает таймер до того, как поток 1 его создал? Что произойдет, если вы введете какой-то текст в Visual Studio перед запуском Visual Studio? Правильно.
2) Дескриптор — это просто числовой идентификатор, который можно копировать и перемещать сколько угодно. Даже после создания таймер не может защитить свою собственную ручку. Внесение каких-либо изменений в ручку во время использования — это плохо.

Для этой цели мьютекс тоже не является решением. Он может защитить дескриптор таймера, но кто защищает дескриптор мьютекса …? Правильно. Любой механизм синхронизации зависит от готовности до используется для синхронизации всего

Реальное решение вашей проблемы — создать таймер и присвоить его ручке. до вы начинаете любую тему; затем предоставить дескриптор запущенным потокам (параметр или глобальная переменная и т. д.)

1

По вопросам рекламы [email protected]