Вы можете легко реализовать события ручного сброса с помощью каналов:
событие в запущенном состоянии -> есть что прочитать из канала
SetEvent -> write ()
ResetEvent -> read ()
WaitForMultipleObjects -> poll () (или select ()) для чтения
операция «SetEvent» должна записать что-то (например, 1 байт любого значения), чтобы перевести канал в непустое состояние, поэтому последующая операция «Wait», то есть poll () для данных, доступных для чтения, не будет блок.
Операция «ResetEvent» считывает записанные данные, чтобы убедиться, что канал снова пуст.
Конец чтения канала должен быть неблокирующим, чтобы попытка сброса (чтение из) уже сброшенного события (пустой канал) не блокировалась - fcntl (pipe_out, F_SETFL, O_NONBLOCK)
Поскольку перед ResetEvent может быть более 1 SetEvents, вы должны закодировать его так, чтобы он читал столько байтов, сколько имеется в канале:
char buf[256]; // 256 is arbitrary
while( read(pipe_out, buf, sizeof(buf)) == sizeof(buf));
Обратите внимание, что ожидание события не считывается из канала, и, следовательно, «событие» останется в сработавшем состоянии до операции сброса.