Resumo : neste tutorial, você aprenderá como executar código em paralelo usando o módulo de multiprocessamento Python.
Introdução ao multiprocessamento Python
Geralmente, os programas lidam com dois tipos de tarefas:
- Tarefas vinculadas a E/S: se uma tarefa realiza muitas operações de entrada/saída, ela é chamada de tarefa vinculada a E/S. Exemplos típicos de tarefas vinculadas a E/S são ler arquivos, gravar em arquivos, conectar-se a bancos de dados e fazer uma solicitação de rede. Para tarefas vinculadas a E/S, você pode usar multithreading para acelerá-las.
- Tarefas vinculadas à CPU: quando uma tarefa realiza muitas operações usando uma CPU, ela é chamada de tarefa vinculada à CPU. Por exemplo, cálculo de números, redimensionamento de imagens e streaming de vídeo são tarefas vinculadas à CPU. Para acelerar o programa com muitas tarefas vinculadas à CPU, você usa multiprocessamento.
O multiprocessamento permite que dois ou mais processadores processem simultaneamente duas ou mais partes diferentes de um programa.
Em Python, você usa o multiprocessing
módulo para implementar multiprocessamento.
Exemplo de multiprocessamento Python
Veja o seguinte programa:
import time
def task():
result = 0
for _ in range(10**8):
result += 1
return result
if __name__ == '__main__':
start = time.perf_counter()
task()
task()
finish = time.perf_counter()
print(f'It took {finish-start:.2f} second(s) to finish')
Linguagem de código: Python ( python )
Saída:
It took 5.55 second(s) to finish
Linguagem de código: Python ( python )
Como funciona.
Primeiro, definir a
função é uma tarefa vinculada à CPU porque ela executa um cálculo pesado executando um loop por 100 milhões de iterações e incrementando uma variável task()
result
:
def task():
result = 0
for _ in range(10**8):
result += 1
return result
Linguagem de código: Python ( python )
Segundo, chame as task()
funções duas vezes e registre o tempo de processamento:
if __name__ == '__main__':
start = time.perf_counter()
task()
task()
finish = time.perf_counter()
print(f'It took {finish-start: .2f} second(s) to finish')
Linguagem de código: Python ( python )
Em nosso computador, demorou 5,55 segundos para ser concluído.
Usando módulo de multiprocessamento
O programa a seguir usa o módulo de multiprocessamento, mas leva menos tempo:
import time
import multiprocessing
def task() -> int:
result = 0
for _ in range(10**8):
result += 1
return result
if __name__ == '__main__':
start = time.perf_counter()
p1 = multiprocessing.Process(target=task)
p2 = multiprocessing.Process(target=task)
p1.start()
p2.start()
p1.join()
p2.join()
finish = time.perf_counter()
print(f'It took {finish-start:.2f} second(s) to finish')
Linguagem de código: Python ( python )
Saída:
It took 3.43 second(s) to finish
Linguagem de código: Python ( python )
Como funciona.
Primeiro, importe o módulo de multiprocessamento:
import multiprocessing
Linguagem de código: Python ( python )
Segundo, crie dois processos e passe a função de tarefa para cada um:
p1 = multiprocessing.Process(target=task)
p2 = multiprocessing.Process(target=task)
Linguagem de código: Python ( python )
Observe que o Process()
construtor retorna um novo Process
objeto.
Terceiro, chame o start()
método dos Process
objetos para iniciar o processo:
p1.start()
p2.start()
Linguagem de código: Python ( python )
Por fim, aguarde a conclusão dos processos chamando o join()
método:
p1.join()
p2.join()
Linguagem de código: Python ( python )
Exemplo prático de multiprocessamento Python
Usaremos o módulo de multiprocessamento para redimensionar as imagens de alta resolução.
Primeiro, instale a Pillow
biblioteca para processamento de imagens:
pip install Pillow
Linguagem de código: Python ( python )
Segundo, desenvolva um programa que crie miniaturas das imagens na images
pasta e salve-as na thumbs
pasta:
import time
import os
from PIL import Image, ImageFilter
filenames = [
'images/1.jpg',
'images/2.jpg',
'images/3.jpg',
'images/4.jpg',
'images/5.jpg',
]
def create_thumbnail(filename, size=(50,50), thumb_dir ='thumbs'):
# open the image
img = Image.open(filename)
# apply the gaussian blur filter
img = img.filter(ImageFilter.GaussianBlur())
# create a thumbnail
img.thumbnail(size)
# save the image
img.save(f'{thumb_dir}/{os.path.basename(filename)}')
# display a message
print(f'{filename} was processed...')
if __name__ == '__main__':
start = time.perf_counter()
for filename in filenames:
create_thumbnail(filename)
finish = time.perf_counter()
print(f'It took {finish-start:.2f} second(s) to finish')
Linguagem de código: Python ( python )
Em nosso computador, demorou cerca de 4,06 segundos para ser concluído:
images/1.jpg was processed...
images/2.jpg was processed...
images/3.jpg was processed...
images/4.jpg was processed...
images/5.jpg was processed...
It took 4.06 second(s) to finish
Linguagem de código: Python ( python )
Terceiro, modifique o programa para usar multiprocessamento. Cada processo criará uma miniatura para uma imagem:
import time
import os
from PIL import Image, ImageFilter
import multiprocessing
filenames = [
'images/1.jpg',
'images/2.jpg',
'images/3.jpg',
'images/4.jpg',
'images/5.jpg',
]
def create_thumbnail(filename, size=(50,50), thumb_dir ='thumbs'):
# open the image
img = Image.open(filename)
# apply the gaussian blur filter
img = img.filter(ImageFilter.GaussianBlur())
# create a thumbnail
img.thumbnail(size)
# save the image
img.save(f'{thumb_dir}/{os.path.basename(filename)}')
# display a message
print(f'{filename} was processed...')
def main():
start = time.perf_counter()
# create processes
processes = [multiprocessing.Process(target=create_thumbnail, args=[filename])
for filename in filenames]
# start the processes
for process in processes:
process.start()
# wait for completion
for process in processes:
process.join()
finish = time.perf_counter()
print(f'It took {finish-start:.2f} second(s) to finish')
if __name__ == '__main__':
main()
Linguagem de código: Python ( python )
Saída:
images/5.jpg was processed...
images/4.jpg was processed...
images/1.jpg was processed...
images/3.jpg was processed...
images/2.jpg was processed...
It took 2.92 second(s) to finish
Linguagem de código: Python ( python )
Nesse caso, a saída mostra que o programa processou as imagens mais rapidamente.
Resumo
- Use o multiprocessamento Python para executar código em paralelo para lidar com tarefas vinculadas à CPU.