предисловие
Программирование должно стать профессией на всю жизнь, а не просто едой 30-летней молодежи.
Эта статья была включенаGitHub https://github.com/ponkans/F2E, есть расширенные руководства для производителей первого уровня, добро пожаловать в Star, продолжайте обновлять
существуетСерия "Big front end node.js" является асинхронной, неблокирующей (вкл.)В , Вейгуай показал всем отморозкам асинхронной неблокировки и рассказал о множестве концептуальных деталей, о которых вы, возможно, раньше не догадывались.
В этом выпуске мы возвращаемся к модели асинхронного ввода-вывода Node. Прежде чем начать, мы зададим несколько вопросов. Эта статья также будет посвящена этим вопросам.
- Какой пул резьбы?
- Как пул потоков реализует мультиплексирование потоков?
- Что такое цикл событий?
- Как Node реализует асинхронную неблокировку на основе пула потоков и цикла обработки событий?
Пул потоков
Что такое пул потоков
Начнем с первого вопроса, что такое пул резьбы.Технология часто рождается для решения проблемы, пул потоков не является исключением.
Давайте начнем с предположения сценария.
Предположим, вы посещаете онлайн-курс в Jijiayuan, и ваш начальник просит вас разработать рекомендательный сервис. Что вы делаете очень просто. Когда пользователь получает доступ к вашему сервису, вам нужно порекомендовать его в соответствии с некоторыми характеристиками пользователя (например, пол ). Например, когда Weiguai посещает, вам нужно порекомендоватьбогатая женщина.
Когда вы получаете эту задачу, первое, о чем нужно подумать, это то, что запрос каждого пользователя должен бытьнезависимая нить. потому чтоПользователь и пользователь изолированы, и то, что делает каждый поток, представляет собой серию рекомендуемых операций.
Конечно, для вас это не сложно, вы можете создавать новый поток на каждый запрос пользователя, уничтожать его после завершения ответа на запрос, и все в порядке.
Горящий гусь, потому что то, что вы рекомендовали, слишком хорошо, ребятаСайт пожар, Группа богатых женщин пытается зарегистрироваться. На этот раз проблема придет, если 1000 богатырей при нажатии, это означает, что 1000 запросов закончились, вы не собираетесь устанавливать 1000 нить это?
По окончании этой серии запросов эти темы не будут уничтожены? Создание потока — самая интуитивно понятная служебная задача.ОЗУ, влияние такого частого создания и уничтожения на производительность очевидно, и эта конструкция не может поддерживать его мгновенноепиковый трафик.
Из-за такого дизайна богатые женщины не удовлетворены, а определенный джи, джияюань находится в опасности.
В это время пул резьбы вошел. Раньше я уже говорил, рождение технологии всегда решать некоторые проблемы. В чем проблема? Резюме на самом деле является контролем жизненного цикла нити. Давайте сделаем прекрасный анализ.
Управление жизненным циклом потока
Давайте сначала рассмотрим нашу проблему, частое создание и уничтожение потоков. Каково решение? должно бытьповторное использование потока.
После создания потока, даже если это время отклика закончено, не позволяйте ему быть восстановленным, в следующий раз будет запрос, чтобы позволить ему до сих пор обрабатывать.
Ключевым моментом здесь является то, как сделатьНити не перерабатываются.
Это кажется очень волшебным, может ли нить продолжать существовать после завершения операции? Так долго долгое? Практика на самом деле очень простая, напишитебесконечная петляВот и все. Поток всегда находится в цикле.Когда есть запрос, он обрабатывает запрос.Когда нет запроса, он все время ждет.После ожидания процесс выполняется.После завершения процесса он ждет,и он прыгает неоднократно, в бесконечном цикле.
Это приводит ко второму ключевому моменту, т.Откуда вы знаете, как узнать, когда у вас есть запрос, чтобы дать ему запрос??
Методы реализации разных языков здесь не совсем одинаковы, но похожи, и должны быть основаны на блокировке пробуждения по сути. Когда задачи нет, все потоки находятся в состоянии блокировки, когда задача приходит, незадействованный поток конкурирует за задачу, захваченный поток начинает выполняться, а неполученный поток продолжает блокироваться.
Здесь вы, возможно, видели интерпретацию пула потоков различных потоков в Интернете, но если вы хотите понять это глубже, вам все равно нужноНачните с исходного кода. (Перед исходником все навороты бледны и бессильны)
дай первымИсходный код libuv threadPoolадрес:Адрес источника
Мы напрямую перехватываем основную часть реализации пула потоков, как показано на следующем рисунке, базовая реализация соответствует ожиданиям.
Проще говоря, uv_cond_signal в приведенном выше коде эквивалентен пробуждению заблокированного потока, а uv_cond_wait эквивалентен разрешению текущему потоку войти в состояние блокировки.
Сводка пула потоков
Окончательный вывод заключается в том, что пул потоков использует бесконечный цикл, чтобы сделать поток невозможным для завершения, находится в состоянии блокировки во время ожидания задачи и использует блокировку пробуждения, чтобы разрешить потоку получать задачи (по сути, блокируя пробуждение). основан на семафоре), чтобы добиться повторного использования потока и завершить текущую задачу. Затем введите следующий цикл и повторите.
eventloop
что такое цикл событий
eventloop — это именно то, что означает его название: цикл событий.
Проще говоря, на самом деле это цикл while(true). Цикл постоянно проверяет, есть ли задачи для обработки. Если есть задачи, обрабатывайте задачи. Если нет, переходите к следующему циклу.
Общий процесс выглядит следующим образом.
Идея eventloop очень проста, ему все равно, как реализован ваш callback и когда закончится операция ввода-вывода.
Он продолжал делать, это подобрать события, чтобы взять на реализацию. Что есть критическая точка, это событие, где он его берет?
ответ:watcher. В каждом цикле событий будет наблюдатель, и каждый цикл будет обращаться к наблюдателю, чтобы получить событие и выполнить его. На самом деле этот так называемый наблюдатель используется для хранения событий.queue(очередь).
Как понять этот вотчер, он дает очень яркую аналогию в nodejs.
В ресторане за регистрацию заказов гостей часто отвечает девушка на ресепшн, а на задней кухне готовит повар. Младшая сестра положит меню на кухню после получения меню от гостей, а повару нужно только постоянно читать меню, готовить, а потом читать меню и готовить. Ему было все равно, кто заказал блюдо или когда оно было заказано.
Место, где размещается меню, — это наблюдатель, который по сути представляет собой очередь. Шеф-повар подобен циклу событий, постоянно находящемуся в цикле приготовления. Каждый раунд цикла будет получать запрос в очереди. Если есть обратный вызов, обратный вызов будет выполнен.Если это так, введите следующий цикл.
цикл событий + пул потоков = асинхронный неблокирующий
Пул потоков и опрос событий более подробно описаны выше, а теперь давайте рассмотрим, как их использовать для достижения асинхронной неблокируемости.
Давайте очищать наши умы шаг за шагом. Во-первых, прекрасно, что вы делаете IO-вызов изСерия "Big Front-end Advanced Node.js" Асинхронная неблокирующаяКак упоминалось выше, вызов ввода-вывода является либо блокирующим вызовом, либо сначала инициируется неблокирующий ввод-вывод, а затем блокируется, когда необходимо увидеть результат.Очевидно, что ни один из этих двух режимов не является тем, что нам нужно.
То, что нам нужно, является асинхронным и неблокирующим, поэтому этот вызов ввода-вывода не должен выполняться в основном потоке.В настоящее время мы можем думать о пуле потоков выше.
Основной поток не может быть заблокирован, но потоки в пуле потоков могут.Основному потоку нужно только передать вызовы ввода-вывода в пул потоков для выполнения, и он может счастливо играть сам по себе, тем самым достигая нашей первой цели:неблокирующий.
ЭтоасинхронныйШерстяная ткань? Как заставить вызов в пуле потоков выполнять обратный вызов, когда он заканчивается? Здесь в игру вступает цикл событий.
После завершения обработки ввода-вывода пула потоков он будет активно помещать готовый запрос в наблюдатель цикла событий, то есть в нашей очереди цикл событий находится в состоянии непрерывного зацикливания, и в следующем цикле проверки есть запросы на очередь. , она будет извлечена, и обратный вызов будет выполнен так, чтобыасинхронныйдостиг.
В конечном счете, пул потоков и EVENTLOOP, эффект заключается в том, что когда вы инициируете вызов ввода-вывода, вам не нужно блокировать конец ввода-вывода или вам не нужно продолжать опрос, когда вы хотите использовать результаты ввода-вывода, весь ввод-вывод обработатьНеблокирующий основной потоки выполнить обратный вызов, когда он завершится автоматически, чтобы добиться желаемой асинхронной неблокировки.
Наконец, мы ссылаемся на диаграмму из «Введение в Nodejs в Simple».
Как показано на рисунке выше, после инициирования асинхронного вызова будет инкапсулирован параметр запроса, который будет включать в себя параметр и обратный вызов, который будет выполнен в конце.
этоЗапрос (запрос параметр)После инкапсуляции он будет брошен в пул потоков для выполнения.Если поток в пуле потоков свободен, он будет получать запрос в очереди пула потоков и выполнять операции ввода-вывода.
Уведомить после завершения выполненияIOCP, по сути, состоит в том, чтобы поместить этот requeat в очередь, которая является концентратором между пулом потоков и циклом обработки событий.
Когда цикл обработки событий обнаружит, что в очереди есть запрос, он извлечет его и выполнит соответствующий обратный вызов, и совершенная асинхронная неблокировка будет завершена.
Суммировать
Эта статья была включенаGithub https://github.com/ponkans/F2E, есть расширенные руководства для производителей первого уровня, добро пожаловать в Star, продолжайте обновлять
После тщательного чтения две серии странного узла асинхронного неблокирования (сверху) и (снизу), вы не можете повесить вопросы собеседования, вы можете прийти ко мне ~
Исходный код libuv threadPoolЯ провел вас через это, но если вы все еще этого не понимаете, вы не можете толком объяснить! !
Наконец, резкое совершенное резюме выглядит следующим образом.
основное резюме: Node использует пул потоков для выполнения вызовов ввода-вывода, чтобы избежать блокировки основного потока.После выполнения результаты и запросы помещаются в очередь, цикл событий используется для извлечения запросов из очереди, и, наконец, выполняется обратный вызов для добиться эффекта асинхронной неблокировки.
Оригинальный текст недавнего теплового портала, biubiu~:
- Серия "Turdee" большой коллекции заводских библиотек компонентов для фронтальных компонентов (для ПК, мобильных устройств, JS, CSS и т. д.)
- Низкоуровневая реализация многопроцессорной модели серии "Большой внешний интерфейс Advanced Node.js" (был задан вопрос ByteDance)
- Серия "Big Front-end Advanced Node.js" Double Eleven Second Kill System
- Асинхронная неблокирующая серия "Big Front-end Advanced Node.js" (часть 1)
Если вам это нравится, добавьте подписку, поставьте лайк, спасибо 💕😊
Свяжитесь со мной / публичный аккаунт
Поиск в WeChat【Доступ монстров] Или отсканируйте QR-код ниже, чтобы ответить на «Добавить группу», я приглашу вас в группу технического обмена. Честно говоря, в этой группе, даже если вы не говорите, просто чтение записей чата — это своего рода рост. (Али технический эксперт, автор Ao Bing, Java3y, старший клиент Mogujie, эксперт по безопасности Ant Financial, там все большие коровы).
Водяной монстр также будет регулярно создавать оригиналы, регулярно обмениваться опытом с небольшими партнерами или помогать читать резюме. Будьте внимательнее, не теряйтесь, есть возможность побегать вместе 🏃↓↓↓