Нужно ли устанавливать hEvent в структуре OVERLAPPED при выполнении портов завершения ввода-вывода?

Я использую порты завершения ввода-вывода в Windows для связи через последовательный порт (потенциально у нас будет очень много использования последовательного порта). Я сделал обычное дело, создав IOCP, раскрутив потоки ввода/вывода и связав мой дескриптор CreateFile() с IOCP (CreateFile() вызывался с FILE_FLAG_OVERLAPPED). Это все работает нормально. Я установил COMMTIMEOUTS для всех на 0, кроме ReadIntervalTimeout, для которого установлено значение MAXDWORD, чтобы быть полностью асинхронным.

В моем потоке ввода-вывода я заметил, что GetQueuedCompletionStatus() блокируется на неопределенный срок. Я использую тайм-аут INFINITE. Поэтому я поставил вызов ReadFile() сразу после того, как свяжу свой дескриптор с IOCP. Теперь это приводит к тому, что GetQueuedCompletionStatus() по какой-то причине немедленно освобождается с переданным 0 байтов, но ошибок нет (он возвращает true, GetLastError() сообщает 0). Я, очевидно, хочу, чтобы он блокировался, если ему нечего делать. Если я поставлю еще один ReadFile() после GetQueuedCompletionStatus(), то другой поток в пуле подхватит его с переданным 0 байтов и без ошибок.

В примерах, которые я видел и которым я следовал, я не вижу, чтобы кто-то устанавливал hEvent в структуре OVERLAPPED при использовании IOCP. Это необходимо? Я не хочу когда-либо блокировать потоки IOCP, поэтому меня никогда не заинтересует CreateEvent(...) | 1.

Если это не обязательно, что может быть причиной проблемы? GetQueuedCompletionStatus() необходимо заблокировать, пока данные не поступят на последовательный порт.

Есть ли хорошие примеры последовательного порта IOCP? Я не нашел полный пример последовательного порта + IOCP. Большинство из них предназначены для розеток. Теоретически он должен работать для последовательных портов, файлов, сокетов и т. д.


person dhoyt    schedule 02.06.2011    source источник


Ответы (1)


Я понял - я не вызывал SetCommMask() с EV_RXCHAR | EV_TXEMPTY, а затем WaitCommEvent() со структурой OVERLAPPED. После того, как я это сделал, мои потоки IOCP вели себя так, как ожидалось. GetQueuedCompletionStatus() возвращается, когда в порту появляется новый символ. Тогда я мог бы позвонить ReadFile().

Итак, чтобы ответить на исходный вопрос: «нет, вам не нужно устанавливать hEvent для IOCP с последовательными портами».

person dhoyt    schedule 03.06.2011
comment
Я понимаю, что это очень старый пост. Мне интересно, можете ли вы опубликовать пример. У меня есть IOCP, работающий для сокетов, и я использую те же классы, специфичные для IOCP, для последовательных портов. Я не могу заставить его работать. Передачи в порядке, но я не могу заставить работать события приема. Я пробовал комбинации (и различный порядок) для ReadFile(), SetCommMask() и WaitCommEvent(), но мне не удалось сделать это правильно. - person Ken; 10.12.2017