LINUX.ORG.RU

Асинхронный прием и асинхронная обработка, неблокирующий и блокирующий *

 ,


1

10

В ВУЗе нам поверхностно освещали вопрос асинхронной обработки данных (это были 1990-е годы с MS-DOS). Упоминались в этом контексте в основном - неблокирующие сокеты. На практике я сталкивался с блокировками ресурсов (C+pthread+mutex), про асинхронность мало знаю.

У меня четыре основных вопроса.

Первый. Асинхронность «в чистом виде» где-нибудь бывает? Я имею ввиду «асинхронный прием сообщений». Ведь принимает их какой-то конкретный узел. Под асинхронностью здесь понимается принципиальная возможность мультиплексирования глобального ресурса (процессора, канала связи) при попадании в очередь нескольких запросов на один «такт» обработки? То есть, асинхронность и «возможность распараллеливания» дальнейшей обработки - это здесь синонимы? [распараллеливание парсинга, перекладывании из очереди в очередь, вычислений]

Второй вопрос. Что бывает «неблокирующего» - кроме приёма сообщений? И, аналогично, «асинхронного». Можете привести примеры из повседневной жизни (см. четвертый вопрос)?

Третий вопрос. «Синхронная обработка» - это синоним «FIFO»?

Четвертое. Приведите, пожалуйста, практический пример для каждого варианта.
1. Блокирующий приём, синхронная обработка.
2. Блокирующий приём, асинхронная обработка.
3. Неблокирующий приём, синхронная обработка.
4. Неблокирующий приём, асинхронная обработка (например, в какой-нибудь конторе - выписали квиток что «ваше заявление принято», по мере возможности обработали запрос, и когда обработка завершилась - отправили уведомление).

★★★★★

Последнее исправление: pacify (всего исправлений: 1)

Ответ на: комментарий от deep-purple

Чё тут разбираться? Я вот с точки зрения неспеца могу сказать, что асинхронный ввод/вывод это использование неблокирующих системных вызовов + механизм проверки, какой(ие) из пайпов/сокетов/итд готовы в данный момент для нужных операций. Мьютексы же - это вообще из другой оперы

pr0n_actor
()

И вообще, тебя что интересует? Многопоточность или именно ввод/вывод? Если последнее, то man select, скажем. Поищи пример, когда у тебя много сокетов и ты хочешь читать данные только с тех, которые уже готовы для чтения, при этом читать столько, сколько уже доступно на данный момент.

pr0n_actor
()

Асинхронность «в чистом виде» где-нибудь бывает?

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

Блокирующим или неблокирующим может быть вызов какой-то функции, грубо говоря. Если каких-то входных данных может не оказаться на момент вызова, но функция всё равно берётся сделать своё дело, то она будет блокирующей.

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

Например, возьмём юниксовые read(), select() и прочее про сокеты. Ставим задачу прочитать из сокета сколько-нибудь байт. Функция read делает это синхронно. В зависимости от флага O_NONBLOCK на сокете, она будет блокирующей или неблокирующей. Теперь усложним задачу и захотим прочитать n байт (или пока не упрёмся в EOF). Цикл с read() будет синхронным и блокирующим. Event loop на select с колбеками будет асинхронным. Результат, буфер с n байтами, приходит в колбек, а не как результат изначального вызова. Будут ли отдельные функции из интерфейса этого event loop'а блокирующими, зависит от кривизны рук программиста.

1. Блокирующий приём, синхронная обработка.

Приём и обработка, скорее всего, являются двумя разными интерфейсами. Наверное, это два слоя, один над другим. Вопрос применим к обоим слоями независимо. Блокирующий/неблокирующий — особенность реализации. Чтобы понять является ли твоя обработка асинхронной, определи (ну или придумай, если хочешь изобрести пример) функции (запросы, вызовы, сообщения...) и результаты их работы.

Всё выше написанное является моим личным бредом. На научность не претендую, книжек не писал и не читал.

const86 ★★★★★
()

Под асинхронностью здесь понимается принципиальная возможность мультиплексирования глобального ресурса...

асинхронность — это отсутствие связи, согласованности с чем либо, синхронность — наоборот, согласованность с чем-то

не надо нагружать термины лишними смыслами

anonymous
()

У тебя все вопросы поставлены так, что либо однозначно не ответишь, либо похоже на поток сознания.

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

А если у тебя например два потока асинхронно общаются, то две атомарные очереди у тебя будут явно присутствовать, и ты будешь лочить их, когда надо сунуть или вынуть элемент с к-л стороны. При этом один поток может насувать элементов другому и сесть прямо тут ждать, пока он все довыполнит, чтобы синхронизироваться. Это будет аналог блокирующего вызова в ядро.

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от anonymous

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

Deleted
()

Сидишь на хате, бухаешь с корешами. Водка кончилась. Встал, пошёл в соседний подъезд за палёнкой - это синхронная операция. Аналог - прямая работа с файловыми дескрипторами или сокетами.

Сидишь на хате, бухаешь с корешами. Водка заканчивается. Всучил сыну пятихатку и отправил в соседний подъезд за палёнкой, а сам продолжаешь бухать - это асинхронная операция. Аналог - работа с файловыми дескрипторами или сокетами через aio.

mv ★★★★★
()
Ответ на: комментарий от anonymous

А вы анонiмуса забанили.

Да тут даже многозвездочные уже им покусаны. Вот прямо сейчас два активных метафизических треда про ООП и асинхронку. Но банят за такой тупняк только анонiмуса почему то.

anonymous
()

1. Блокирующий приём, синхронная обработка.

В одном треде читаем из источника и обрабатываем полученные данные, последовательно.

2. Блокирующий приём, асинхронная обработка.

Один тред читает из одного сокета, разбирает сообщение и запускает колбек (в другом треде или в пуле тредов).

3. Неблокирующий приём, синхронная обработка.

Специфичный случай. Такой use-case можно представить: CPU-bound симуляция, которая перед каждой итерацией считывает пользовательский ввод. Но если пользователь ничего не ввёл, то симуляция всё равно отработает. Т.е. получение данных происходит неблокирующе.

4. Неблокирующий приём, асинхронная обработка

Типичный event loop. Loop поллит сокеты на готовность к чтению или записи, выполняет io, инициирует выполнение колбеков.

anonymous
()

В одноядерном процессоре вся работа - асинхронная, из кусочков. Прерывание, обработка прерывания, переход к пользовательскому процессу, пауза и снова прерывание. Для пользовательского процесса работа выглядит непрерывной, но это лишь видимость, создаваемая усилиями операционной системы. Поэтому в ядре практически всё - асинхронное. Т.е. произошло внешнее событие, выполнили кусочек кода, снова ждём событие.

Deleted
()

Просто почитай доки про жаваскрипт — он весь асинхронный.

В двух словах — асинхронность это возможность повесить коллбек.

отправить хттп запрос, ответ обработать вот этой фунцкией
отправить еще один запрос, ответ обработать другой функцией

На этом код закончился. Никаких тредов, никаких блокировок. Все будет обработано асинхронно.

И вообще неплохо бы почитать про мультиплексоры (select epoll kqueue). Там ничего сложного нет.

A Computer is a state machine. Threads are for people who can't program state machines. (с)

redixin ★★★★
()

Асинхронный и синхронный режимы рассматривают обычно в контексте посылки сообщений. На синхронный вызов ждешь ответа, на асинхронный - нет. Впрочем, «асинхронность» - многозначный термин.

Вон, в F# есть монада асинхронных вычислений. Даже называется Async, и она так называется по праву, потому что там тоже есть асинхронность, но на уровне вычислений. Буквально, пишешь выглядящий линейным код, выполнение которого зависит от наступления внешних событий.

dave ★★★★★
()

Я имею ввиду «асинхронный прием сообщений». Ведь принимает их какой-то конкретный узел. Под асинхронностью здесь понимается

Под асинхронностью всегда понимается одно: объект посылает сообщение и не блокирует при этом выполнение программы ожиданием ответа. Таким образом все выполняется по-сути одновременно, даже если выполнение происходит в одном потоке.

sedquest
()

Э, кхм. На правах наркомана-полуночника.

Асинхронность «в чистом виде» где-нибудь бывает? Я имею ввиду «асинхронный прием сообщений». Ведь принимает их какой-то конкретный узел.

В распределенной системе совсем не обязательно это будет «конкретный узел». Это может быть множество узлов, причем пустое. Вопрос про «чистый вид» - философский.

Под асинхронностью здесь понимается принципиальная возможность мультиплексирования глобального ресурса (процессора, канала связи) при попадании в очередь нескольких запросов на один «такт» обработки? То есть, асинхронность и «возможность распараллеливания» дальнейшей обработки - это здесь синонимы? [распараллеливание парсинга, перекладывании из очереди в очередь, вычислений]

Нет, это про разное. Например HTTP Pipelining - асинхронная штука, но её нельзя параллелить. Асинхронность это скорее про отложенное, чем про параллельное выполнение (но отложенное выполнение это тоже не синоним асинхронного, хотя и параллельное и отложенное оба обычно подразумевают присутствие асинхронности).

Второй вопрос. Что бывает «неблокирующего» - кроме приёма сообщений? И, аналогично, «асинхронного». Можете привести примеры из повседневной жизни (см. четвертый вопрос)?

Неблокирующий ввод/вывод (не всегда же про прием сообщений?). Неблокирующие алгоритмы. Неблокирующая многозадачность. Неблокирующие тормоза.

Асинхронная подгрузка CSS / JS. Асинхронный двигатель. Асинхронное плавание.

Третий вопрос. «Синхронная обработка» - это синоним «FIFO»?

Асинхронная тоже может быть FIFO (тот же HTTP Pipelining). А синхронная может быть параллельной и не FIFO.

практический пример для каждого варианта

1. Блокирующий приём, синхронная обработка.

data = sock.read()
process_data(data)

2. Блокирующий приём, асинхронная обработка.

data = sock.read()
apply_async(process_data, data)

3. Неблокирующий приём, синхронная обработка.

data = await sock.read()
process_data(data)

4. Неблокирующий приём, асинхронная обработка

data = await sock.read()
apply_async(process_data, data)

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

data = sock.read() - клиент написал заявление под присмотром сотрудника

data = await sock.read() - клиент отправил заявление факсом

process_data(data) - обработали запрос сами

apply_async(process_data, data) - перенаправили запрос в другую организацию

ps. подумай над тормозами и плаванием в ответе на второй вопрос

ei-grad ★★★★★
()
Ответ на: комментарий от sedquest

sedquest

Ура, анонiмус снова в строю! Мы скучали, чувак.

anonymous
()

1. Скорее 1почти в чистом виде. ИМХО, асинхронный ввод/вывод в большинстве случает предпочтителен, нежели синхронный.

2. Что такое «сообщения» в твоем понимании? Мне больше нравится выражение «ожидание события». Ты можешь синхронно или асинхронно ждать какие-то события. При синхронном варианте ты блокируешь поток исполнения и ждешь одно событие, когда событие наступает, поток просыпается, при этом если надо во время этого сна среагировать на какое-то другое событие(ия), то необходим другой поток(и). А при асинхронном, ждем в одном потоке наступления множества разных событий, когда одно из них наступает - обрабатываем, потом снова ждем событий.

3. Нет, FIFO само по себе ни причем.

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 1)

я думаю, надо рассмотреть синхронную и асинхронную композицию конечных автоматов, ответ где-то там))

dimon555 ★★★★★
()

почитай тут, например:
http://www.kegel.com/c10k.html
статья хоть и древняя, но мало что изменилось с тех пор. ну, по мелочи некоторые функции инициализации всяких параметров изменились, с появлением ipv6, для пущего удобства. но приём-передача - всё то же, всё так же.

Iron_Bug ★★★★★
()

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

Iron_Bug ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.