Асинхронне програмування: види, класифікація, принципи програмування, концепція, значення та застосування

Асинхронне програмування: види, класифікація, принципи програмування, концепція, значення та застосування

Асинхронне програмування (АП) - це форма паралельного програмування, яка дозволяє структурній одиниці системи працювати окремо від основного потоку програми. Коли робота завершена, вона повідомляє основний потік про те, чи була робота завершена чи ні. Таке програмування вигідне, оскільки воно збільшує підтримувану пропускну здатність, що робить її привабливою, враховуючи зростаючу потребу інтернету в системах з високою масштабованістю.

Моделі асинхронного програмування

Для того щоб обробити безперервність результату неблокуючих операцій після їх завершення, були створені різні моделі АП. Переваги їх оцінюються з точки зору того, наскільки вони дозволяють наблизитися до схеми, найбільш близької до послідовної.


Типи моделей АП:

  1. Continuations step model - спадкоємна ступенева модель. Це найбільш використовувана асинхронність в Node JS. Кожна функція отримує інформацію про те, як вона повинна обробляти в операції результат успіху або помилки.
  2. Event model - модель події, використовує керовану подіями архітектуру, яка дозволяє неблокуючим операціям повідомляти про їх завершення за ознаками успіху або невдачі, вимагає кореляція для синхронізації.
  3. Promise model - модель обіцянки, пояснюється поверненими значеннями неблокуючих операцій незалежно від моменту часу, в який були отримані зазначені значення успіху або невдачі.
  4. Generator model - модель генератора. Генератори використовуються для тимчасового повернення управління зухвалою програмою і подальшого повернення до підпрограми, шляхом відновлення стану в точці, в якій її виконання було припинено.

Архітектурні принципи Node

Незважаючи на те що останнім часом Node JS отримує різку критику щодо використання ним обчислювальних циклів через однопоточне середовище, його філософія, заснована на трьох сильних архітектурних принципах, залишається затребуваною.

JavaScript асинхронний за своєю природою, як і Node. Платформа для запуску серверного JavaScript, Node.js була представлена в 2009 році з використанням асинхронної моделі введення-висновку, керованої подіями, що робить її ефективною і масштабованою.

Чат є найбільш типовим прикладом багатокористувацької програми Node.js в реальному часі. Починаючи з IRC для багатьох пропріетарних і відкритих протоколів на нестандартних портах, з 'явилася можливість реалізовувати все в сучасних Noje.js з WebSockets, що працюють за замовчуванням на тому ж порту 80, який прослуховує нові повідомлення, відправлені їх клієнтами. На боці клієнта є HTML-сторінка з кількома налаштованими обробниками, одна для кнопки "Відправити", що вибирає повідомлення і надсилає його в WebSocket, та інша, яка прослуховує повідомлення, що надходять на клієнт. Очевидно, що це проста і базова модель, але заснована на іншій дисперсії складності.

Неактивна модель, яку Node JS використовує в API для підтримки асинхронного програмування, є кроком до продовження. Кожна неблокуюча операція отримує функцію в якості останнього параметра, яка включає логіку продовження. Вона буде викликана після закінчення операції, як для обробки результатів у разі успіху, так і для усунення помилок. Функція продовження дозволяє вказати дії блокування, як вона повинна тривати після завершення операції.

Керування послідовним потоком

Для того щоб в рамках цієї моделі продовжити встановлення послідовних потоків виконання, необхідно об 'єднати кожну наступну функцію в ланцюжок, як продовження попередньої, де результати будуть оброблятися в разі успіху або невдачі. Це призводить до діагоналізації коду, який був названий пірамідою пекла (пекло зворотного виклику), через відсутність практичної керованості, якщо тільки кількість послідовних ланцюжків зростає мінімально.


Розпаралелювання - асинхронне виконання неблокуючих операцій відбувається негайно, оскільки його простий виклик виконується у фоновому режимі за визначенням. Щоб перетворити блокуючі операції на неблокуючі, потрібен невеликий процес інкапсуляції, який запускає операцію у фоновому режимі.

Синхронізація функцій продовження

Вона вимагає ланцюжка в кінці кожної паралельної послідовності функції завершення, яка застосовує певну логіку тільки після того, як буде підтверджено, що всі паралельні гілки завершені. Для реалізації цієї перевірки використовуються діаграми на основі лічильників.

Приклад за допомогою продовжувачів:

  1. Паралельність, цикл дозволяє виконувати всі неблокуючі пари зчитування-рахунки неблокуючим способом.
  2. Послідовність, кожна пара зчитування зчитується через крок функцій продовження.
  3. Синхронізація, кожна паралельна гілка отримує останнє продовження, яке виконує логіку завершення, як тільки буде забезпечено завершення всіх гілок.

Бібліотеки продовжувачів

Існує безліч бібліотек, які можуть допомогти спростити життя розробникам, що працюють з моделлю АП. Деякі з них пов 'язані не тільки з АП, але і з функціональною парадигмою, яка обумовлена тим фактом, що механізми впровадження з' єднань, по суті, є функціональними перевагами.

Види бібліотек:

  1. Async, мабуть, найвідоміша бібліотека для асинхронного програмування на основі продовжувачів. Вона пропонує різні методи управління потоком для неблокуючих функцій.
  2. Join - є реалізацією методу синхронізації, який можна знайти в інших мовах, таких як C і працює з потоками. Це може також використовуватися в обіцянках, хоча в даному випадку його використання менш актуальне.
  3. js - відмінна бібліотека, яка реалізує різні функціональні методи управління. Його практична застосовність у цьому контексті пов 'язана з можливостями, які він надає для генерації неблокуючих функцій і застосування перевірки.

Переваги і недоліки

Асинхронне програмування на основі продовжувачів хороший варіант для ситуацій з простою логікою управління потоком. Зазвичай це стосується програм у Node JS, які дозволяють визначати неблокуючу відповідь на вхідні запити.

Переваги моделі:


  1. Прості схеми запиту і відповіді.
  2. Узгодженість зі схемами функціонального програмування.
  3. Легко зрозуміти як концептуальний механізм.

Недоліки:

  1. Коли логіка управління розроблена недостатньо, процес ускладнюється, що призводить до створення коду з розподіленою функціональною логікою, який важко читати, розуміти і підтримувати.
  2. Складність у визначенні логіки управління потоками.
  3. Складно налаштовуватися механізми синхронізації.
  4. Логіка керування розподіляється між кожною неблокуючою гілкою.

Модель, керована подіями

Подія є сигналом у бізнес-екосистемі. Анатомічно вони зазвичай складаються з типу, часової мітки і набору даних, що характеризують контекст, в якому сталася подія. Архітектура подій (EDA) забезпечує механізм зв 'язку між клієнтами і постачальниками у відносинах 1: N і з номінальною розв 'язкою. Одне з багатьох його застосувань - усунення проблем асинхронної обробки даних.

У централізованих архітектурах, керованих подіями, існує центральна комунікаційна шина-посередник, яка відповідає за забезпечення ефективності процесу реєстрації прослуховуючих клієнтів і запуску повідомлень на вимогу постачальників до них. Цей механізм допускає потужність N:N, а схема називається шаблоном PUB/SUB.

У розподілених керованих подіями архітектурах кожен провайдер відповідає за управління підпискою своїх клієнтів і за відправку повідомлень, при виникненні події. Механізм зв 'язку також номінально відокремлений, але зазвичай кількість провайдерів і клієнтів становить 1:N. Ця схема відповідає схемі або джерелам подій у Node JS jargon.

Обчислювальна абстракція: Promise

Обіцянка - це обчислювальна абстракція, яка являє собою зобов 'язання з боку неблокуючої операції, викликаної для доставки відповіді викликає програмі, коли результат отримано після завершення. Обіцянка - це об 'єкт, який надає два методи для включення логіки обробки в разі успіху або невдачі.


Вони відповідають простому життєвому циклу, який необхідно знати, щоб з ними можна було працювати. Суттєва цінність обіцянки полягає у двох принципах. По-перше, логіка процесу в разі успіху або невдачі застосовується тільки один раз. І, по-друге, гарантується виконання логіки успіху або невдачі, навіть якщо обіцянка дозволена до того, як будуть введені його драйвери. Якщо буде потрібно, обіцянка чекає своїх обробників, асинхронного програмування JavaScript.

Є кілька способів отримати обіцянки, які можна ідентифікувати як шаблони побудови, які з 'являються періодично при використанні цієї моделі. Визначення ES6 включає в себе обіцянки і Node JS версії 0.12 має підтримку цієї специфікації. Крім того, є кілька бібліотек, які реалізують модель обіцянок. Для того щоб мати порівняльну систему відліку, був визначений стандарт Promises A +, який управляє всіма реалізаціями з доступними на той момент об 'єктами.

Синхронне та асинхронне програмування

Рекомендується використовувати АП JavaScript, завантаження для всіх його тегів і коду постачальника з нього. Це забезпечує найкращу сумісність з найбільшою кількістю постачальників. Таке розміщення надає всім тегам постачальників найбільшу можливість завершити відстеження, перш ніж відвідувач перейде на наступну сторінку.

Синхронне завантаження відбувається, коли переглядач повинен зупинити рендеринг сторінки, щоб завершити виконання коду JavaScript. Якщо він виявляє синхронний тег JS, то блокує відображення сторінки до завершення виконання коду. Це аналогічно тихохідній вантажівці на дорозі з однією смугою руху, яка уповільнює рух за ним. Сучасні веб-сайти відійшли від цього методу, тому що він представляє прямий ризик затримки часу завантаження сторінки.

Браком цього методу є те, що весь сайт блокується від початку до повного завантаження тега. І хоча постачальники тегів укладають угоди про рівень обслуговування протягом терміну їх доставки, на продуктивність можуть впливати кілька факторів. До них належать повільний час відгуку, пов 'язаний з постачальниками, ведення непотрібних серверів додатків у гібридну модель клієнт-сервер і повільний інтернет-трафік. Якщо користувач завантажує теги синхронно, рекомендується переконатися, що у постачальника час відгуку становить 100 мілісекунд (мс) або швидше.


Програмування синхронної та асинхронної обробки даних через API - це інтерфейси прикладного програмування, які повертають дані для запитів або відразу, або, відповідно, пізніше. Синхронні та асинхронні API надають спосіб робити негайні або заплановані запити ресурсів, даних або послуг, коли вони доступні. Сучасний метод, прийнятий для сайтів, полягає в асинхронному завантаженні тегів.

У цьому методі код JavaScript обробляється паралельно з іншим вмістом сторінки. Це означає, що навіть якщо тег постачальника повільно реагує або завантажується, він не буде уповільнювати роботу решти сторінки. Використовуючи цей підхід, можна не тільки розділяти теги JavaScript, які завантажуються незалежно один від одного, асинхронний метод мінімізує вплив завантаження зовнішніх файлів JS на процес візуалізації сторінки.

Розуміння і профілювання C #

Microsoft і спільнота .NET дуже спростили АП завдяки реалізації асинхронного очікування в C #. Останні версії ASP.NET активно використовують його для підвищення продуктивності. Багато інструментів для моніторингу продуктивності та профілювання намагаються підтримувати і візуалізувати продуктивність асинхронного програмування 1С. Продукти Stackify Prefix & Retrace мають відмінну підтримку додатків, що використовують C # async await. Для початку потрібно зрозуміти, як насправді працює код, що використовує async awai "" і HttpClient як приклад.

Використовуючи ILSpy, можна побачити, як компілятор перетворює цей код на AsyncState Machine. Кінцевий автомат виконує весь складний код під прикриттям, що дозволяє розробникам, писати асинхронний код.

Профілювання асинхронного програмування в C 5 0 складним, тому що він перетинає потоки. Традиційно, метод і всі виклики його дочірніх методів відбуваються в одному потоці. Це полегшує розуміння відносин між батьківськими і дочірніми методами. З асинхронним кодом це зовсім інша історія. Батьківський метод запускається в одному потоці. Коли починається операція введення-виведення, код у цьому потоці закінчується. Коли операція введення-виведення завершується, код продовжує виконуватися в новому потоці. Зв 'язати код між цими потоками, як частину більшої транзакції, досить складно.


AIOHTTP: сервер-клієнт для asyncio

Aiohttp - дозволяє користувачам створювати асинхронні сервери і клієнти. Пакет асинхронного програмування aiohttp працює для клієнтських і серверних веб-сокетів. Документація з цього прикладу aiohttp використовується для захоплення сторінки HTML.

У цьому прикладі показано, як завантажити один або декілька файлів, і також можна завантажувати файли через програму. У ньому вказано декілька нових елементів, таких як asynctimeout. Це дозволяє створити менеджер контексту часу очікування. Внизу код створює асинхронний цикл синхронізації і використовує його як основну функцію.

Створюють об 'єкт Client Session в головній функції асинхронного програмування і coroutine, і функцію співпрограми, яка збирає URL всього, що потрібно завантажити. У download coroutine він створює менеджер контексту, який працює близько X секунд. Після закінчення цієї кількості секунд X менеджер контексту закінчується. Далі використовують функцію get () сеансу, яка знаходить об 'єкт відповіді.

Коли розробник створює атрибут вмісту об 'єкта відповіді, він повертає aiohttp. StreamReader, який дозволяє користувачеві завантажувати файл у будь-якому розмірі. Як тільки буде прочитано файл, його буде записано на локальний диск. Після чого використовують функцію response (), щоб завершити обробку відповіді. Згідно документації він неявно викликає release (). Тим не менш, асинхронне програмування Python явно краще. Краще залишити цю функцію, щоб запобігти подальшим проблемам. Тут є один розділ, який блокує розділ коду, що записується на диск, при цьому код залишається заблокованим. Використання aiohttp - реальний спосіб поліпшити робочий процес, де користувачам не потрібно витрачати час на створення сервера, завантаження посилань і написання асинхронних файлів, що скорочує час створення проекту.

Асинхронне програмування дозволяє досягти більшої ефективності в програмному забезпеченні, оскільки не блокується потік виконання для тривалих процесів або взаємодії з користувачем, як для розробки програм для Node, так і для браузерів.