Что такое перекрывающийся ввод-вывод, альтернатива WaitNamedPipe?

ФункцияWaitNamedPipeпозволяет клиентскому приложению канала синхронно ожидать доступного соединения на сервере именованного канала. Затем вы вызываетеCreateFile , чтобы открыть канал в качестве клиента. Псевдокод:

// loop works around race condition with WaitNamedPipe and CreateFile
HANDLE hPipe;
while (true) {
    if (WaitNamedPipe says connection is ready) {
        hPipe = CreateFile(...);
        if (hPipe ok or last error is NOT pipe busy) {
            break; // hPipe is valid or last error is set
        }
    } else {
        break; // WaitNamedPipe failed
    }
}

Проблема в том, что все это блокирующие синхронные вызовы. Каков хороший способ сделать это асинхронно? Например, я не могу найти API, который использует перекрывающийся ввод-вывод для этого.Например, для каналов серверовфункцияConnectNamedPipeпредоставляет параметры lpOverlapped, позволяющие серверу асинхронно ожидать клиента. Затем сервер канала может вызвать WaitForMultipleObjectsи дождаться завершения операции ввода-вывода или любого другого события, которое будет сигнализировано (например, событие, сигнализирующее потоку об отмене ожидающего ввода-вывода и завершении).

Единственный способ, который я могу придумать, это вызвать WaitNamedPipeв цикле с коротким конечным временем ожидания и проверить другие сигналы, если время ожидания истекло. В качестве альтернативы, в вызове цикла CreateFile, проверьте другие сигналы, а затем вызовите Sleepс небольшой задержкой (или WaitNamedPipe). Например:

HANDLE hPipe;
while (true) {
    hPipe = CreateFile(...);
    if (hPipe not valid and pipe is busy) {
        // sleep 100 milliseconds; alternatively, call WaitNamedPipe with timeout
        Sleep(100);
        // TODO: check other signals here to see if we should abort I/O
    } else
        break;
}

Но этот метод, на мой взгляд, вонючий. Если канал недоступен в течение некоторого времени, поток продолжает работать — загружая ЦП, потребляя энергию, требуя, чтобы страницы памяти оставались в ОЗУ и т. д. На мой взгляд, поток, который полагается на Sleepили короткие тайм-ауты плохо работают и являются признаком неаккуратного многопоточного программирования.

Но какая в этом случае альтернатива?

6
задан James Johnston 26 March 2012 в 19:40
поделиться