Страницы

Поиск по вопросам

воскресенье, 24 ноября 2019 г.

Многопоточное vs асинхронное программирование


Хотелось бы узнать разницу между этими подходами.
Разве асинхронное программирование не подразумевает из себя уже многопоточность
ведь Task где-то там по любому выполняется в отдельном потоке ?

В каких случаях нужно прибегать к многопоточному, а в каких к асинхронному программированию ?

И еще ко всему этому есть параллельное программирование, которая тоже вносит путаниц
для меня. В чем её отличие ?
    


Ответы

Ответ 1



Попробую собрать воедино все, что дали уже в комментариях. Есть несколько разных понятий, связанных с областью параллельных вычислений. Конкурентное исполнение (concurrency) Параллельное исполнение (parallel execution) Многопоточное исполнение (multithreading) Асинхронное исполнение (asynchrony) Каждый из этих терминов строго определен и имеет четкое значение. Конкурентность (concurrency) Конкурентность (*) (concurrency) - это наиболее общий термин, который говорит, чт одновременно выполняется более одной задачи. Например, вы можете одновременно смотрет телевизор и комментить фоточки в фейсбуке. Винда, даже 95-я могла (**) одновременн играть музыку и показывать фотки. (*) К сожалению, вменяемого русскоязычного термина я не знаю. Википедия говорит что concurrent computing - это параллельные вычисления, но как тогда будет paralle computing по русски? (**) Да, вспоминается анекдот про Билла Гейтса и многозадачность винды, но, теоретическ винда могла делать несколько дел одновременно. Хотя и не любых. Конкурентное исполнение - это самый общий термин, который не говорит о том, каки образом эта конкурентность будет получена: путем приостановки некоторых вычислительны элементов и их переключение на другую задачу, путем действительно одновременного исполнения путем делегации работы другим устройствам или еще как-то. Это не важно. Конкурентное исполнение говорит о том, что за определенный промежуток времени буде решена более, чем одна задача. Точка. Параллельное исполнение Параллельное исполнение (parallel computing) подразумевает наличие более одного вычислительног устройства (например, процессора), которые будут одновременно выполнять несколько задач. Параллельное исполнение - это строгое подмножество конкурентного исполнения. Эт значит, что на компьютере с одним процессором параллельное программирование - невозможно;) Многопоточность Многопоточность - это один из способов реализации конкурентного исполнения путе выделения абстракции "рабочего потока" (worker thread). Потоки "абстрагируют" от пользователя низкоуровневые детали и позволяют выполнят более чем одну работу "параллельно". Операционная система, среда исполнения или библиотек прячет подробности того, будет многопоточное исполнение конкурентным (когда потоко больше чем физических процессоров), или параллельным (когда число потоков меньше ил равно числу процессоров и несколько задач физически выполняются одновременно). Асинхронное исполнение Асинхронность (asynchrony) подразумевает, что операция может быть выполнена кем-т на стороне: удаленным веб-узлом, сервером или другим устройством за пределами текущег вычислительного устройства. Основное свойство таких операций в том, что начало такой операции требует значительн меньшего времени, чем основная работа. Что позволяет выполнять множество асинхронны операций одновременно даже на устройстве с небольшим числом вычислительных устройств. CPU-bound и IO-Bound операции Еще один важный момент, с точки зрения разработчика - разница между CPU-bound и IO-boun операциями. CPU-Bound операции нагружают вычислительные мощности текущего устройства а IO-Bound позволяют выполнить задачу вне текущей железки. Разница важна тем, что число одновременных операций зависит от того, к какой категори они относятся. Вполне нормально запустить параллельно сотни IO-Bound операций, и надеяться что хватит ресурсов обработать все результаты. Запускать же параллельно слишком большо число CPU-bound операций (больше, чем число вычислительных устройств) бессмысленно. Возвращаясь к исходному вопросу: нет смысла выполнять в 1000 потоков метод Calc если он является CPU-Intensive (нагружает центральный процессор), поскольку это приведе к падению общей эффективности вычислений. ОС-ке придется переключать несколько доступны ядер для обслуживания сотен потоков. А этот процесс не является дешевым. Самым простым и эффективным способом решения CPU-Intensive задачи, заключается использовании идиомы Fork-Join: задачу (например, входные данные) нужно разбить на определенно число подзадач, которые можно выполнить параллельно. Каждая подзадача должна быть независимо и не обращаться к разделяемым переменным/памяти. Затем, нужно собрать промежуточны результаты и объединить их. Именно на этом принципе основан PLINQ. О чем можно почитать тут: Джозеф Албахари Параллельное программирование. Выглядит это очень интересно: IEnumerable yourData = GetYourData(); var result = yourData.AsParallel() // начинаем обрабатывать параллельно .Select(d => ComputeMD5(d)) // Вычисляем параллельно .Where(md5 => IsValid(md5)) .ToArray(); // Возврвщаемся к синхронной модели В этом случае, число потоков будет контролироваться библиотечным кодом в недрах CLR/TP и метод ComputeMD5 будет вызван параллельно N-раз на компьютере с N-процессорами (ядрами).

Ответ 2



Многопоточное программирование подразумевает, что код приложения выполняется в разны потоках. Например, есть главный поток UI, и несколько рабочих потоков, которые выполняю тяжелые вычисления, результаты которых затем выводятся на UI. Асинхронное программирование подразумевает инициацию некоторой операцию, об окончани которой главный поток узнает спустя некоторое время. Обычно это применяется для работ с системой ввода-вывода: диски, сеть и т.д. При этом, если это все сделано правильно никакого потока нет. Также часто под выражением "выполнить асинхронно" подразумевают что выполнение некоторого кода будет произведено не в текущем потоке, а в соседнем при этом текущий поток не будет заблокирован. Но мой взгляд, это не совсем корректно. Параллельное программирование подразумевает разбиение одной задачи на независимы подзадачи, которые можно рассчитать параллельно, а затем объединить результаты. Оди из примеров -- это map-reduce. Это частный случай многопоточного программирования.

Ответ 3



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

Ответ 4



Многопоточная работа - работа нескольких потоков. При этом не факт, что все поток будут активны. Возможно, что работает один поток, а другой спит. Когда первый пото закончил работу, он может разбудить второй, а сам заснуть Распараллеливание - разбиение одной задачи на независимые подзадачи и выполнени этих подзадач одновременно разными потоками. Пример: вычисление среднего значения двумерног массива. Каждый поток может посчитать сумму своей строки, а потом все это объединить Асинхронная работа - когда мы ставим какую-то задачу, но не ждем ответа, а продолжае делать свою работу. А когда будет готов ответ - нас уведомят. Пример: попросить секретар сварить кофе. Мы не ждем этого кофе и занимаемся своими делами, а когда кофе будет гото - нам его принесут. Количество ядер процессора определяет только сколько потоков могут одновременно быт в активном состоянии

Комментариев нет:

Отправить комментарий