Как JavaScript никогда не блокирует? [Дубликат]

Вы хотите группу захвата .

p = re.compile("name (.*) is valid", re.flags) # parentheses for capture groups
print p.match(s).groups() # This gives you a tuple of your matches.

296
задан Ry- 8 March 2018 в 14:27
поделиться

7 ответов

Функция c.query () имеет два аргумента

c.query("Fetch Data", "Post-Processing of Data")

. Операция «Fetch Data» в этом случае является DB-Query, теперь это может обрабатываться Node.js путем нереста рабочий поток и задание этой задачи выполнения DB-Query. (Помните, что Node.js может создавать поток внутри). Это позволяет функции мгновенно возвращаться без задержки

Второй аргумент «Постобработка данных» - это функция обратного вызова, инфраструктура узла регистрирует этот обратный вызов и вызывается циклом события.

Таким образом, инструкция c.query (paramenter1, parameter2) вернется мгновенно, позволяя узлу обслуживать другой запрос.

PS: Я только начал понимать узел, на самом деле я хотел написать это как комментарий к @Philip , но так как не хватало очков репутации, так написал это как ответ.

345
ответ дан Community 16 August 2018 в 06:46
поделиться
  • 1
    Последующие вопросы: как происходит процесс ввода-вывода? Узел делает запрос в систему и просит получить уведомление, когда он будет завершен. Так же работает ли система, выполняющая ввод-вывод, или система также выполняет асинхронное выполнение ввода-вывода на аппаратном уровне с помощью прерываний? Что-то где-то должно ждать завершения ввода-вывода, и это будет заблокировано до тех пор, пока оно не будет выполнено и не будет потреблять некоторое количество ресурсов. – Philip 13 November 2013 в 21:24
  • 2
    Просто заметили, что на следующий комментарий ответили @ user568109 ниже, я хотел бы, чтобы был способ объединить эти два ответа. – lfalin 30 December 2014 в 02:04
  • 3
    Хотелось бы, чтобы вы могли написать ответ в два раза больше, поэтому я бы понял в два раза лучше. – Rafael Eyng 11 May 2015 в 04:40
  • 4
    Узел поддерживается во многих местах, для записи. Когда я разрабатывал прошивку для маршрутизаторов MIPS32, Node.JS можно было запускать с помощью OpenWRT. – Qix 26 May 2015 в 01:56
  • 5
    Как он забивает за Apache? Apache также способен обрабатывать параллельные соединения с отдельным потоком. – Suhail Gupta 4 May 2016 в 05:44

Node.js основан на модели программирования цикла событий. Цикл событий работает в одном потоке и многократно ждет событий, а затем запускает любые обработчики событий, подписанные на эти события. События могут быть, например,

  • . Ожидание таймера завершено
  • следующий фрагмент данных готов к записи в этот файл
  • theres новый новый HTTP request coming our way

Все это выполняется в одном потоке, и код JavaScript никогда не выполняется параллельно. Пока эти обработчики событий малы и ждут еще большего количества событий, все работает хорошо. Это позволяет нескольким запросам обрабатываться одновременно одним процессом Node.js.

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

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

event loop high level view [/g1]

В соответствии с: «Контур события из 10 000 фут-ядра концепция за Node.js ".

345
ответ дан Community 16 August 2018 в 07:50
поделиться
  • 1
    Последующие вопросы: как происходит процесс ввода-вывода? Узел делает запрос в систему и просит получить уведомление, когда он будет завершен. Так же работает ли система, выполняющая ввод-вывод, или система также выполняет асинхронное выполнение ввода-вывода на аппаратном уровне с помощью прерываний? Что-то где-то должно ждать завершения ввода-вывода, и это будет заблокировано до тех пор, пока оно не будет выполнено и не будет потреблять некоторое количество ресурсов. – Philip 13 November 2013 в 21:24
  • 2
    Просто заметили, что на следующий комментарий ответили @ user568109 ниже, я хотел бы, чтобы был способ объединить эти два ответа. – lfalin 30 December 2014 в 02:04
  • 3
    Хотелось бы, чтобы вы могли написать ответ в два раза больше, поэтому я бы понял в два раза лучше. – Rafael Eyng 11 May 2015 в 04:40
  • 4
    Узел поддерживается во многих местах, для записи. Когда я разрабатывал прошивку для маршрутизаторов MIPS32, Node.JS можно было запускать с помощью OpenWRT. – Qix 26 May 2015 в 01:56
  • 5
    Как он забивает за Apache? Apache также способен обрабатывать параллельные соединения с отдельным потоком. – Suhail Gupta 4 May 2016 в 05:44
345
ответ дан Community 6 September 2018 в 04:23
поделиться

Хорошо, чтобы дать некоторую перспективу, позвольте мне сравнить node.js с apache.

Apache - это многопоточный HTTP-сервер, для каждого запроса, который получает сервер, он создает отдельный поток который обрабатывает этот запрос.

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

Когда A и B принимаются на apache, два потока которые обрабатывают запросы. Каждый обрабатывает запрос отдельно, каждый из которых ожидает результатов запроса перед обслуживанием страницы. Страница выполняется только до тех пор, пока запрос не будет завершен. Извлечение запроса блокируется, потому что сервер не может выполнить оставшуюся часть потока до получения результата.

В узле c.query обрабатывается асинхронно, что означает, что c.query извлекает результаты для A, это перескакивает для обработки c.query для B, и когда результаты приходят для A, он отправляет результаты для обратного вызова, который отправляет ответ. Node.js знает, как выполнить обратный вызов при завершении выборки.

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

На самом деле сервер узлов делает именно это для вас все время.

Редактировать

SQL-запрос берется из библиотеки mysql . Для выполнения переключателей (асинхронное поведение) большинство функций, которые будут использоваться, будут иметь обратные вызовы. Он реализует стиль обратного вызова, а также эмитент событий для запросов SQL в очереди. Он не выполняет их асинхронно, что выполняется внутренними потоками libuv , которые обеспечивают абстракцию неблокирующего ввода-вывода. Для выполнения запроса выполняются следующие шаги:

  1. Открыть соединение с db, само соединение может быть выполнено асинхронно.
  2. Как только db подключен, запрос передается на сервер. Запросы могут быть поставлены в очередь.
  3. Основной цикл события получает уведомление о завершении с обратным вызовом или событием.
  4. Основной цикл выполняет ваш обработчик обратного вызова / события.

Обрабатываемые запросы на HTTP-сервер обрабатываются аналогичным образом. Архитектура внутреннего потока выглядит примерно так:

node.js event loop [/g3]

Потоки C ++ - это libuv, которые выполняют асинхронный ввод-вывод (диск или сеть). Цикл основного события продолжает выполняться после отправки запроса в пул потоков. Он может принимать больше запросов, так как он не ждет и не спит. SQL-запросы / HTTP-запросы / файловая система читают все, что происходит.

191
ответ дан Bruno Gomes 16 August 2018 в 06:46
поделиться
  • 1
    Диаграмма очень полезна. – Anmol Saraf 26 November 2014 в 14:46
  • 2
    Подождите, так что на диаграмме у вас есть «внутренний C ++ поток», что означает, что все операции блокировки ввода-вывода будут порождать поток, не так ли? Итак, если приложение Node выполняет некоторую работу IO для каждого запроса , разве нет никакой разницы между моделью узла и моделью Apache? Я не получаю эту часть извинения. – gav.newalkar 27 January 2015 в 06:17
  • 3
    @ gav.newalkar Они не порождают нить, запросы ставятся в очередь. Потоки в threadpool обрабатывают их. Нити не являются динамическими и для каждого запроса, как в Apache. Они обычно фиксируются и отличаются от системы к системе. – user568109 27 January 2015 в 07:58
  • 4
    @ user568109 Но Apache также использует threadpool ( httpd.apache.org/docs/2.4/mod/worker.html ). Итак, в конце разница между установкой с node.js отличается от одной с Apache впереди только в том месте, где находится threadpool, не так ли? – Kris 10 April 2016 в 15:59
  • 5
    Эта диаграмма должна быть на первой странице официальных документов. – bouvierr 5 June 2016 в 15:42

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

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

в вашем примере: есть два запроса A (на первом месте) и B. вы выполняете запрос A, ваш код продолжает работать синхронно и выполняет запрос B. event loop обрабатывает запрос A, когда он заканчивается, он вызывает обратный вызов запроса A с результатом, то же самое относится к запросу B.

2
ответ дан Gal Ben-Haim 16 August 2018 в 06:46
поделиться
  • 1
    "Конечно, на бэкэнд есть потоки и процессы для доступа к БД и выполнения процесса. Тем не менее, они явно не подвержены вашему коду & quot; . Если я беру из этой фразы, то я не вижу никакой разницы между тем, что делает Node или какой-либо многопоточной инфраструктурой, скажем, Spring Framework Spring. Есть темы, но вы не контролируете их создание. – Rafael Eyng 12 May 2015 в 23:38

Хорошо, большинство вещей должно быть ясным до сих пор ... сложной частью является SQL: если она на самом деле не работает в другом потоке или процессе во всей полноте, SQL-исполнение должно быть разбито на отдельные этапы (с помощью процессора SQL, выполненного для асинхронного выполнения!), где выполняются неблокирующие, а блокирующие (например, спящий) на самом деле могут переноситься в ядро ​​(в качестве прерывания / событие) и поместить в список событий для основного цикла.

Это означает, например, интерпретация SQL и т. д. выполняется немедленно, но во время ожидания (хранится как событие, которое должно появиться в будущем ядром в некоторой структуре kqueue, epoll, ... вместе с другими операциями ввода-вывода) основной цикл может делать другие вещи и, в конечном счете, проверять, произошло ли что-то из этих IO и ждет.

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

Удалить? : -)

Я не знаю Узел. Но откуда берется c.query?

1
ответ дан Robert Siemer 16 August 2018 в 06:46
поделиться
  • 1
    kqueue epoll предназначен для масштабируемого асинхронного уведомления ввода-вывода в ядре linux. У узла есть libuv для этого. Узел полностью находится в пользовательском пространстве. Это не зависит от того, что реализует ядро. – user568109 16 November 2013 в 16:21
  • 2
    @ user568109, libuv - средний человек Узел. Любая асинхронная структура зависит (напрямую или нет) от некоторой поддержки асинхронного ввода-вывода в ядре. Так? – Robert Siemer 17 November 2013 в 03:59
  • 3
    Извините за путаницу. Операции сокета требуют неблокирующего ввода-вывода из ядра. Он выполняет асинхронную обработку. Но асинхронный ввод / вывод файлов обрабатывается самим libuv. Ваш ответ об этом не говорит. Он обрабатывает как то же самое, обрабатывается ядром. – user568109 17 November 2013 в 10:44
  • 4
    @ user568109, вы правы – Robert Siemer 17 November 2013 в 15:43

Node.js использует libuv за кулисами. libuv имеет пул потоков (по умолчанию размер 4). Поэтому Node.js использует потоки для достижения параллелизма.

Однако ваш код работает в одном потоке (т. Е. Все обратные вызовы функций Node.js будут вызываться тот же поток, так называемый loop-thread или event-loop). Когда люди говорят, что «Node.js работает на одном потоке», они действительно говорят «обратные вызовы Node.js запускаются в одном потоке».

34
ответ дан Tiago 16 August 2018 в 06:46
поделиться
  • 1
    Короткий, но четкий ответ (y) – Sudhanshu Gaur 24 July 2017 в 15:03
  • 2
    Хороший ответ Я бы добавил, что ввод / вывод происходит за пределами этого основного цикла событий, loop-thread, request-thread – Ionut Popa 2 January 2018 в 14:39
  • 3
    это ответ на то, что я искал с 2 часов, как управлялся параллелизм в однопоточном приложении – Muhammad Ramzan 12 January 2018 в 16:27
  • 4
    да, трудно получить ответ «следующего уровня». Это объясняет, где фактически выполняется IO (в пуле потоков в другом месте) – Oliver Shaw 4 February 2018 в 21:23
Другие вопросы по тегам:

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