Иван Волков, да, примитивные типы данных и базовые коллекции можно прокинуть в процессы. Но когда речь заходит о чём-то нетипичном вроде numpy-массивов, дело усложняется.
Кроме того, не все блокирующие IO-bound задачи можно переписать на асинхронщину. Иногда имеешь дело с ситуацией, когда есть только синхронная библиотека. Например, графический интерфейс + IO-bound задача.
В таких случаях кроме потоков, вариантов остаётся немного - GUI обычно синхронный, а проброс данных через процесс не всегда удобен.
Не очень понял в чем будет заключаться проблема с numpy-массивами. Ведь в контексте питона из стандартной библиотеки для работы с CPU bound подходит только multiprocessing.
Иван Волков, я писал программу, которая распараллеливает вычисления через мультипроцессинг. Numpy-массивы multiprocessing не умеет сериализовать для передачи, приходится конвертировать в списки и обратно. Выигрыш всё ещё есть, впрочем.
В общем, если коротко: мультипроцессинг имеет солидный оверхед и ряд ограничений. Для реально тяжелых CPU-bound задач он имеет смысл, но если нужно просто отпараллелить небольшой кусок кода с минимальными правками - потоки в разы проще.