Вопрос по java, sockets, c# – Как реализован неблокирующий ввод-вывод?

15

В Java или C # или некоторых других языках существуют неблокирующие средства ввода-вывода, например, для сокетов.

Поэтому я могу передать свои функции обратного вызова неблокирующему IO, и как только неблокирующий IO получит что-либо, он вызовет мои обратные вызовы.

Мне интересно, как они реализованы. Если я создаю неблокирующий ввод-вывод за кулисами, Java или C # просто создают фоновые потоки для них? или ОС, лежащая в основе, имеет их собственную поддержку?

@mellamokb говорит, что контекст выполнения кэшируется и используется повторно, он ничего не говорит о потоке. Chris Shain
Смотрите замечания здесь:msdn.microsoft.com/en-us/library/dxkwh6zw.aspx, Кажется, он использует фоновый поток, который кэшируется, если тот же контекст используется повторно. mellamokb

Ваш Ответ

1   ответ
18

В Windows имеется базовая поддержка ОС для неблокирующего ввода-вывода, и Microsoft CLR использует это преимущество. Другие реализации CLR (моно), вероятно, делают то же самое, но я не знаю наверняка. При выполнении асинхронного ввода-вывода в Microsoft CLR не существует корреляции 1: 1 между ожидающими операциями асинхронного ввода-вывода и потоками (или, по крайней мере, управляемыми потоками), ожидающими завершения этих операций ввода-вывода.

Увидетьhttp://msdn.microsoft.com/en-us/library/windows/desktop/aa365683(v=vs.85).aspx для некоторых деталей о деталях слоя Win32. Также информация о портах завершения ввода / вывода здесь:http://msdn.microsoft.com/en-us/library/aa365198(VS.85).aspx

Мое понимание таково:

  1. I begin an async I/O operation on some application thread.
  2. If it hasn't already, a queue will be created (well, really a kernel-level construct called an I/O completion port, which is associated with a queue in the kernel space of my application). In the .NET world a specially designated thread called an I/O completion port thread will start waiting for notifications of I/O completion on that queue. The important thing to note here is that I can make any number of async I/O requests without increasing the number of I/O completion ports.
  3. The OS will notify the application when I/O completes by enqueueing an I/O completion message on the queue. The I/O completion port thread will then handle that message by invoking the I/O completion callback in my .NET application. In the meantime, if other I/O completes, it's results will be enqueued behind the currently-processing results.

Предостережения к вышесказанному:

  1. I am sure I got part of this wrong, but I believe the overall gist of it is correct. Eric or someone can come in and correct me where I'm off.

  2. In .NET there are multiple I/O completion port threads. I have no idea how async I/O requests are allocated amongst the various I/O completion ports. This may be an operating system feature (wherein I/O may come back on any port that the application has open).

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

РЕДАКТИРОВАТЬ: историческое обновление, много больше деталейВот

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Jack
Error: User Rate Limit ExceededFor C# there is underlying OS support...Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы