ejemplos - multitarea en python
El multiprocesamiento de Python utiliza solo un nĂșcleo (4)
De alguna forma, la afinidad de la CPU ha cambiado. Tuve este problema con numpy antes. Encontré la solución aquí http://bugs.python.org/issue17038#msg180663
Estoy probando un fragmento de código de la documentación estándar de python para aprender a usar el módulo de multiprocesamiento. El código está pegado al final de este mensaje. Estoy usando Python 2.7.1 en Ubuntu 11.04 en una máquina quad core (que de acuerdo con el monitor del sistema me da ocho núcleos debido a hyper threading)
Problema: toda la carga de trabajo parece estar programada para un solo núcleo, que se acerca al 100% de utilización, a pesar de que se inician varios procesos. Ocasionalmente, toda la carga de trabajo migra a otro núcleo, pero la carga de trabajo nunca se distribuye entre ellos.
¿Alguna idea de por qué esto es así?
Atentamente,
Pablo
#
# Simple example which uses a pool of workers to carry out some tasks.
#
# Notice that the results will probably not come out of the output
# queue in the same in the same order as the corresponding tasks were
# put on the input queue. If it is important to get the results back
# in the original order then consider using `Pool.map()` or
# `Pool.imap()` (which will save on the amount of code needed anyway).
#
# Copyright (c) 2006-2008, R Oudkerk
# All rights reserved.
#
import time
import random
from multiprocessing import Process, Queue, current_process, freeze_support
#
# Function run by worker processes
#
def worker(input, output):
for func, args in iter(input.get, ''STOP''):
result = calculate(func, args)
output.put(result)
#
# Function used to calculate result
#
def calculate(func, args):
result = func(*args)
return ''%s says that %s%s = %s'' % /
(current_process().name, func.__name__, args, result)
#
# Functions referenced by tasks
#
def mul(a, b):
time.sleep(0.5*random.random())
return a * b
def plus(a, b):
time.sleep(0.5*random.random())
return a + b
def test():
NUMBER_OF_PROCESSES = 4
TASKS1 = [(mul, (i, 7)) for i in range(500)]
TASKS2 = [(plus, (i, 8)) for i in range(250)]
# Create queues
task_queue = Queue()
done_queue = Queue()
# Submit tasks
for task in TASKS1:
task_queue.put(task)
# Start worker processes
for i in range(NUMBER_OF_PROCESSES):
Process(target=worker, args=(task_queue, done_queue)).start()
# Get and print results
print ''Unordered results:''
for i in range(len(TASKS1)):
print ''/t'', done_queue.get()
# Add more tasks using `put()`
for task in TASKS2:
task_queue.put(task)
# Get and print some more results
for i in range(len(TASKS2)):
print ''/t'', done_queue.get()
# Tell child processes to stop
for i in range(NUMBER_OF_PROCESSES):
task_queue.put(''STOP'')
test()
He encontrado un trabajo para usar Parallel Python. Sé que esta no es la solución que usa las bibliotecas básicas de Python, pero el código es simple y funciona como un encanto
Intenta reemplazar el tiempo. time.sleep
con algo que realmente requiera CPU y verás que el multiprocess
funciona muy bien. Por ejemplo:
def mul(a, b):
for i in xrange(100000):
j = i**2
return a * b
def plus(a, b):
for i in xrange(100000):
j = i**2
return a + b
El multiprocesamiento no significa que usará todos los núcleos de un procesador, solo obtendrá múltiples procesos y no procesos de varios núcleos, esto sería manejado por el sistema operativo y es incierto, la pregunta @Devraj publicada en los comentarios tiene respuestas para lograr lo que deseo.