Re[15]: Горутины и потоки
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.07.21 07:57
Оценка:
Здравствуйте, netch80, Вы писали:

N>Эээ...

N>1. Если у кого-то на "обычном локе" тысячи ниток, то тут в первую очередь нужно менять весь дизайн (может быть, даже архитектуру, в обычном понимании).
N>Любые локи предназначены для малого количества конкурентов за их ресурс. Даже по количеству хартов — это уже много. До 4 — нормально. Если выше — надо думать разделять на разные локи. Если выше 8 — срочно думать.
N>2. Я уже описывал работу адаптивных мьютексов. Вначале, да, цикл сколько-то попыток захвата в стиле спинлока — чистым CAS (если нет видимой очереди). Если они не получились, тогда уже начинать более серьёзную машину — или через await, или через Lock() в ядре.
N>Но противопоставлять спинлоки мьютексам и говорить про "эффективность" spinlock по сравнению с мьютексом — это просто смешно.
N>Спинлок заведомо менее эффективен на длительных периодах и большом количестве конкурентов. Есть случаи, когда его использование неизбежно — когда шедулера более высокого порядка просто нет (в первую очередь это борьба в ядре за общие ресурсы между разными хартами). Но в остальных случаях его использовать — только ухудшать.

S>>Ну вот я и хочу разобраться если переключение потоков так эффективно, то нахрена городить async await?


N>1. "Во-первых, это красиво" (tm). Линейное написание кода в разы проще цепочек коллбэков, неважно, в явном виде или на промисах.

N>Если программист не справляется без await, он будет писать линейно, но будут сплошные блокировки на синхронных операциях. Await позволяет использовать широкие ресурсы кодеров с реальным улучшением характеристик именно за счёт этого — меньше блокировок.
+
N>2. При высокой цене переключения между нитками внутреннее переключение (шедулером на границе awaitʼа) будет в разы дешевле переключения через ОС.
Вот спасибо! Все таки дешевле!
Ну давай возьмем типичный сервер. БОльшая часть задач сводится к вызову асинхронным методов а именно запрос к базе данных (не локальной), запрос к сайту, к файлу итд.
Выделять для каждого запроса отдельный поток не имеет смысла (тут и затраты на создание потока или держать пул огромного размера).
Как правило эти задачи небольшие.
Отдельный поток стоит выделять для длительных задач LongRunning

То есть смысла в выделении потоках на задачу нет. Есть смысл использовать пул потоков. Что было кстати в ранних версиях вэб сервисов ASP.Net.
Тогда тоже были и асинхронные делегаты (BeginInvoke() и EndInvoke()) и ThreadPool. Но в том же сервисе вызов вэб метода был синхронным, то есть привязан к одному потоку. То есть внутри то можно было использовать калбеки и прочее, но поток морозился на эвенте

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