LINUX.ORG.RU

Асинхронный ввод/вывод средствами операционной системы

 ,


0

2

Всем здравствуйте.

Посмотрел я на API богомерзкой .NET – и там в классе System.IO.File есть семейство методов Read...Async, возвращающих task<T> либо от массива байт (byte[]), либо от строки (string). Заводить фоновый поток исполнения (хоть managed, хоть native – неважно) не требуется. На оффтопике всё это работает через т. наз. Overlapped_I/O, и я предполагаю, что в рамках проектов .NET Core и Mono то же самое API правильно портировано на Linux и BSD.

А потом я посмотрел на реализацию java.nio.channels.AsynchronousFileChannel (и наследников) в стандартной библиотеке Java – и там, наоборот, при создании канала ввода/вывода нужно либо предоставить свой фоновый пул потоков (внутри ExecutorService), либо использовать пул по умолчанию.

И то, и другое означает, что, если к вашему сервису придёт миллион китайцев, то либо китайцы будут ждать, либо сервис ляжет с OOME, не справившись с созданием стотысячного потока.

И вот тут напрашивается вопрос – а почему? Почему в Java нельзя было сделать так же, как в .NET? Ведь есть:

  • kernel-accelerated AIO, O_DIRECT и epoll в Linux;
  • I/O Completion Ports в AIX и Solaris;
  • kqueue() и kevent() в BSD и Mac OS X;
  • наконец, POSIX AIO, стандартное для всех ОС.
★★★★★

Заводить фоновый поток исполнения (хоть managed, хоть native – неважно) не требуется

А event loop где крутится?

no-such-file ★★★★★
()
Ответ на: комментарий от no-such-file

А event loop где крутится?

В том-то и дело, что нигде. Фоновые потоки не создаются.

У тебя на руках – отложенное вычисление (это Task<T>, Future<T> или Deferred<T>), но задачу по выполнению этого вычисления берёт на себя ОС.

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

В упомянутых мной низкоуровневых API, в общем-то, используется та же самая обстракция.

Bass ★★★★★
() автор топика

/me пошел по classpath и уткнулся в

/**
 * "Portable" implementation of AsynchronousFileChannel for use on operating
 * systems that don't support asynchronous file I/O.
 */

public class SimpleAsynchronousFileChannelImpl
    extends AsynchronousFileChannelImpl
{ ... }

* Смотреть комментарий

/me удивился, пошел в гугл и нагуглил по словам «AsynchronousFileChannel SimpleAsynchronousFileChannelImpl» это:

https://stackoverflow.com/questions/3955250/why-filechannel-in-java-is-not-non-blocking

А теперь разрешаю смеяться.

anonymous
()
Ответ на: комментарий от anonymous

Спасибо.

Про sun.nio.ch.WindowsAsynchronousFileChannelImpl не знал, посмотрю. Что характерно, он реализует интерфейс Iocp.OverlappedChannel.

Ну и за статью тоже спасибо. Но статья всё-таки про неблокирующий ввод/вывод (non-blocking I/O), а мой вопрос про асинхронный (AIO). Это две разные вещи.

Bass ★★★★★
() автор топика
Последнее исправление: Bass (всего исправлений: 2)

Кстати, тж показательно вот это обсуждение восьмилетней давности: Real async file IO on Linux?

Bass ★★★★★
() автор топика

Ты не путаешь файлы с сокетами? Если ты на диск отправишь миллион запросов, то он у тебя в любом случае будет ждать. Оптимальная скорость работы со средним SSD это около 32 потоков. Больше - смысла нет. Если у тебя хитрый рейд, можно больше, но всё равно не намного. Да и то тестить надо. С HDD скорей всего намного меньше будет. А сокеты жава нормально реализует. Не надо упарываться в асинхронность на каждый чих. Где-то это имеет смысл, где-то нет.

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 2)
Ответ на: комментарий от Bass

Это две разные вещи

Можешь это обосновать?

По-моему этотодно и то же. Ну то есть, имея первое и реализуя некий планировщик, ты получаешь второе.

WitcherGeralt ★★
()

Мне кажется, ты че-то попутал. Пул потоков создается и ждёт запросы, они приходят и раскидываются по тредам этого пула, без создания треда на каждый запрос. А в дотнет можно без отдельных потоков в одном потоке крутить евентлуп и в нём асинхронно создавать таски по обслуживанию входящего соединения. Как в дотнет делается также и в libuv, и в node.js, libevent, asyncio; но поизводительность такого решения будет меньше, нежели с отдельным пулом потоков, которые запущены и ждут обработку запроса; как они ждут - через семафоры или событиями event loop - я не в курсе.

menangen ★★★★★
()
Последнее исправление: menangen (всего исправлений: 1)

Netty смотрел?

dave ★★★★★
()
Ответ на: комментарий от Iron_Bug

Обычно использую нормальные технологии, в котором IO неблокирующий из коробки, тот же дотнет, жс или го, а не вручную какие-то отдельные потоки создают.

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

Какие-то потоки зачастую создать проще, чем всю программу переводить на коллбеки. В go просто создали абстракции, поэтому всё так «просто» кажется, в конечном счёте всё-равно приходится возиться то с каналами, то с async-await, то с синхронизациями и семафорами, на хелло вордах всё просто, а на деле везде свои плюсы - минусы есть. В том же libuv и go всё-равно под капотом создаются потоки под ввода-вывода.

menangen ★★★★★
()
Ответ на: комментарий от nikolnik

в песочницах пользуются тем, что дали. ну а в обычном программировании можно невозбранно создавать потоки :)

Iron_Bug ★★★★★
()
Ответ на: комментарий от Iron_Bug

В го можно планировщику прикреплять рутину к определенному треду, что, в принципе, почти эквивалентно созданию треда ручками в жаве. Но это очень редкий кейс и для ввода-вывода этого никто не делает, потому, что весь ввод-вывод в го асинхронный, реализованный через epoll, kqueue и aio на соответствующих платформах.

nikolnik ★★★
()
Ответ на: комментарий от Bass

То что ты хочешь будет через год по-умолчанию, сейчас реализацией файберов занимается Project Loom. Уже есть готовый прототип, но заюзать его в продакшен-реди JDK ты не сможешь, только в тестовых билдах.

По сабжу с твоим task<T>, наверняка всё это уже реализовано в Spring. Погугли по «Spring Project Reactor AsynchronousFileChannel» или что-то такое.

По мне так вся эта асинхронщина - зло, поэтому по памяти кусок кода на Реакторе не напишу, а если разбираться - ну ты лучше меня это сделаешь, лол.

Олсо, я почти перестал заглядывать на ЛОР, т.к. считаю что администрация решила окончательно угробить ресурс, а как говорит эпиграф Арни Мишо к фильму «Мертвец» с Джонни Деппом, «Желательно не путешествовать с мертвецом». Прости за задержку с ответом, короче.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Ответ на: комментарий от crutch_master

Погляди на talks. Там могильник, жопновзрывающих тем нет, даже на hackernews и то веселее. А был период, когда в толксах было весело, треш угар и содомия. Так что они не то чтобы его «гробят», а угробили окончательно.

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

Спасибо, Олег.

За «Мертвеца» плюс тебе в карму =)

Bass ★★★★★
() автор топика
Ответ на: комментарий от crutch_master

Ну почему же не задевает. Непрерывный срач на Хабре задевает, люблю его (написал статью про Котлин). Непрерывный срач в фейсбуке задевает (пару дней назад написал, почему мы в России всегда будем жить плохо, там в комментариях прям пир духа - раз, два. И такое постоянно!). Обличения, взаимное кидание говном друг в друга в фоллоуап-постах, обещания подать в суд за экстримизм, пиздюли IRL, проваленное собеседование - в общем, огонь, всё как я люблю. В толксах это всё было, но несколько лет назад. Современный состав модераторов-аутистов неспособен на настоящий огонь. Нужно чтобы у участников тредов жопы горели и взрывались, а это совершенно специальный майндсет.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.