#c #mfc
#c #mfc
Вопрос:
В простом приложении MFC мне нужно иметь рабочий поток, который постоянно опрашивает ioctl на предмет события. Сначала я попытался добиться этого, используя неперекрывающийся ioctl внутри цикла while. Я понял, что если ioctl не завершит запрос ввода-вывода немедленно, поток передаст управление или переключение контекста другому потоку (основному потоку или циклу управления сообщениями MFC), но вместо этого он блокирует приложение.
Во второй попытке я использую overlapped, и проблема исчезла. Но мне кажется, что эти два метода идентичны по поведению, поскольку я использую WaitForSingleObject, который ожидает запуска события (завершения запроса ввода-вывода).
Базовая компоновка следующая. Обратите внимание, что следующий код является неполным и показывает только конструкцию
Синхронный:
WaitForIo {
do {
DeviceIoControl(hDevice,ioctl_code, ..., NULL);
do something after io request completed
} while(1);
return;
}
Асинхронный:
WaitForIo {
do {
Overlapped ov;
//CreateEvent
DeviceIoControl(hDevice,ioctl_code, ..., amp;ov);
WaitForSingleObject
do something after io request completed
} while(1);
}
почему два метода ведут себя по-разному? Что-то не так в моей логике?
Комментарии:
1. Каким образом они ведут себя по-разному?
2. Один блокирует приложение, а другой нет
3. Я бы хотел, чтобы вы публиковали реальный код вместо этой псевдокодовой ерунды. Однако я рискну предположить: во втором фрагменте вы не открывали устройство с
FILE_FLAG_OVERLAPPED
помощью,amp;ov
аргумент игнорируется, событие никогда не получает сигнал, и ожидание никогда не выполняется, оставляя поток замороженным навсегда, не потребляя процессорного времени.4. Кроме того, что именно означает «он блокирует приложение»? На моем компьютере потоки вытесняются, если они выполняются слишком долго.
5. I метод, который использует перекрывающуюся структуру, не блокирует первый метод (синхронный), и hDevice создается с помощью FILE_FLAG_OVERLAPPED .
Ответ №1:
Если он блокирует поток, это означает, что вам нужно вернуть процессор, переведя его в спящий режим или что-то в этом роде. WaitForSingleObject делает именно это по умолчанию, когда вы его вызываете. Я не уверен в этом, но я думаю, что ввод null в функцию DeviceIoControl заставил ее ждать, сохраняя контроль над потоком, и поэтому блокирует поток.