Latest web development tutorials

python3 multithreading

Múltiples hilos ejecutados simultáneamente es similar a un número de diferentes programas, el funcionamiento multiproceso tiene las siguientes ventajas:

  • Utilizando hilos pueden ocupar mucho tiempo en el programa de tarea en el fondo de tratar.
  • La interfaz de usuario puede ser más atractivo, así que por ejemplo el usuario hace clic en un botón para accionar una cierta manipulación de eventos, puede estallar una barra de progreso para mostrar el progreso del proceso de
  • La velocidad de carrera podría acelerar
  • En realizado algunas tareas, tales como la espera de la entrada del usuario, la alfabetización de documentos y la red para enviar y recibir datos, el hilo es más útil. En este caso, se puede liberar algunos recursos valiosos, tales como el uso de memoria y así sucesivamente.

Temas en el proceso de implementación y el proceso es diferente. Cada uno tiene un hilo independiente que ejecute la entrada, la salida y la secuencia de los procedimientos para la ejecución de la orden. Sin embargo, el hilo no es capaz de realizar de forma independiente, debe existir según la aplicación, proporcionando múltiples hilos de ejecución controlados por la aplicación.

Cada hilo tiene su propio conjunto de registros de la CPU, llamado el contexto de la rosca, el contexto hilo refleja la última ejecución del estado de rosca registro de la CPU.

indicador de instrucción y el puntero de pila registros son los dos más importantes registros de contexto hilo, el hilo siempre se ejecute en el contexto del proceso, estas direcciones se utiliza para marcar el proceso que posee el hilo de espacio de direcciones de memoria.

  • Hilo pueda ser substituida (interrumpe).
  • En otros hilos se están ejecutando, el hilo se puede mantener en suspenso (también conocido como el sueño) - este es el hilo conductor de las concesiones.

Tema se puede dividir en:

  • Los hilos del núcleo: el núcleo del sistema operativo creado y destruido.
  • subprocesos de usuario: el soporte del núcleo y no requiere que el programa de usuario implementados hilo.

hilo común python3 dos módulos:

  • _thread
  • threading (recomendado)

Módulo mensaje ha sido abandonada. Los usuarios pueden utilizar el módulo threading en su lugar. Así, en python3 ya no pueden utilizar el módulo "hilo". Por razones de compatibilidad, hilo python3 cambiará el nombre de "_thread".


Empieza a aprender hilos Python

hilos de Python utilizan de dos formas: con una función o clases para ajustar el objeto hilo.

Funcional: Llame a la función _thread módulo start_new_thread () para generar un nuevo hilo. La sintaxis es la siguiente:

_thread.start_new_thread ( function, args[, kwargs] )

Descripción de parámetros:

  • - Función hilo.
  • args - los parámetros de hilos pasados ​​a la función, que debe ser un tipo tupla.
  • kwargs - opcionales.

Ejemplo:

#!/usr/bin/python3

import _thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count < 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

# 创建两个线程
try:
   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print ("Error: 无法启动线程")

while 1:
   pass

Los resultados de la salida programa anterior son los siguientes:

Thread-1: Wed Apr  6 11:36:31 2016
Thread-1: Wed Apr  6 11:36:33 2016
Thread-2: Wed Apr  6 11:36:33 2016
Thread-1: Wed Apr  6 11:36:35 2016
Thread-1: Wed Apr  6 11:36:37 2016
Thread-2: Wed Apr  6 11:36:37 2016
Thread-1: Wed Apr  6 11:36:39 2016
Thread-2: Wed Apr  6 11:36:41 2016
Thread-2: Wed Apr  6 11:36:45 2016
Thread-2: Wed Apr  6 11:36:49 2016

Después de ejecutar el proceso anterior puede pulsar Ctrl-C para salir.


módulo threading

Python3 proporciona soporte para enhebrar a través de dos _thread biblioteca estándar y roscado.

_thread proporciona un nivel bajo, el hilo original y una cerradura simple, que se compara con el módulo de función de enhebrado es todavía relativamente limitada.

Otros métodos, además de módulo threading contiene módulo _thread todos los métodos, sino también para proporcionar:

  • threading.currentThread (): Devuelve la variable hilo actual.
  • threading.enumerate (): Devuelve una lista contiene hilo conductor. Se refiere corriendo hilo comenzó antes del final, que no incluye el hilo antes de comenzar y después de la terminación.
  • threading.activeCount (): Devuelve el número de subprocesos que se ejecutan, y len (threading.enumerate ()) tienen el mismo resultado.

Además de la utilización de métodos, módulo threading también proporciona una clase de rosca para manejar el hilo, clase Thread proporciona los siguientes métodos:

  • ejecutar (): para indicar el método de hebras activas.
  • start (): iniciar actividad de los hilos.

  • join ([hora]): Esperar hasta quese interrumpe el hilo. Esto bloquea el subproceso de llamada hasta que el método de la rosca join () se llama suspensión - salida normal o lanzar una excepción no controlada - o tiempo de espera se produce opcional.
  • isAlive (): Devuelve el hilo está activo.
  • getName (): Devuelve el nombre del hilo.
  • setName (): Establecer el nombre del hilo.

Utilice módulo threading para crear un hilo

Podemos crear directamente heredado de threading.Thread una nueva subclase, después de que el método de arranque y cree una instancia (llamada) para iniciar un nuevo hilo, que se llama al método de ejecución de la rosca ():

#!/usr/bin/python3

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 ("开始线程:" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程:" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")

Los resultados de la ejecución del programa anterior son los siguientes;

开始线程:Thread-1
开始线程:Thread-2
Thread-1: Wed Apr  6 11:46:46 2016
Thread-1: Wed Apr  6 11:46:47 2016
Thread-2: Wed Apr  6 11:46:47 2016
Thread-1: Wed Apr  6 11:46:48 2016
Thread-1: Wed Apr  6 11:46:49 2016
Thread-2: Wed Apr  6 11:46:49 2016
Thread-1: Wed Apr  6 11:46:50 2016
退出线程:Thread-1
Thread-2: Wed Apr  6 11:46:51 2016
Thread-2: Wed Apr  6 11:46:53 2016
Thread-2: Wed Apr  6 11:46:55 2016
退出线程:Thread-2
退出主线程

sincronización hilo

Si varios hilos de una modificación de datos común, se pueden producir resultados imprevisibles, con el fin de garantizar la exactitud de los datos, es necesario sincronizar múltiples hilos.

objeto hilo mediante el bloqueo y RLOCK puede lograr una sincronización simple hilo, los dos objetos han de adquirir métodos y métodos de liberación, para aquellos que necesitan cada uno permitiendo sólo un hilo datos de funcionamiento, se puede colocar en funcionamiento adquirir y liberar métodos de la habitación. En la siguiente manera:

Multithreading ventaja es que puede ejecutar simultáneamente varias tareas (al menos se siente como esto). Pero cuando las discusiones necesitan compartir datos, puede que no haya problemas de sincronización de datos.

Consideremos un caso: una lista de todos los elementos son cero, el hilo "conjunto" de atrás hacia adelante todos los elementos en una sola, y el hilo de "impresión" de adelante hacia atrás el encargado de leer la lista y de impresión.

A continuación, el hilo podría ser "ajustado" empezó a cambiar cuando la "impresión" hilo para imprimir una lista, sería la mitad de la potencia de la mitad de un 0, que se no se sincroniza los datos. Para evitar esta situación, se introduce el concepto de la cerradura.

Cerradura tiene dos estados - bloqueado y desbloqueado. Cada vez que un hilo como "set" para acceder a los datos compartidos, primero debe obtener el bloqueo; si ya tiene otro hilo, tales como "impresión" para obtener encerrado, y luego dejar que el hilo "set" de pausa, que es el bloqueo sincrónica; espere hasta que el hilo " imprimir "el acceso se ha completado, después de la liberación de la cerradura, dejar que el hilo" set "para continuar.

Después de este proceso, al imprimir una lista de todas las salidas de 0 o 1 salida completa, ya no aparece la mitad vergüenza 0 1 medio.

Ejemplo:

#!/usr/bin/python3

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 ("开启线程: " + self.name)
        # 获取锁,用于线程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁,开启下一个线程
        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 = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

El programa anterior, la salida es:

开启线程: Thread-1
开启线程: Thread-2
Thread-1: Wed Apr  6 11:52:57 2016
Thread-1: Wed Apr  6 11:52:58 2016
Thread-1: Wed Apr  6 11:52:59 2016
Thread-2: Wed Apr  6 11:53:01 2016
Thread-2: Wed Apr  6 11:53:03 2016
Thread-2: Wed Apr  6 11:53:05 2016
退出主线程

cola de prioridad de subprocesos (cola)

módulo de cola de Python proporciona sincronización, clases de cola compatibles con el proceso, incluyendo FIFO (First In First Out) Cola de cola, LIFO (último en entrar, primero en salir) LifoQueue cola y PriorityQueue cola de prioridad.

Estas colas se implementan bloquean primitivas se pueden utilizar directamente en un multiproceso, puede utilizar la cola para conseguir la sincronización entre hilos.

Módulo de cola de métodos comúnmente utilizados:

  • Queue.qsize () devuelve el tamaño de la cola
  • Queue.empty () si la cola está vacía, devuelve True, False y viceversa
  • Queue.full () Si la cola está llena, devuelven verdadero, falso y viceversa
  • En correspondencia con el tamaño y maxsize Queue.full
  • Queue.get ([bloque [, tiempo de espera]]) Obtiene la cola, el tiempo de espera de tiempo de espera
  • Queue.get_nowait () en lugar Queue.get (Falso)
  • Queue.put (punto) cola de escritura, tiempo de espera de tiempo de espera
  • Queue.put_nowait (punto) bastante Queue.put (tema, False)
  • Queue.task_done () tras la realización de una obra, Queue.task_done () función envía una señal a la tarea se ha completado la cola
  • Queue.join () significa en realidad hasta que la cola está vacía, a continuación, realizar otras operaciones

Ejemplo:

#!/usr/bin/python3

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 ("开启线程:" + self.name)
        process_data(self.name, self.q)
        print ("退出线程:" + 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

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

Los resultados del programa anterior:

开启线程:Thread-1
开启线程:Thread-2
开启线程:Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
退出线程:Thread-3
退出线程:Thread-2
退出线程:Thread-1
退出主线程