[Python]Duda con thread

Iniciado por .:UND3R:., 9 Mayo 2015, 05:13 AM

0 Miembros y 1 Visitante están viendo este tema.

.:UND3R:.

Hola a todos, saben tengo una duda a ver si me pueden ayudar con la idea, intentaré ser lo más específico y sencillo ya que entiendo que se requieren detalles para que me puedan ayudar.

Tengo una lista de muchos datos, usaré como ejemplo una lista de muchos números:

Código (python) [Seleccionar]
lista = [1, 9, 2, 12, 5, 2, 0, 123, 32, 4, .........] # (miles)

pretendo hacer una serie de operaciones matemáticas (como ejemplo sacar la raíz de cada número) con cada número de la lista, pero si lo hago uno por uno, no terminaría nunca.

por lo cual mi idea sería usar Threads para solventar mi problema.

aquí la pregunta:

¿Cómo podría hacer para que se vayan tomando de a 4 (por dar un ejemplo de num.) valores de la lista y estos una vez que terminen, tomen otros 4 más?

No sé si se entienda, pero la idea sería como hacer un buffer de 4 operaciones matemáticas (uno en cada thread) si una termina, o dos, se vuelvan a crear otros thread, es decir que siempre se estén realizando operaciones matemáticas (4 a la vez) hasta que se termine toda la lista completa?

Que difícil explicar mi duda, si me dieran un ejemplo estaría más que feliz.

Muchas gracias y saludos.

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

Eleкtro

#1
Creo que se ha entendido a la perfección lo que pretendes hacer, no te preocupes :P, aquí te escribo este ejemplo bien documentado!.

Basicamente inicio una cantidad específica de threads (4) a los que les voy pasando tareas que realizar, es decir, una cantidad específica de valores que procesar, en este ejemplo es 1 valor por thread, por lo que siempre hay 4 threads activos procesando de forma asíncrona 1 valor de la pila de valores.

Código (python) [Seleccionar]
# -*- coding: Windows-1252 -*-
from Queue import Queue; from threading import Thread, current_thread

# El trabajo que realizará cada hilo.
def MathWorker(queue):
   # El While mantiene activo el hilo para aceptar nuevas tareas.
   while True:
       # print current_thread().getName() + " work started."
       # Itero los valores del siguiente item en la cola.
       for value in queue.get():
           # Hacer operaciones aritméticas aquí.
           print "value: " + str(value)

       queue.task_done()
       # print current_thread().getName() + " work done." + "\n"

# La colección de valores.
valueList = [
             1, 2, 3, 4,
             5, 6, 7, 8,
             9
           ]

# La cola (o pila) de espera.
mathQueue = Queue(maxsize=0)

# La cantidad máxima de hilos simultaneos.
maxThreads = 4

# La cantidad máxima de valores simultaneos por hilo.
maxValues = 1

# Voy insertando los valores simultaneos por hilo, en la cola (o pila) de espera.
for index in range(0, len(valueList), maxValues): # range(start, stop, step)
   mathQueue.put(valueList[index:(index+maxValues)])

# Inicio los hilos.
for value in range(maxThreads):
   worker = Thread(target=MathWorker, args=(mathQueue,))
   worker.setDaemon(True)
   worker.start()

# Espero a que la cola (o pila) se vacie.
mathQueue.join()


Esta linea la he documentado 'print current_thread().getName()' por que queda muy feo cuando hay varios threads activos debido a la asincronía, pero este sería el resultado de ejecución con un solo thread activo:

Thread-1 work started.
value: 1
Thread-1 work done.

Thread-1 work started.
value: 2
Thread-1 work done.

Thread-1 work started.
value: 3
Thread-1 work done.

Thread-1 work started.
value: 4
Thread-1 work done.

y así hasta el 9...


PD: Me ha tocado desempolvar Python y volver a instalarlo, que practicamente no lo uso nunca pa nah, pero te lo mereces :).

Saludos!








.:UND3R:.

Eres un mounstrillo, más tarde lo probaré, de verdad muchísimas gracias, al verlo a simple vista estoy más que seguro que es lo que busco, muchísimas gracias :D

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

.:UND3R:.

Hola electro, te comento que me funciona a la perfección pero tengo un pequeño problema y es que tengo la posibilidad de que se produzcan errores dentro de MathWorker por lo cual intenté con poner un bloque TRY and EXCEPT pero no funciona, ya que se queda esperando en mathQueue.join().

Mi pregunta sería: ¿Cómo puedo manejar una excepción dentro de MathWorker sin estropear la idea principal (se realizan cuatro tareas pero que todas terminen)?

Saludos y gracias nuevamente

Solicitudes de crack, keygen, serial solo a través de mensajes privados (PM)

Eleкtro

Cita de: .:UND3R:. en 11 Mayo 2015, 07:35 AMMi pregunta sería: ¿Cómo puedo manejar una excepción dentro de MathWorker sin estropear la idea principal (se realizan cuatro tareas pero que todas terminen)?

Si estás controlando correctamente la excepción entonces no se debería detener la ejecución del thread.

Creo que vas a tener que mostrar lo que tengas escrito en el bloque del except:, y el tipo de excepción que te lanza.

Recuerda que siempre puedes utilizar la declaración pass para ignorar la excepción:

Código (python) [Seleccionar]
...
for value in queue.get():
   try:
       0 + str(value)
   except BaseException as e:
       # print e.message, e.args
       pass
queue.task_done()
...


saludos