Linux и порты завершения ввода-вывода?

Используя winsock, вы можете настроить сокеты или отдельные операции ввода-вывода для «перекрытия». Это означает, что вызовы для выполнения ввода-вывода возвращаются немедленно, в то время как фактические операции выполняются асинхронно отдельными рабочими потоками.

Winsock также предоставляет «порты завершения». Насколько я понимаю, порт завершения действует как мультиплексор дескрипторов (сокетов). Дескриптор может быть демультиплексирован, если он не находится в середине операции ввода-вывода, т.е. если все его операции ввода-вывода завершены.

Итак, переходя к моему вопросу ... поддерживает ли Linux порты завершения или даже асинхронный ввод-вывод для сокетов?


person someguy    schedule 08.05.2010    source источник
comment
epoll - это самый быстрый метод Linux для написания серверов. Обратите внимание, что Linux в настоящее время занимает большую долю рынка Интернет-серверов, чем Windows.   -  person unixman83    schedule 20.02.2012
comment
@ unixman83: я знаю об epoll. Мне было просто любопытно, потому что есть упоминание о поддержке асинхронного ввода-вывода в Linux, но я не совсем уверен, была ли поддержка сокетов в частности (что подтвердила BlackAura). Кстати, epoll не всегда может быть лучшим решением (см. sheddingbikes.com/posts/1280829388 .html).   -  person someguy    schedule 20.02.2012
comment
Порты завершения не предназначены для мультиплексирования сокетов. Они идеально подходят для одиночного сокета или файлового дескриптора. Они представляют собой механизм параллелизма данных. Их цель - позволить нескольким потокам обрабатывать данные, полученные асинхронно из сокета или файла. Они также используются в реализациях пула потоков, таких как .NET.   -  person Ron Inbar    schedule 21.07.2017


Ответы (6)


Итак, переходя к моему вопросу ... поддерживает ли Linux порты завершения или даже асинхронный ввод-вывод для сокетов?

Что касается сокетов, то в ядрах версии 5.3 и более поздних Linux имеет нечто подобное портам завершения в виде io_uring (для файлов В ядре 5.1 появилась поддержка / блочных устройств io_uring).

person Anon    schedule 28.04.2020

Если вы ищете что-то в точности как IOCP, вы его не найдете, потому что его не существует.

Windows использует модель уведомления о завершении (отсюда и порты ввода-вывода Завершение). Вы запускаете некоторую операцию асинхронно и получаете уведомление, когда эта операция завершена.

Приложения Linux (и большинство других Unix-подобных) обычно используют модель уведомления о готовности. Вы получите уведомление о том, что сокет может быть прочитан или записан без блокировки. Затем вы выполняете операцию ввода-вывода, которая не блокируется.

В этой модели вам не нужен асинхронный ввод-вывод. Данные немедленно копируются в / из буфера сокета.

Модель программирования для этого довольно сложна, поэтому существуют библиотеки абстракции, такие как libevent. Он обеспечивает более простую модель программирования и абстрагирует различия реализации между поддерживаемыми операционными системами.

В Windows также есть уведомление о готовой модели (выберите или WSAWaitForMultipleEvents), которое вы, возможно, уже видели раньше. Он не может масштабироваться до большого количества сокетов, поэтому не подходит для высокопроизводительных сетевых приложений.

Пусть это вас не смущает - Windows и Linux - совершенно разные операционные системы. То, что плохо масштабируется в одной системе, может хорошо работать в другой. Этот подход действительно очень хорошо работает в Linux, с производительностью, сопоставимой с IOCP в Windows.

person BlackAura    schedule 12.05.2010
comment
Любой синхронный ввод-вывод будет блокироваться, пока вы пишете больше данных, чем может вместить буфер. И если данные, которые вы пишете, были выгружены, ваш процесс заблокируется из-за ошибки страницы. - person Gabe; 15.08.2010
comment
@BlackAura: Разве WSAAsyncSelect не будет поддерживать большое количество сокетов в Windows с моделью уведомления о готовности? По общему признанию, я не использовал его с большим количеством сокетов, но поскольку дескриптор сокета передается как параметр события, и нет битовой маски или массива сокетов для запроса, похоже, что он должен великолепно масштабироваться. - person Ben Voigt; 19.03.2011
comment
@Ben Voigt Проблема с WSAAsyncSelect заключается в том, что он построен на API оконных процедур. Его цикл обработки сообщений медленный по сравнению с другими функциями опроса. Необходимость обрабатывать тысячи сокетов может значительно снизить производительность вашей программы. Кстати, а что у вас там нет битовой маски? Вам еще нужно передать флаги. - person someguy; 19.03.2011
comment
@someguy: Под отсутствием битовой маски я подразумеваю отсутствие использования FD_SET, как это сделано в select. Кроме того, WSAAsyncSelect требует использования очереди сообщений потока, а не API оконных процедур. Вполне возможно перехватить эти сообщения в цикле сообщений и не передавать их через DispatchMessage и код оконной процедуры. - person Ben Voigt; 19.03.2011
comment
@Ben Voigt О, да, ты прав насчет сообщений в очереди. Однако вам все равно придется проводить опрос с использованием GetMessage. Я хочу сказать, что он медленный по сравнению с другими функциями опроса. Я не слишком много знаю об этом, но мне сказали, что WSAAsyncSelect не очень хорошо масштабируется. - person someguy; 20.03.2011
comment
@BlackAura, модели совсем не разные. Асинхронный WSARecv () с 0-байтовым буфером является уведомлением о готовности, как и epoll_wait (). С высокой степенью уверенности (и в зависимости от размера получаемых вами буферов) следующий WSARecv с размером ›0 не будет блокироваться, поскольку байты уже кэшированы Winsock. - person Vladislav Vaintroub; 09.10.2011
comment
@Vladislav Vaintroub: WSARecv() возвращает 0, если операция ввода-вывода была запланирована; это не означает, что сокет готов к этой операции. Кроме того, любое значение, отличное от 0, означает, что произошла ошибка. - person someguy; 20.02.2012
comment
@someguy, GetQueuedCompletionStatus возвращается, когда WSARecv () с 0 байтами завершается, что означает готовность к работе. Я так понимаю - в соединении есть хотя бы один байт, который можно прочитать без блокировки - person Vladislav Vaintroub; 21.02.2012
comment
... или возникла ошибка. GetQueuedCompletionStatus () сравнима с epoll_wait (), а асинхронный 0 байтов WSARecv () сравним с epoll_ctl () с флагами EPOLL_CTL_MOD | EPOLLIN | EPOLLET | EPOLLONESHOT - person Vladislav Vaintroub; 21.02.2012
comment
@Vladislav Vaintroub: WSARecv() планирует выполнение операции ввода-вывода. Когда операция завершена, GetQueuedCompletionStatus() вернется. Посмотрите различия между событиями готовности и событиями завершения. - person someguy; 21.02.2012
comment
Не думаю, что когда-либо отрицал это. Вы должны понимать, что операция WSARecv () 0 байтов эквивалентна началу наблюдения за готовностью. GetQueuedCompletionStatus в этом случае говорит, что да, что-то можно прочитать из сокета. Это уведомление о готовности по фронту, полностью эквивалентное приведенному выше примеру epoll_ctl / epoll_wait. И epoll не отправляет уведомление о завершении - person Vladislav Vaintroub; 21.02.2012

IOCP произносится как «асинхронный ввод-вывод» на различных платформах UNIX:

person D.Shawley    schedule 08.05.2010
comment
Спасибо. Есть ли шанс предоставить мне образцы кодов? Раньше я заглядывал в POSIX AIO, но не нашел ничего, связанного с сокетами. - person someguy; 08.05.2010
comment
Раньше я не использовал POSIX AIO. Я просто знаю, что это обсуждалось на разных форумах. Лично я использую системы на основе BSD, поэтому я использовал для этого Kqueue. Я бы посмотрел на использование Boost или какой-либо реализации MPI для одновременного ввода-вывода, если это то, что вам нужно. - person D.Shawley; 08.05.2010
comment
Я изучил POSIX AIO и Kernel AIO, и оба, похоже, подразумевают, что нет настоящей поддержки сокетов, что очень досадно. Я собираюсь предположить, что все документы, которые я прочитал, устарели, поскольку Java 7, очевидно, будет поддерживать асинхронный ввод-вывод, поэтому в Linux он должен быть или будет, верно? Может быть, я попробую взглянуть на то, что уже сделали Sun / Oracle. - person someguy; 09.05.2010
comment
Похоже, что POSIX AIO не получил должного внимания. Возможно, вы захотите прочитать некоторые ссылки на Fast UNIX Servers (dank.qemfd.net/dankwiki/index.php/Fast_UNIX_Servers). Кажется, там много хорошей информации. - person D.Shawley; 09.05.2010
comment
асинхронный ввод-вывод содержит ошибки и плохо поддерживается большинством Unix! Остерегаться - person unixman83; 20.02.2012
comment
Мне сказали, что завершение портов (IOCP) намного быстрее, чем epoll / select, но в Linux теперь есть io_uring, ведь это версия IOCP для Linux. - person Scott 混合理论; 28.02.2021

Используйте boost :: asio. Руки вниз. У него умеренная кривая обучения, но он кроссплатформенный и автоматически использует лучший доступный метод для системы, на которой вы компилируете. Просто нет причин не делать этого.

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

person Ken Smith    schedule 19.08.2011
comment
+1 Я ненавижу ASIO из-за чрезмерного использования пространств имен, но должен согласиться с тем, что это бесплатная библиотека высочайшего качества, которая полностью поддерживает ОБЕ Windows И Linux. Libevent с другой стороны, имеет дрянную, незаконченную поддержку Windows. - person unixman83; 20.02.2012

Прочтите запись в блоге Google на libevent, вы можете реализовать семантику IOCP в Unix, используя асинхронный ввод-вывод, но не можете напрямую реализовать семантику асинхронного ввода-вывода с помощью IOCP,

http://google-opensource.blogspot.com/2010/01/libevent-20x-like-libevent-14x-only.html

В качестве примера кросс-платформенного асинхронного ввода-вывода с API-интерфейсом сокета BSD посмотрите ZeroMQ, недавно опубликованный на LWN.net,

http://www.zeromq.org/

LWN статья,

http://lwn.net/Articles/370307/

person Steve-o    schedule 10.05.2010
comment
Я не думаю, что libevent поддерживает асинхронный ввод-вывод, и на связанной странице даже сказано, что он предназначен для неблокирующих сокетов. Думаю, позже я займусь этим глубже. 0MQ тоже интересен, но я не думаю, что это то, что я ищу. Кажется, это библиотека для передачи сообщений (похожая на актеров erlang?) - person someguy; 10.05.2010
comment
@someguy асинхронный ввод-вывод включает в себя неблокирующие сокеты. - person jweyrich; 11.05.2010

Boost ASIO реализует IOCP (шаблон проектирования Proactor) в стиле Windows в Linux с использованием epoll (шаблон Reactor). См. http://think-async.com/Asio/asio-1.5.3/doc/asio/overview/core/async.html.

person Roshan    schedule 22.08.2012
comment
Было бы более полезно процитировать и резюмировать эту страницу из предоставленной ссылки, поскольку произойдет гниение ссылки, и пользователи будут щелкать по ней, чтобы в какой-то момент найти 404. - person t0mm13b; 06.10.2012