Windows перекрывает ввод-вывод и ввод-вывод в отдельном потоке

В Windows, когда вы выполняете ввод-вывод, вы можете сделать это асинхронно, используя параметр OVERLAPPED. Есть ли разница между этим и синхронным вводом-выводом в другом потоке? Если да, то что лучше? ОС просто порождает отдельный поток в асинхронном случае или просто ставит его в очередь в потоке драйвера и отправляет сигнал вместо ожидания блока?

Спасибо!


person user1181950    schedule 04.09.2014    source источник
comment
Операционная система почти наверняка не порождает новые потоки только для обслуживания вашего перекрывающегося запроса ввода-вывода. Найдите порты завершения ввода-вывода, которые на самом деле требуют, чтобы вы предоставили свои собственные потоки для извлечения уведомлений о завершении из порта завершения ввода-вывода. То, как именно Windows это делает, является деталью реализации, но в силу того, что это операционная система, она может выполнять некоторые трюки, помимо порождения потоков.   -  person In silico    schedule 04.09.2014
comment
У меня были смешанные результаты с асинхронным вводом-выводом, особенно с вызовом WriteFile. Некоторые операции WriteFile, вызванные с флагом OVERLAPPED, фактически блокируются, а не возвращаются немедленно. Как бы я ни хотел, чтобы перекрывающийся ввод-вывод работал, это только добавляло сложности коду, поскольку мне все еще приходилось опрашивать/ждать завершения перекрывающейся операции... В конце концов, подход создания потока был на самом деле проще в реализации и не вызывает никаких побочных эффектов. YMMV. Создайте прототип и измерьте, чтобы подтвердить ожидаемые преимущества — результаты могут вас удивить.   -  person selbie    schedule 04.09.2014


Ответы (2)


Ввод-вывод Windows по своей природе асинхронный, поэтому выполнение асинхронной операции в .NET, например, не должен использовать поток, после завершения операции некоторые существующие потоки ненадолго заимствуются для уведомления о завершении операции, но потоки не создаются.

Это сильно отличается от запуска синхронной операции в другом потоке. Он использует поток, который делает программу гораздо менее масштабируемой. В .NET поток имеет локальное хранилище по умолчанию 1 МБ, поэтому тысячи запущенных потоков будут потреблять гигабайты памяти. Затем у вас также есть дополнительные затраты на переключение между потоками, которые обычно невелики, но могут складываться, если у вас много потоков.

person NeddySpaghetti    schedule 04.09.2014
comment
Обратите внимание, что по умолчанию асинхронные методы .NET в FileStream используют поток. Вы можете указать isAsync: true в его конструкторе, чтобы получить FileStream, который вместо этого использует перекрывающийся ввод-вывод, но кажется, что в наиболее распространенных сценариях использования это работает хуже, чем многопоточный ввод-вывод по умолчанию. Итак, по умолчанию в .NET в пользовательском пространстве есть поток. Теперь, поскольку он использует ThreadPool, стоимость создания потока амортизируется, и размер стека не будет проблемой из-за рабочих очередей, а автоматическая настройка размера пула обычно позволяет избежать тысяч потоков. - person binki; 10.07.2018

Согласно центру разработки MSDN, «асинхронный ввод-вывод также называется перекрывающимся вводом-выводом», кроме того, далее говорится, что асинхронный ввод-вывод обрабатывается ядром, по сути, другим потоком. Не знаю, как вы, но если мне не нужно что-то писать, то я не буду... Это мое правило ленивого программиста №1.

person Steve    schedule 04.09.2014
comment
хорошо, учитывая, что у меня есть пул потоков для других целей, а синхронный ввод-вывод намного проще закодировать, чем OVERLAPPED IO, я могу просто добавить его в поток в своем пуле. Но мне было интересно, есть ли какая-либо польза от использования OVERLAPPED по сравнению с просто перебрасыванием в другой поток... - person user1181950; 04.09.2014
comment
На этот вопрос ответил stackoverflow.com/questions/3050621/ говорит, что нет большой разницы в скорости, однако человек делает заявления, используя асинхронность в пуле потоков, ваше приложение может обрабатывать произвольное количество операций ввода-вывода звонки, например, на сервер. - person Steve; 04.09.2014