Именованный канал в окнах, разница между FILE_FLAG_OVERLAPPED и PIPE_NOWAIT - PullRequest
0 голосов
/ 10 ноября 2018

Я использую именованный канал в Windows и запутался в разнице между FILE_FLAG_OVERLAPPED и PIPE_NOWAIT, которые являются параметрами, установленными в CreateNamedPipe, я устанавливаю параметры следующим образом.

HANDLE hPipe = CreateNamedPipe(
    lpszPipename,             // pipe name 
    PIPE_ACCESS_DUPLEX |      // read/write access 
    FILE_FLAG_OVERLAPPED,     // overlapped mode 
    PIPE_TYPE_MESSAGE |       // message-type pipe 
    PIPE_READMODE_MESSAGE |   // message read mode 
    PIPE_WAIT,                // blocking mode 
    PIPE_UNLIMITED_INSTANCES, // unlimited instances 
    BUFSIZE * sizeof(TCHAR),    // output buffer size 
    BUFSIZE * sizeof(TCHAR),    // input buffer size 
    PIPE_TIMEOUT,             // client time-out 
    NULL);                    // default security attributes

ConnectNamedPipe немедленно возвращаются, и я получаю ERROR_IO_PENDING от GetLastError. С дескриптором неблокирующего ожидания, операция подключения немедленно возвращает ноль, а функция GetLastError возвращает ERROR_IO_PENDING. Однако MSDN сообщает: При использовании дескриптора ожидания без блокировки операция соединения немедленно возвращает ноль, а функция GetLastError возвращает ERROR_PIPE_LISTENING . Итак, что означает nonblocking-wait, PIPE_NOWAIT или FILE_FLAG_OVERLAPPED, большое спасибо!

1 Ответ

0 голосов
/ 10 ноября 2018

PIPE_NOWAIT означает, что неблокирующий режим включен на ручке. В этом режиме ReadFile, WriteFile и ConnectNamedPipe всегда завершено немедленно.

Значение FILE_FLAG_OVERLAPPED означает, что асинхронный режим включен на дескрипторе. Если этот режим включен, все не синхронно io [1] операции всегда немедленно возвращают .

так FILE_FLAG_OVERLAPPED против PIPE_NOWAIT - это возврат немедленно против завершено немедленно.

завершено немедленно (что включает возврат немедленно) означает, что операция io уже завершена при возврате API. но наоборот не соответствует действительности. если операция возвращает немедленно, это не означает, что операция завершена уже. если операция еще не завершена ntapi код возврата STATUS_PENDING. Win32 API в таких ситуациях обычно устанавливает последнюю ошибку на ERROR_IO_PENDING.

существует 3 способа определения завершения операции ввода-вывода в случае асинхронного режима обработки.

  1. привязать ручку к IOCP (через CreateIoCompletionPort или BindIoCompletionCallback или CreateThreadpoolIo). как результат, когда io complete - указатель на OVERLAPPED, который мы передаем io call - будет поставлен в очередь на IOCP (в случае BindIoCompletionCallback или CreateThreadpoolIo Система самостоятельно создайте IOCP и прослушайте ее и вызов нашего зарегистрированного обратного вызова, когда указатель на OVERLAPPED будет быть в очереди на IOCP )
  2. некоторые Win32 API, такие ReadFileEx или WriteFileEx и все Ntapi пусть указать процедуру завершения APC, которая будет вызываться в контексте поток, который начинает работу io, когда операция io завершена. В этом случае поток должен делать предупреждающее ожидание. это ожидание не совместим с дескриптором связывания IOCP вызов API, если дескриптор файла привязан к IOCP - системный возврат недействителен ошибка параметра)
  3. мы можем создать событие и передать его вызову API (через OVERLAPPED::hEvent) - в этом случае это событие будет сброшено система, когда начинается операция IO, и устанавливается в сигнальное состояние, когда IO операция завершена. в отличие от первых 2 вариантов в этом случае мы имеем нет дополнительного контекста (в указателе лица на OVERLAPPED) при вводе операция завершена. обычно это худший вариант.

[1] существует несколько операций ввода-вывода, которые всегда синхронны API. например GetFileInformationByHandleEx, SetFileInformationByHandle. но почти io операции не являются синхронными io. все эти операции ввода-вывода принимают указатель на OVERLAPPED в качестве параметра. так что если в подписи API нет указателя на OVERLAPPED - это синхронный вызов API. если существует - обычно асинхронный (исключение CancelIoEx, например, когда указатель на перекрытие связан не с текущей операцией, а с предыдущей операцией ввода-вывода, которую мы хотим отменить). в частности ReadFile, WriteFile, DeviceIoControl, ConnectNamedPipe (внутренне это вызов DeviceIoControl с FSCTL_PIPE_LISTEN)) не является синхронным io api

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