Python - Programación multiproceso
Página anteriorPágina siguiente
Ejecutar varios subprocesos es similar a ejecutar varios programas diferentes al mismo tiempo, pero con los siguientes beneficios:
-
Múltiples subprocesos dentro de un proceso comparten el mismo espacio de datos con el subproceso principal y, por lo tanto, pueden compartir información o comunicarse entre sí más fácilmente que si fueran procesos separados.
-
Los subprocesos a veces se denominan procesos ligeros y no requieren mucha sobrecarga de memoria; son más baratos que los procesos.
Un hilo tiene un comienzo, una secuencia de ejecución y una conclusión. Tiene un puntero de instrucciones que realiza un seguimiento de dónde se está ejecutando actualmente dentro de su contexto.
-
Puede ser anticipado (interrumpido)
-
Se puede poner en espera temporalmente (también conocido como suspensión) mientras se ejecutan otros subprocesos; esto se denomina ceder.
Inicio de un hilo nuevo
Para generar otro hilo, debe llamar al siguiente método disponible en hilo módulo −
thread.start_new_thread ( function, args[, kwargs] )
Esta llamada de método permite una forma rápida y eficiente de crear nuevos subprocesos tanto en Linux como en Windows.
La llamada al método regresa inmediatamente y el hilo secundario comienza y llama a la función con la lista pasada de args . Cuando la función regresa, el hilo termina.
Aquí, argumentos es una tupla de argumentos; use una tupla vacía para llamar a la función sin pasar ningún argumento. kwargs es un diccionario opcional de argumentos de palabras clave.
Ejemplo
#!/usr/bin/python import thread import time # Define a function for the thread def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # Create two threads as follows try: thread.start_new_thread( print_time, ("Thread-1", 2, ) ) thread.start_new_thread( print_time, ("Thread-2", 4, ) ) except: print "Error: unable to start thread" while 1: pass
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009
Aunque es muy efectivo para subprocesos de bajo nivel, pero el subproceso El módulo es muy limitado en comparación con el módulo de subprocesamiento más nuevo.
El enhebrado Módulo
El módulo de creación de subprocesos más nuevo incluido con Python 2.4 proporciona un soporte de alto nivel mucho más potente para subprocesos que el módulo de subprocesos analizado en la sección anterior.
El enhebrado módulo expone todos los métodos del hilo módulo y proporciona algunos métodos adicionales −
-
hilos.activeCount() − Devuelve el número de objetos de hilo que están activos.
-
subprocesamiento.subprocesoactual() − Devuelve el número de objetos de subprocesos en el control de subprocesos de la persona que llama.
-
enhebrar.enumerar() − Devuelve una lista de todos los objetos de hilo que están actualmente activos.
Además de los métodos, el módulo de subprocesamiento tiene el Subproceso clase que implementa subprocesos. Los métodos proporcionados por el Thread clase son los siguientes −
-
ejecutar() − El método run() es el punto de entrada para un hilo.
-
inicio() − El método start() inicia un hilo llamando al método de ejecución.
-
unir([hora]) − El join() espera a que terminen los subprocesos.
-
está Vivo() − El método isAlive() comprueba si un subproceso aún se está ejecutando.
-
obtenerNombre() − El método getName() devuelve el nombre de un hilo.
-
establecerNombre() − El método setName() establece el nombre de un hilo.
Crear hilo usando Threading Módulo
Para implementar un nuevo subproceso utilizando el módulo de subprocesos, debe hacer lo siguiente −
-
Definir una nueva subclase del Thread clase.
-
Anular __init__(self [,args]) para agregar argumentos adicionales.
-
Luego, invalide el método run(self [,args]) para implementar lo que debe hacer el subproceso cuando se inicia.
Una vez que haya creado el nuevo Hilo subclase, puede crear una instancia de ella y luego iniciar un nuevo hilo invocando el start() , que a su vez llama a run() método.
Ejemplo
#!/usr/bin/python import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name print_time(self.name, 5, self.counter) print "Exiting " + self.name def print_time(threadName, counter, delay): while counter: if exitFlag: threadName.exit() time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() print "Exiting Main Thread"
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Thu Mar 21 09:10:03 2013 Thread-1: Thu Mar 21 09:10:04 2013 Thread-2: Thu Mar 21 09:10:04 2013 Thread-1: Thu Mar 21 09:10:05 2013 Thread-1: Thu Mar 21 09:10:06 2013 Thread-2: Thu Mar 21 09:10:06 2013 Thread-1: Thu Mar 21 09:10:07 2013 Exiting Thread-1 Thread-2: Thu Mar 21 09:10:08 2013 Thread-2: Thu Mar 21 09:10:10 2013 Thread-2: Thu Mar 21 09:10:12 2013 Exiting Thread-2
Sincronización de subprocesos
El módulo de creación de subprocesos proporcionado con Python incluye un mecanismo de bloqueo fácil de implementar que le permite sincronizar subprocesos. Se crea un nuevo bloqueo llamando a Lock() método, que devuelve el nuevo bloqueo.
La adquirir(bloquear) El método del nuevo objeto de bloqueo se usa para forzar que los subprocesos se ejecuten sincrónicamente. El bloqueo opcional El parámetro le permite controlar si el subproceso espera para adquirir el bloqueo.
Si bloqueo se establece en 0, el subproceso regresa inmediatamente con un valor de 0 si no se puede adquirir el bloqueo y con un 1 si se adquirió el bloqueo. Si el bloqueo se establece en 1, el subproceso se bloquea y espera a que se libere el bloqueo.
La liberación() El método del nuevo objeto de bloqueo se utiliza para liberar el bloqueo cuando ya no es necesario.
Ejemplo
#!/usr/bin/python import threading import time class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name # Get lock to synchronize threads threadLock.acquire() print_time(self.name, self.counter, 3) # Free lock to release next thread threadLock.release() def print_time(threadName, delay, counter): while counter: time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1 threadLock = threading.Lock() threads = [] # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() # Add threads to thread list threads.append(thread1) threads.append(thread2) # Wait for all threads to complete for t in threads: t.join() print "Exiting Main Thread"
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Starting Thread-1 Starting Thread-2 Thread-1: Thu Mar 21 09:11:28 2013 Thread-1: Thu Mar 21 09:11:29 2013 Thread-1: Thu Mar 21 09:11:30 2013 Thread-2: Thu Mar 21 09:11:32 2013 Thread-2: Thu Mar 21 09:11:34 2013 Thread-2: Thu Mar 21 09:11:36 2013 Exiting Main Thread
Cola de prioridad multiproceso
La Cola El módulo le permite crear un nuevo objeto de cola que puede contener una cantidad específica de elementos. Existen los siguientes métodos para controlar la cola −
-
obtener() − El get() elimina y devuelve un elemento de la cola.
-
poner() − El puesto agrega un elemento a una cola.
-
qtamaño() − El qsize() devuelve el número de elementos que están actualmente en la cola.
-
vacío() − El vacío( ) devuelve True si la cola está vacía; de lo contrario, Falso.
-
completo() − full() devuelve True si la cola está llena; de lo contrario, Falso.
Ejemplo
#!/usr/bin/python import Queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self): print "Starting " + self.name process_data(self.name, self.q) print "Exiting " + self.name def process_data(threadName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() queueLock.release() print "%s processing %s" % (threadName, data) else: queueLock.release() time.sleep(1) threadList = ["Thread-1", "Thread-2", "Thread-3"] nameList = ["One", "Two", "Three", "Four", "Five"] queueLock = threading.Lock() workQueue = Queue.Queue(10) threads = [] threadID = 1 # Create new threads for tName in threadList: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # Fill the queue queueLock.acquire() for word in nameList: workQueue.put(word) queueLock.release() # Wait for queue to empty while not workQueue.empty(): pass # Notify threads it's time to exit exitFlag = 1 # Wait for all threads to complete for t in threads: t.join() print "Exiting Main Thread"
Cuando se ejecuta el código anterior, produce el siguiente resultado −
Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-1 processing One Thread-2 processing Two Thread-3 processing Three Thread-1 processing Four Thread-2 processing Five Exiting Thread-3 Exiting Thread-1 Exiting Thread-2 Exiting Main Thread
python
- Formado de hilo vs enrollado de hilo:¿Cuál es la diferencia?
- Tipos de datos de Python
- Operadores de Python
- Python mientras bucle
- Declaración de paso de Python
- Argumentos de la función de Python
- Diccionario de Python
- Programación orientada a objetos de Python
- Python - Programación de redes
- Python - Programación de extensiones con C
- Ciclo de roscado Fanuc G76 para principiantes