В чем разница между событийной архитектурой Node.js и многопоточным программированием на других языках?


Ответ 1:

Как в управляемой событиями, так и в многопоточной парадигме код выполняется внутри процесса операционной системы.

Когда процесс запускает несколько потоков, эти потоки совместно используют память процесса (адресное пространство) как для чтения, так и для записи.

JavaScript, поддерживающий Node.js, является однопоточным. Каждая функция гарантированно выполняется до конца, и никакой другой код JavaScript в текущем процессе не будет выполняться во время выполнения этой функции. Естественно асинхронные события (сеть, дисковый ввод-вывод, таймеры, другое оборудование и события операционной системы) обрабатываются механизмом, который добавляет функции JavaScript, зарегистрированные как обработчики (или обратные вызовы) для этих событий, в очередь цикла событий, которая будет выполнена после функции перед очередью завершены.

В многопоточной парадигме два или более потоков выполняют код параллельно, поэтому во время выполнения функции другой фрагмент кода может также выполняться на другом ядре процессора, возможно, читая или записывая по одним и тем же адресам памяти. Это может привести к несовместимому состоянию памяти, если код не использует специальные механизмы операционной системы (примитивы синхронизации) для управления доступом к общей памяти.



Ответ 2:

Это хороший вопрос: «В чем разница между управляемой событиями архитектурой Node.js и многопоточным программированием на других языках?».

Мы можем и должны это немного сломать.

  • Событийная архитектура Node.

Управляемая событиями архитектура не является эксклюзивной для Node, например, Tornado (Python), Vertx (Java), Akka (Scala), ReactiveX (несколько языков).

  • Многопоточное программирование на других языках.

Обратите внимание, что JavaScript по своему дизайну не поддерживает несколько потоков. Хотя он поддерживает веб-работников, которые, насколько я знаю, могут функционировать как потоки.

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

Таким образом, здесь может быть два вопроса: «В чем разница между событиями и многопоточностью» и «В чем разница между Node и другими языками (фреймворками)». Я сосредоточусь на последнем, так как это, похоже, является целью вопроса.

Я бы сказал, что делает Node особенным, потому что автор создал его с целью избежать блокировки ввода-вывода при создании веб-приложений. Культура сообщества Node состоит в том, чтобы подчеркивать и укреплять силу неблокирующего ввода-вывода. Вы не найдете слишком много сторонних библиотек, которые выполняют блокировку вызовов. Как разработчик, использующий Node, вы вряд ли столкнетесь с тонкими операциями блокировки в вашем коде. В то время как на других языках наивный разработчик может случайно выполнить крайне неэффективные блокирующие вызовы, такие как чтение из соединения с базой данных.

Кроме этого, вы должны действительно прочитать о нескольких моделях «параллелизма» и понять плюсы и минусы каждой из них. Бонусные баллы за понимание того, почему многопоточность была приемлемой в течение столь длительного времени.



Ответ 3:

концептуальные различия довольно легко обернуть вокруг.

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

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

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