Я искал в Интернете некоторые технические подробности о блокировке ввода-вывода и неблокирующих ввода-вывода, и я обнаружил, что несколько человек заявили, что неблокирующий ввод-вывод будет быстрее блокировки ввода-вывода. Например, в этом документе.
Если я использую блокировку ввода-вывода, то, конечно, поток, который в настоящий момент заблокирован, не может ничего сделать... Потому что он заблокирован. Но как только поток начинает блокироваться, ОС может переключиться на другой поток, а не переключиться обратно, пока не будет что-то делать для заблокированного потока. Итак, если в системе есть еще один поток, который нуждается в процессоре и не заблокирован, не должно быть больше времени простоя процессора по сравнению с неблокирующим подходом, основанным на событиях, есть ли?
Кроме сокращения времени, в течение которого процессор находится в режиме ожидания, я вижу еще один вариант увеличения количества задач, которые компьютер может выполнять в заданные временные рамки: уменьшите накладные расходы, связанные с переключением потоков. Но как это можно сделать? И накладные расходы достаточно велики, чтобы показать измеримые эффекты? Вот идея о том, как я могу представить работу:
- Чтобы загрузить содержимое файла, приложение делегирует эту задачу на фреймворк ввода-вывода на основе событий, передавая функцию обратного вызова вместе с именем файла
- Структура событий делегирует операционную систему, которая программирует контроллер DMA на жестком диске для записи файла непосредственно в память
- Структура событий позволяет запускать следующий код.
- По завершении копирования с диска на память контроллер DMA вызывает прерывание.
- Обработчик прерываний операционной системы уведомляет фреймворк ввода-вывода о событии о том, что файл полностью загружен в память. Как оно это делает? Использование сигнала
- Выполняется код, который в настоящее время выполняется внутри фреймворка ввода/вывода.
- Платформа ввода-вывода на основе событий проверяет свою очередь и видит сообщение операционной системы с шага 5 и выполняет обратный вызов, полученный на шаге 1.
Как это работает? Если это не так, как это работает? Это означает, что система событий может работать без необходимости явно касаться стека (например, реального планировщика, который должен был бы создать резервную копию стека и скопировать стопку другого потока в память при переключении потоков)? Сколько времени это фактически спасает? Есть ли еще больше?