Синхронный ввод-вывод поддерживает поток занятым? - PullRequest
1 голос
/ 06 июня 2019

Скажем, я делаю ввод / вывод в синхронном сокете ввода / вывода, который готов к операции read или write.Это означает, что вызывающий поток не будет заблокирован в операции, независимо от неблокирующей (SOCK_NONBLOCK) / блокирующей природы сокета.Но следующие вещи мне не ясны -

  1. Когда происходит фактический перевод?Данные уже присутствуют в памяти, когда сокет помечен как готовый к чтению, или данные будут переданы при вызове команды read?Зависит ли это от семейства сокета ?
  2. Если передача данных выполняется во время команды read , означает ли это, что вызывающий поток будет заняти задержка будет зависеть от аппаратного обеспечения сокета?

Обновление:

С аппаратным обеспечением сокета я ошибся, я думал о реальных данныхпередача под.Я понимаю, что Socket не имеет значения, это просто сущность в ОС для обозначения файлового дескриптора, пригодного для связи.

Дополнительный вопрос - это также означает, что во время write вызывающий поток записывает данные в память.Есть ли поток ядра, который позаботится о передаче данных на другую сторону сокета?Если да, то чем асинхронный ввод-вывод для сокетов отличается от синхронного ввода-вывода?

1 Ответ

2 голосов
/ 06 июня 2019

В целом вы можете думать о сокетах ввода / вывода как о двухуровневой системе буферизации.В вашем приложении есть буфер, а затем - буферы ядра.Поэтому, когда вы вызываете read (), ядро ​​копирует данные из буфера (ов) ядра в буфер вашего приложения.Соответственно, когда вы вызываете write (), вы копируете данные из буфера приложения в буфер (ы) ядра.

Затем ядро ​​говорит NIC записывать входящие данные в буферы ядра и считывать исходящие данные.из буферов ядра.Этот ввод-вывод выполняется AFAIK, как правило, на основе DMA. Это означает, что ядру просто нужно сообщить NIC, что делать, и NIC отвечает за фактическую передачу данных.И когда NIC завершается, он вызывает прерывание (или для высоких скоростей ввода-вывода, прерывания отключаются, а ядро ​​вместо этого опрашивает), в результате чего ядро ​​ЦП, получившее прерывание, перестает выполнять все, что оно выполняло (код пользователя, код ядра(если прерывания отключены, в этом случае прерывание будет поставлено в очередь)) и выполнить обработчик прерываний, который затем позаботится о других шагах, которые необходимо выполнить.

Итак, чтобы ответить на ваш дополнительный вопрос, в общемэто не отдельный ввод / вывод сокета обработки потока ядра на стороне ядра, работа выполняется оборудованием NIC и в контексте прерывания.

Для асинхронного ввода-вывода или, скорее, неблокирующего ввода-вывода,единственное отличие состоит в том, как выполняется копирование из буфера пользовательского приложения и буфера (ов) ядра.Для неблокирующего чтения в пользовательское пространство копируются только те данные, которые готовы и ожидают в буферах ядра (что может привести к короткому чтению), или, если данные не готовы, вызов read () немедленно возвращается с EAGAIN.Точно так же для неблокирующей записи () он копирует только столько данных, сколько имеется доступного пространства в буферах ядра, что может вызвать короткую запись или, если пространство вообще не доступно, при возврате с EAGAIN.Для блокировки read (), если нет доступных данных, вызов будет блокироваться, пока не будет, тогда как для блокирующей write (), если буфер (ы) ядра заполнен, он будет блокироваться, пока не будет доступно некоторое пространство.

...