Ответ 1
Они связаны, но разные.
Многопоточность, обычно называемая многопоточностью, относится к использованию нескольких потоков выполнения в одном процессе. Обычно это относится к простому случаю использования небольшого набора потоков, каждый из которых выполняет разные задачи, которые должны выполняться или могут быть полезны одновременно. Например, приложение с графическим интерфейсом может иметь один элемент рисования потока, другой поток реагирует на такие события, как щелчки мыши, а другой поток выполняет некоторую фоновую обработку.
Однако, когда количество потоков, каждый из которых делает свое дело, доведено до предела, мы обычно начинаем говорить о агентном подходе.
Подход, основанный на задачах, относится к конкретной стратегии в разработке программного обеспечения, где в абстрактных терминах вы динамически создаете "задачи", которые должны быть выполнены, и эти задачи выбираются диспетчером задач, который назначает задачи потокам, которые могут их выполнять. Это скорее программная архитектура. Преимущество здесь состоит в том, что выполнение всей программы представляет собой последовательность ретранслируемых задач (задача A завершена → вызвать задачу B, когда и задача B, и задача C выполнены → вызвать задачу D и т.д.), А не необходимость написать большую функцию или программу, которая выполняет каждую задачу одну за другой. Это дает гибкость, когда неясно, какие задачи будут занимать больше времени, чем другие, и когда задачи слабо связаны. Обычно это реализуется с помощью пула потоков (потоков, ожидающих назначения задачи) и некоторого интерфейса передачи сообщений (MPI) для обмена данными и "контрактами" задачи.
Асинхронное программирование не относится к многопоточному программированию, хотя оба они очень часто связаны (и хорошо работают вместе). Синхронная программа должна завершить каждый шаг, прежде чем перейти к следующему. Асинхронная программа запускает шаг, переходит к другим шагам, которые не требуют результата первого шага, а затем проверяет результат первого шага, когда требуется его результат.
То есть синхронная программа может выглядеть примерно так: "выполнить эту задачу", "дождаться выполнения", "сделать что-то с результатом" и "перейти к чему-то другому". В отличие от этого, асинхронная программа может выглядеть примерно так: "Я собираюсь начать задание, и мне понадобится результат позже, но он мне сейчас не нужен", "А пока я Я сделаю что-нибудь еще "," Я не смогу сделать ничего другого, пока не получу результат первого шага, поэтому я буду ждать его, если он не готов ", и" перейду к чему-то другому ".
Обратите внимание, что "асинхронный" относится к очень широкой концепции, которая всегда включает в себя некоторую форму "начни какую-то работу и скажи мне, когда она сделана" вместо традиционной "сделай это сейчас!". Это не требует многопоточности, и в этом случае это просто становится выбором дизайна программного обеспечения (который часто включает функции обратного вызова и тому подобное для обеспечения "уведомления" об асинхронном результате). С несколькими потоками он становится более мощным, так как вы можете делать различные вещи параллельно, пока работает асинхронная задача. В крайнем случае, она может стать более полноценной архитектурой, подобной подходу, основанному на задачах (который является одним из видов техники асинхронного программирования).
Я думаю, что то, что вам нужно, больше соответствует еще одной концепции: параллельные вычисления (или параллельная обработка). Этот подход больше касается разделения большой задачи обработки на более мелкие части и параллельной обработки всех частей, а затем объединения результатов. Вы должны посмотреть на библиотеки, такие как OpenMP или OpenCL/CUDA (для GPGPU). Тем не менее, вы можете использовать многопоточность для параллельной обработки.
но, очевидно, асинхронное программирование не обязательно означает, что вы используете несколько ядер?
Асинхронное программирование не обязательно включает в себя что-то, происходящее одновременно в нескольких потоках. Это может означать, что ОС делает что-то от вашего имени за кулисами (и будет уведомлять вас о завершении этой работы), как в случае асинхронного ввода-вывода, который происходит без создания каких-либо потоков. Это сводится к тому, чтобы быть выбором дизайна программного обеспечения.
Зачем вам это делать, если у вас не было нескольких ядер для использования в своих интересах?
Если у вас нет нескольких ядер, многопоточность все же может повысить производительность, повторно используя "время ожидания" (например, не "блокируйте" обработку, ожидающую файловый или сетевой ввод-вывод, или ожидая, когда пользователь нажмет кнопка мыши). Это означает, что программа может выполнять полезную работу, ожидая этих вещей. Помимо этого, он может обеспечить гибкость дизайна и заставить вещи работать одновременно, что часто делает пользователей счастливее. Тем не менее, вы правы в том, что до многоядерных CPU
не было такого большого стимула для многопоточности, так как выгоды часто не оправдывают накладные расходы.