Как win32 управляет экземплярами структуры OVERLAPPED в контексте двух функций:
GetQueuedCompletionStatus
PostQueuedCompletionStatus
Когда я вызываю GetQueuedCompletionStatus, win32 освобождает экземпляр структуры OVERLAPPED или я должен сделать это сам?
Когда я отправляю данные с помощью PostQueuedCompletionStatus, win32 копирует их во внутренние структуры? Когда я должен освободить память отправленных данных?
Где я мог найти какую-то картинку со схемой обработки ПЕРЕКРЫТЫХ данных между GetQueuedCompletionStatus, PostQueuedCompletionStatus и очередью IOCP?
OVERLAPPED
структура должна существовать с момента успешной операции ввода-вывода (или вручную PostQueuedCompletionStatus ()) выполняется до OVERLAPPED
выходит из звонка GetQueuedCompletionStatus ().
Вы несете ответственность за срок службы структуры.
Из документов MSDN вы увидите, что GetQueuedCompletionStatus()
фактически принимает «указатель на переменную, которая получает адрес OVERLAPPED
структура, которая была указана при запуске завершенной операции ввода-вывода. «. Что вы фактически получаете из этого вызова, так это указатель на оригинал OVERLAPPED
что вы прошли, когда вы сделали PostQueuedCompletionStatus()
вызов (или инициировал перекрывающуюся операцию ввода / вывода).
Все это на самом деле очень полезно, поскольку «нормальный» способ использования OVERLAPPED
структура состоит в том, чтобы поместить ее в более крупную структуру, которая содержит всю информацию «на операцию», которая может вам понадобиться, — так что это идеальный способ перейти непосредственно от ограниченной информации, которую вы получаете при вызове GetQueuedCompletionStatus()
например, к буферу данных, который вы использовали в перекрывающемся вызове чтения …
Я нахожу лучший способ справиться с OVERLAPPED
структура состоит в том, чтобы: а) встраивать их в буфер, который вы используете для чтения / записи; б) подсчитывать ссылки и с) возвращать их в пул для повторного использования, когда количество ссылок падает до 0.
У меня есть исходный код, который вы можете скачать (Вот) что может немного облегчить понимание (это полный пример сервера IOCP, поэтому он немного сложен, но он работает и показывает, как эти вещи можно использовать).
OVERLAPPED *
в GetQueuedCompletionStatus
, Это заполняется значением, переданным PostQueuedCompletionStatus
, PostQueuedCompletionStatus
контекст. Это должно быть сделано с помощью контекста GetQueuedCompletionStatus
, (Предполагая, что он был выделен динамически в первую очередь — не требуется, чтобы это была динамически размещаемая структура, он мог быть извлечен из фиксированного пула или размещен в стеке функции, которая не возвращает, пока не получит было сообщено, что операция завершена).