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.
Функция 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 , но так как не хватало очков репутации, так написал это как ответ.
Node.js основан на модели программирования цикла событий. Цикл событий работает в одном потоке и многократно ждет событий, а затем запускает любые обработчики событий, подписанные на эти события. События могут быть, например,
Все это выполняется в одном потоке, и код JavaScript никогда не выполняется параллельно. Пока эти обработчики событий малы и ждут еще большего количества событий, все работает хорошо. Это позволяет нескольким запросам обрабатываться одновременно одним процессом Node.js.
(В то время как события происходят немного, под капотом немного магии. Некоторые из них связаны с параллельными рабочими потоками низкого уровня. )
В этом случае SQL происходит много событий (событий) между созданием запроса базы данных и получением его результатов в обратном вызове. За это время цикл событий продолжает накачивать жизнь в приложении и продвигать другие запросы по одному крошечному событию за раз. Поэтому несколько запросов подаются одновременно.
[/g1]
В соответствии с: «Контур события из 10 000 фут-ядра концепция за Node.js ".
Хорошо, чтобы дать некоторую перспективу, позвольте мне сравнить 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 , которые обеспечивают абстракцию неблокирующего ввода-вывода. Для выполнения запроса выполняются следующие шаги:
- Открыть соединение с db, само соединение может быть выполнено асинхронно.
- Как только db подключен, запрос передается на сервер. Запросы могут быть поставлены в очередь.
- Основной цикл события получает уведомление о завершении с обратным вызовом или событием.
- Основной цикл выполняет ваш обработчик обратного вызова / события.
Обрабатываемые запросы на HTTP-сервер обрабатываются аналогичным образом. Архитектура внутреннего потока выглядит примерно так:
[/g3]
Потоки C ++ - это libuv, которые выполняют асинхронный ввод-вывод (диск или сеть). Цикл основного события продолжает выполняться после отправки запроса в пул потоков. Он может принимать больше запросов, так как он не ждет и не спит. SQL-запросы / HTTP-запросы / файловая система читают все, что происходит.
, если вы читаете немного дальше: «Конечно, на сервере есть потоки и процессы для доступа к БД и выполнения процесса. Однако они явно не подвержены действию вашего кода, поэтому вы не можете беспокоиться о них другим чем, зная, что взаимодействия ввода-вывода, например, с базой данных или с другими процессами, будут асинхронными с точки зрения каждого запроса, поскольку результаты этих потоков возвращаются через цикл событий в ваш код ».
about - «все работает параллельно, кроме вашего кода» - ваш код выполняется синхронно, всякий раз, когда вы вызываете асинхронную операцию, такую как ожидание ввода-вывода, цикл событий обрабатывает все и вызывает обратный вызов. это просто не то, о чем вам нужно подумать.
в вашем примере: есть два запроса A (на первом месте) и B. вы выполняете запрос A, ваш код продолжает работать синхронно и выполняет запрос B. event loop обрабатывает запрос A, когда он заканчивается, он вызывает обратный вызов запроса A с результатом, то же самое относится к запросу B.
Хорошо, большинство вещей должно быть ясным до сих пор ... сложной частью является SQL: если она на самом деле не работает в другом потоке или процессе во всей полноте, SQL-исполнение должно быть разбито на отдельные этапы (с помощью процессора SQL, выполненного для асинхронного выполнения!), где выполняются неблокирующие, а блокирующие (например, спящий) на самом деле могут переноситься в ядро (в качестве прерывания / событие) и поместить в список событий для основного цикла.
Это означает, например, интерпретация SQL и т. д. выполняется немедленно, но во время ожидания (хранится как событие, которое должно появиться в будущем ядром в некоторой структуре kqueue, epoll, ... вместе с другими операциями ввода-вывода) основной цикл может делать другие вещи и, в конечном счете, проверять, произошло ли что-то из этих IO и ждет.
Итак, чтобы перефразировать его снова: программа никогда не (заводится) застревать, сонные вызовы никогда не выполняются. Их долг выполняется ядром (пишите что-нибудь, ждите, что что-то придет через сеть, ожидая времени, чтобы пройти) или другого потока или процесса. - Процесс узла проверяет, завершено ли по крайней мере одна из этих обязанностей ядром в единственном блокирующем вызове ОС один раз в каждом цикле цикла событий. Эта точка достигнута, когда все неблокирование выполнено.
Удалить? : -)
Я не знаю Узел. Но откуда берется c.query?
Node.js использует libuv за кулисами. libuv имеет пул потоков (по умолчанию размер 4). Поэтому Node.js использует потоки для достижения параллелизма.
Однако ваш код работает в одном потоке (т. Е. Все обратные вызовы функций Node.js будут вызываться тот же поток, так называемый loop-thread или event-loop). Когда люди говорят, что «Node.js работает на одном потоке», они действительно говорят «обратные вызовы Node.js запускаются в одном потоке».