Windows Очереди Таймера API и вопрос безопасности потока - PullRequest
0 голосов
/ 28 января 2020

По сути, мое приложение использует Windows очереди таймеров для создания таймера, который будет вызываться каждые 50 миллисекунд с использованием CreateTimerQueueTimer (ссылка ниже).

Вот краткий обзор функции, которая будет вызываться при вызове таймера:

// Set up the timer
CreateTimerQueueTimer(timerHandle, NULL, foo, NULL, 20, 20, WT_EXECUTEDEFAULT);
//…
//...
// Timer callback
void foo(void* param, BOOLEAN b)
{
    static bool doing_timer_func = false;
    if (!doing_timer_func) 
    {
        doing_timer_func = true;
        MyType *p = reinterpret_cast<MyType*>(param); 
        CallSomeFunction();  // This function may take more than 50 ms.
    }
    doing_timer_func = false;
}

Я утверждаю, что следующий код (даже если он запускается как однопоточное приложение) небезопасен с точки зрения гарантии того, что doing_timer_func логическое значение всегда предотвращает проблемы повторного входа. Несмотря на то, что bool, кажется, "делает работу", в целом код выглядит безопасным, но так ли это?

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

Поскольку таймеры, используемые здесь, являются объектами синхронизации, у меня всегда было представление, что для защиты от чего-либо неожиданного приложение должно использовать надлежащие примитивы синхронизации (мьютекс, критическая секция, SRWLocks и т. д.) 1027 *.), А не просто логическая переменная (и).

Я здесь не прав, а код действительно безопасный?

Дополнительная информация:

Используется компилятор - Visual Studio 2010.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...