Use essas técnicas para executar código simultaneamente e fornecer uma experiência de usuário mais tranquila.
Principais conclusões
- Simultaneidade e paralelismo são princípios fundamentais de execução de tarefas em computação, cada um com características distintas.
- A simultaneidade permite a utilização eficiente de recursos e melhor capacidade de resposta dos aplicativos, enquanto o paralelismo é crucial para desempenho e escalabilidade ideais.
- Python oferece opções para lidar com simultaneidade, como threading e programação assíncrona com asyncio, bem como paralelismo usando o módulo multiprocessing.
Simultaneidade e paralelismo são duas técnicas que permitem executar vários programas simultaneamente. Python tem múltiplas opções para lidar com tarefas simultaneamente e em paralelo, o que pode ser confuso.
Explore as ferramentas e bibliotecas disponíveis para implementar adequadamente a simultaneidade e o paralelismo em Python e como elas diferem.
Compreendendo a simultaneidade e o paralelismo
Simultaneidade e paralelismo referem-se a dois princípios fundamentais de execução de tarefas em computação. Cada um tem suas características distintas.
- Simultaneidade é a capacidade de um programa gerenciar múltiplas tarefas ao mesmo tempo sem necessariamente executá-las exatamente ao mesmo tempo. Gira em torno da ideia de intercalar tarefas, alternando entre elas de uma forma que pareça simultânea.
- Paralelismo, por outro lado, envolve a execução de múltiplas tarefas genuinamente em paralelo. Normalmente aproveita vários núcleos de CPU ou processadores. O paralelismo alcança uma verdadeira execução simultânea, permitindo que você execute tarefas com mais rapidez e é adequado para operações computacionalmente intensivas.
A importância da simultaneidade e do paralelismo
A necessidade de simultaneidade e paralelismo na computação não pode ser exagerada. Veja por que essas técnicas são importantes:
- Utilização de recursos: a simultaneidade permite a utilização eficiente dos recursos do sistema, garantindo que as tarefas progridam ativamente, em vez de aguardar ociosamente por recursos externos.
- Capacidade de resposta: a simultaneidade pode melhorar a capacidade de resposta dos aplicativos, especialmente em cenários que envolvem interfaces de usuário ou servidores web.
- Desempenho: o paralelismo é crucial para alcançar o desempenho ideal, especialmente em tarefas vinculadas à CPU, como cálculos complexos, processamento de dados e simulações.
- Escalabilidade: Tanto a simultaneidade quanto o paralelismo são essenciais para a construção de sistemas escaláveis.
- À prova de futuro: À medida que as tendências de hardware continuam a favorecer os processadores multicore, a capacidade de aproveitar o paralelismo se tornará cada vez mais necessária.
Simultaneidade em Python
Você pode obter simultaneidade em Python usando threading e programação assíncrona com a biblioteca asyncio.
Threading em Python
Threading é um mecanismo de simultaneidade Python que permite criar e gerenciar tarefas em um único processo. Threads são adequados para certos tipos de tarefas, especialmente aquelas que são vinculadas a E/S e podem se beneficiar da execução simultânea.
Python rosqueamento módulo fornece uma interface de alto nível para criar e gerenciar threads. Embora o GIL (Global Interpreter Lock) limite os threads em termos de paralelismo verdadeiro, eles ainda podem alcançar simultaneidade intercalando tarefas de forma eficiente.
O código abaixo mostra um exemplo de implementação de simultaneidade usando threads. Ele usa a biblioteca de solicitações Python para enviar uma solicitação HTTP, uma tarefa comum de bloqueio de E/S. Ele também usa o módulo de tempo para calcular o tempo de execução.
import requests
import time
import threadingurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]# function to request a URL
defdownload_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")# Execute without threads and measure execution time
start_time = time.time()for url in urls:
download_url(url)end_time = time.time()
print(f"Sequential download took {end_time - start_time:.2f} seconds\n")# Execute with threads, resetting the time to measure new execution time
start_time = time.time()
threads = []for url in urls:
thread = threading.Thread(target=download_url, args=(url,))
thread.start()
threads.append(thread)# Wait for all threads to complete
for thread in threads:
thread.join()
end_time = time.time()
print(f"Threaded download took {end_time - start_time:.2f} seconds")
Ao executar este programa, você verá o quão mais rápidas são as solicitações encadeadas do que as solicitações sequenciais. Embora a diferença seja apenas uma fração de segundo, você tem uma noção clara da melhoria de desempenho ao usar threads para tarefas vinculadas a E/S.
Programação assíncrona com Asyncio
assíncio fornece um loop de eventos que gerencia tarefas assíncronas chamadas corrotinas. Corrotinas são funções que você pode pausar e retomar, tornando-as ideais para tarefas vinculadas a E/S. A biblioteca é particularmente útil para cenários onde as tarefas envolvem espera por recursos externos, como solicitações de rede.
Você pode modificar o exemplo anterior de envio de solicitação para trabalhar com assíncio:
import asyncio
import aiohttp
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]# asynchronous function to request URL
asyncdefdownload_url(url):
asyncwith aiohttp.ClientSession() as session:
asyncwith session.get(url) as response:
content = await response.text()
print(f"Downloaded {url} - Status Code: {response.status}")# Main asynchronous function
asyncdefmain():
# Create a list of tasks to download each URL concurrently
tasks = [download_url(url) for url in urls]# Gather and execute the tasks concurrently
await asyncio.gather(*tasks)start_time = time.time()
# Run the main asynchronous function
asyncio.run(main())end_time = time.time()
print(f"Asyncio download took {end_time - start_time:.2f} seconds")
Usando o código, você pode baixar páginas da web simultaneamente usando assíncio e aproveite as operações de E/S assíncronas. Isso pode ser mais eficiente do que threading para tarefas vinculadas a E/S.
Paralelismo em Python
Você pode implementar o paralelismo usando Python multiprocessamento módulo, que permite aproveitar ao máximo os processadores multicore.
Multiprocessamento em Python
Python multiprocessamento O módulo fornece uma maneira de obter paralelismo criando processos separados, cada um com seu próprio interpretador Python e espaço de memória. Isso efetivamente ignora o Global Interpreter Lock (GIL), tornando-o adequado para tarefas vinculadas à CPU.
import requests
import multiprocessing
import timeurls = [
'https://www.google.com',
'https://www.wikipedia.org',
'https://www.makeuseof.com',
]# function to request a URL
defdownload_url(url):
response = requests.get(url)
print(f"Downloaded {url} - Status Code: {response.status_code}")defmain():
# Create a multiprocessing pool with a specified number of processes
num_processes = len(urls)
pool = multiprocessing.Pool(processes=num_processes)start_time = time.time()
pool.map(download_url, urls)
end_time = time.time()# Close the pool and wait for all processes to finish
pool.close()
pool.join()print(f"Multiprocessing download took {end_time-start_time:.2f} seconds")
main()
Neste exemplo, multiprocessamento gera vários processos, permitindo que o URL_download função seja executada em paralelo.
Quando usar simultaneidade ou paralelismo
A escolha entre simultaneidade e paralelismo depende da natureza das suas tarefas e dos recursos de hardware disponíveis.
Você pode usar simultaneidade ao lidar com tarefas vinculadas a E/S, como lendo e gravando em arquivos ou fazer solicitações de rede e quando as restrições de memória são uma preocupação.
Use o multiprocessamento quando você tiver tarefas vinculadas à CPU que podem se beneficiar do paralelismo verdadeiro e quando tiver um isolamento robusto entre tarefas, onde a falha de uma tarefa não deve afetar outras.
Aproveite as vantagens da simultaneidade e do paralelismo
Paralelismo e simultaneidade são formas eficazes de melhorar a capacidade de resposta e o desempenho do seu código Python. É importante compreender as diferenças entre esses conceitos e selecionar a estratégia mais eficaz.
Python oferece as ferramentas e os módulos necessários para tornar seu código mais eficaz por meio de simultaneidade ou paralelismo, independentemente de você estar trabalhando com processos vinculados à CPU ou vinculados à E/S.