Threading vs Task-based vs асинхронное программирование

Я новичок в этой концепции. Это те же или разные вещи? В чем разница? Мне очень нравится идея запуска сразу двух процессов, например, если у меня есть несколько больших файлов для загрузки в мою программу, мне бы хотелось загрузить как можно больше из них одновременно, а не ждать по одному за раз. И при работе с большим файлом, таким как wav файл, было бы здорово разбить его на части и обработать сразу несколько кусков, а затем снова сместить их. Что я хочу изучить, чтобы узнать, как это сделать?

Изменить: Кроме того, я знаю, что использование более одного ядра на многоядерном процессоре здесь где-то здесь, но, по-видимому, асинхронное программирование не обязательно означает, что вы используете несколько ядер? Зачем вам это делать, если у вас не было нескольких ядер, чтобы воспользоваться преимуществами?

Ответы

Ответ 1

Они связаны, но разные.

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

Однако, когда количество потоков, каждый из которых делает свое дело, доведено до предела, мы обычно начинаем говорить о агентном подходе.

Подход, основанный на задачах, относится к конкретной стратегии в разработке программного обеспечения, где в абстрактных терминах вы динамически создаете "задачи", которые должны быть выполнены, и эти задачи выбираются диспетчером задач, который назначает задачи потокам, которые могут их выполнять. Это скорее программная архитектура. Преимущество здесь состоит в том, что выполнение всей программы представляет собой последовательность ретранслируемых задач (задача A завершена → вызвать задачу B, когда и задача B, и задача C выполнены → вызвать задачу D и т.д.), А не необходимость написать большую функцию или программу, которая выполняет каждую задачу одну за другой. Это дает гибкость, когда неясно, какие задачи будут занимать больше времени, чем другие, и когда задачи слабо связаны. Обычно это реализуется с помощью пула потоков (потоков, ожидающих назначения задачи) и некоторого интерфейса передачи сообщений (MPI) для обмена данными и "контрактами" задачи.

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

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

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

Я думаю, что то, что вам нужно, больше соответствует еще одной концепции: параллельные вычисления (или параллельная обработка). Этот подход больше касается разделения большой задачи обработки на более мелкие части и параллельной обработки всех частей, а затем объединения результатов. Вы должны посмотреть на библиотеки, такие как OpenMP или OpenCL/CUDA (для GPGPU). Тем не менее, вы можете использовать многопоточность для параллельной обработки.

но, очевидно, асинхронное программирование не обязательно означает, что вы используете несколько ядер?

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

Зачем вам это делать, если у вас не было нескольких ядер для использования в своих интересах?

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

Ответ 2

Я думаю, что в целом все это связано с дизайном, а не с языком. То же самое относится к многоядерному программированию.

Чтобы отразить Джима, это не только сценарий загрузки файла. Как правило, вам нужно разработать все программное обеспечение для одновременной работы, чтобы ощутить реальную пользу многопотокового, основанного на задачах или асинхронного программирования.

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