No multiprocessamento, você aproveita várias CPUs para distribuir seus cálculos. Como cada uma das CPUs funciona em paralelo, você é capaz de executar várias tarefas simultaneamente. Você gostaria de usar multiprocessamento para tarefas vinculadas à CPU . Um exemplo seria tentar calcular a soma de todos os elementos de uma lista enorme. Se sua máquina tiver 8 núcleos, você pode "cortar" a lista em 8 listas menores e calcular a soma de cada uma dessas listas separadamente em núcleos separados e, em seguida, apenas somar esses números. Você obterá uma aceleração de ~ 8x ao fazer isso.
Em threadingvocê não precisa de múltiplas CPUs. Imagine um programa que envia muitas solicitações HTTP para a web. Se você usasse um programa de thread único, ele interromperia a execução (bloco) a cada solicitação, aguardaria uma resposta e, em seguida, continuaria assim que recebesse uma resposta. O problema aqui é que sua CPU não está realmente funcionando enquanto espera que algum servidor externo faça o trabalho; ele poderia realmente ter feito algum trabalho útil nesse ínterim! A solução é usar threads - você pode criar muitos deles, cada um responsável por solicitar algum conteúdo da web. A coisa boa sobre threads é que, mesmo se eles rodarem em uma CPU, a CPU de vez em quando "congela" a execução de uma thread e pula para a execução da outra (é chamada de troca de contexto e acontece constantemente em não determinística intervalos). - use threading.
asyncio é essencialmente threading onde não a CPU, mas você, como um programador (ou na verdade sua aplicação), decide onde e quando a troca de contexto acontece . Em Python, você usa uma await
palavra-chave para suspender a execução de sua co-rotina (definida usando a async
palavra-chave).