Как стать автором
Обновить

Комментарии 16

Благодарю! Первое вменяемое объяснение асинхронности в Node.JS: таки создаётся пул потоков, в в котором выполняются неблокирующие операции. И самая понятная картинка:


image


А мне тут на хабре некоторые товарищи, которые сами не до конца всё поняли, упорно пытались доказать, что потоки тут не причём, а просто Node.js использует неблокирующие возможности ввода/вывода ОС. Только мне было не понятно тогда как работает неблокирующий IO, например, по сети и т.п. и почему, если потоки таки используются, не дать такую же возможность разработчику, какую имеет сам node.


С появлением worker-ов такая возможность по счастью появилась. Отсюда вопрос: не появилась ли уже в ноде какая-та удобная обёртка async/await по аналогии с C# для выполнения любой необходимой функции в потоке для неблокирующего вызова await по типу async Task<class> Function(Args)?

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

Тут проблема, скорее всего в том, что сам JS однопоточный. По крайней мере был на момент написания NodeJS. То есть в нем не было предусмотрено какого-то правила одновременного доступа к переменной из нескольких потоков.

Зато ему не нужно аналога сложнейшей Java Memory Model. Но за это на разработчика перекладывается ответственность, чтобы все вычислительно сложные операции (которые долго именно считаются) он отправлял в worker threads.

Вообще, это очень интересная борьба: потоки vs event loops. Задача, которую они решают — одна и та же: эффективное разделение ресурсов между задачами. То самое «чтобы ничего не простаивало». Если посмотреть на это в исторической перспективе, то видно, что операционные системы конструировались тоже для решения именно этой задачи. Сначала они были однопользовательскими, потом придумали, как сделать так, чтобы на одном мэйнфрейме работали одновременно много пользователей, не мешая друг другу. И для этого использовалась именно абстракция «потока», поддержанная на уровне железа центрального процессора (стэк + регистры, относящиеся именно к текущему потоку, и переключение контекста, когда процессор переключается на другой «поток»)

Эту возможность выторчали в API и дали приложениям прикладного уровня ее использовать. Чем и воспользовалась Java, и долгое время на этом ехала (сейчас же они уже пилят реактивный стэк WebFlux с одной стороны, и Project Loom с другой)

Но потом оказалось, что если думать об эффективности, то переключение контекста — дорогая операция, поток — тоже дорогой и тяжелый объект (больше 10000 потоков запускать на одном процессоре уже тяжело). И в поисках более эффективных подходов родился nginx, а потом и nodejs.
Отсюда вопрос: не появилась ли уже в ноде какая-та удобная обёртка async/await по аналогии с C# для выполнения любой необходимой функции в потоке для неблокирующего вызова await по типу async Task Function(Args)?

К сожалению, пока такой возможности нет.

Может в npm-ах что-то уже сделали?

там накладные расходы на передачу данных в поток и обратно высокие. но вообще, конечно есть пара либ
там накладные расходы на передачу данных в поток и обратно высокие.

Но можно же опять как в libuv сделать — пул потоков. Вроде в C# так и сделано.


но вообще, конечно есть пара либ

Какие?

Хорошие, спасибо, сохраню себе. threads смотрел раньше, вроде она ещё без worker-ов была в ноде.

Интересная тоже.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Спасибо, очень полезно! Я правильно понимаю, что потоков будет создано ровно столько, сколько одновременных запросов поступит на сортировку массива? Если да, то есть ли возможность ограничить это число X?

А почему пидормота который написал эту статью еще не пристрелили?
Ну тоесть сорри. От того что осмысленного примера применения многопоточности не увидел =//
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории