У меня не укладывается в голове, как поток может освободить ресурсы и вернуться в пул.
Представьте себе очередь к врачу:
В синхронном режиме врач с пациентом может его проконсультировать и отпустить, а может его проконсультировать и вместе с ним пойти на дополнительные исследования. УЗИ, допустим, и ждёт там, пока ему его сделают, простаивает и ничего полезного не делает. В это время, пока он ходит с пациентом 1 и ждёт, пришёл пациент 2 и этот пациент не получает консультацию, пока не обслужится 1й пациент.
В асинхронном режиме врач не ходит на УЗИ с 1м пациентом, а направляет его в другой кабинет, а сам принимает второго, третьего и т.п. а когда первый пациент сделает это УЗИ, то он возвращается к врачу и получает дополнительную консультацию.
Так вот, асинхронный режим - это упрощённейшее описание TPL.
В этой истории врачи - это пул потоков. Размер, обычно, по количеству ядер процессора, вроде как. При этом каждый врач - это уже созданный заранее поток ОС.
Асинхронность в том, что врачи гоняют пациентов из кабинета в кабинет, а история болезни - это контекст потока и совсем не обязательно, что пациент после УЗИ попадёт к тому же врачу или другому, всё зависит от очереди, свободности врача и пр.
Когда у нас заканчиваются врачи, то увеличение пула потоков - это добавление нового врача, но т.к. вы не можете увеличить количество ядер, то это как если бы на трёх врачей было только два кабинета.
Потоки ОС - это более низкоуровневые "потоки". Это уже распределение ресурсов ядер процессора - освобождение кабинетов для тех кому они нужны да ещё и очень-очень быстро, а это переключение контекста потоков ОС (это отличается от контекста TPL).
А дальше аналитика:
Пул потоков вы увеличили, а ядра - не можете, то ОС начинает часто переключать свои контексты на выполнение ваших задач, что не хорошо.
При очень-очень малом количестве пациентов, по величине абсолютно затраченного времени, асинхронность проигрывает, т.к. накладываются расходы переключения контекста.
А вот при большом количестве пациентов асинхронность выигрывает - т.к., условно, возьмём 11 пациентов и одному нужно УЗИ. Пациент лечится за 1 секунду, кабинет УЗИ работает 10 секунд, если врач ходит с пациентом, то он тратит на УЗИ 10 секунд+1 секунду работа с пациентом + 10*1 работа с остальными=21 секунд на 11 пациентов. А если врачей больше и работают они асинхронно, то за эти 10 секунд УЗИ одного больного обслужатся 10 других пациентов=11 секунд на 11 пациентов. В этом свете накладные расходы на переключение контекста ничтожно малы.
Джефри Рихтер об этом пишет в своей книге CLR via C#.
В технических терминах про асинхронность можно почитать в блоге Стивена Клири.
Если у вас в системе один контроллер и один метод в нём, вы можете выиграть от синхронного подхода если только у вас нет внутри необходимости в асинхронном получении данных и запросы приходят достаточно редко.
Или если у вас и асинхронный контроллер, и синхронный контроллер всегда выполняют одну и ту же операцию, с одним и тем же набором данных, по одному и тому же сценарию, при одних и тех же свободных мощностях. И то это не точно.
И на графике выше это видно.
Написано
Войдите на сайт
Чтобы задать вопрос и получить на него квалифицированный ответ.
Представьте себе очередь к врачу:
В синхронном режиме врач с пациентом может его проконсультировать и отпустить, а может его проконсультировать и вместе с ним пойти на дополнительные исследования. УЗИ, допустим, и ждёт там, пока ему его сделают, простаивает и ничего полезного не делает. В это время, пока он ходит с пациентом 1 и ждёт, пришёл пациент 2 и этот пациент не получает консультацию, пока не обслужится 1й пациент.
В асинхронном режиме врач не ходит на УЗИ с 1м пациентом, а направляет его в другой кабинет, а сам принимает второго, третьего и т.п. а когда первый пациент сделает это УЗИ, то он возвращается к врачу и получает дополнительную консультацию.
Так вот, асинхронный режим - это упрощённейшее описание TPL.
В этой истории врачи - это пул потоков. Размер, обычно, по количеству ядер процессора, вроде как. При этом каждый врач - это уже созданный заранее поток ОС.
Асинхронность в том, что врачи гоняют пациентов из кабинета в кабинет, а история болезни - это контекст потока и совсем не обязательно, что пациент после УЗИ попадёт к тому же врачу или другому, всё зависит от очереди, свободности врача и пр.
Когда у нас заканчиваются врачи, то увеличение пула потоков - это добавление нового врача, но т.к. вы не можете увеличить количество ядер, то это как если бы на трёх врачей было только два кабинета.
Потоки ОС - это более низкоуровневые "потоки". Это уже распределение ресурсов ядер процессора - освобождение кабинетов для тех кому они нужны да ещё и очень-очень быстро, а это переключение контекста потоков ОС (это отличается от контекста TPL).
А дальше аналитика:
Пул потоков вы увеличили, а ядра - не можете, то ОС начинает часто переключать свои контексты на выполнение ваших задач, что не хорошо.
При очень-очень малом количестве пациентов, по величине абсолютно затраченного времени, асинхронность проигрывает, т.к. накладываются расходы переключения контекста.
А вот при большом количестве пациентов асинхронность выигрывает - т.к., условно, возьмём 11 пациентов и одному нужно УЗИ. Пациент лечится за 1 секунду, кабинет УЗИ работает 10 секунд, если врач ходит с пациентом, то он тратит на УЗИ 10 секунд+1 секунду работа с пациентом + 10*1 работа с остальными=21 секунд на 11 пациентов. А если врачей больше и работают они асинхронно, то за эти 10 секунд УЗИ одного больного обслужатся 10 других пациентов=11 секунд на 11 пациентов. В этом свете накладные расходы на переключение контекста ничтожно малы.
Джефри Рихтер об этом пишет в своей книге CLR via C#.
В технических терминах про асинхронность можно почитать в блоге Стивена Клири.
Если у вас в системе один контроллер и один метод в нём, вы можете выиграть от синхронного подхода если только у вас нет внутри необходимости в асинхронном получении данных и запросы приходят достаточно редко.
Или если у вас и асинхронный контроллер, и синхронный контроллер всегда выполняют одну и ту же операцию, с одним и тем же набором данных, по одному и тому же сценарию, при одних и тех же свободных мощностях. И то это не точно.
И на графике выше это видно.