Latest web development tutorials

Python multithread

Plusieurs threads exécutés simultanément est similaire à un certain nombre de programmes différents, le fonctionnement multithread présente les avantages suivants:

  • Utilisation de threads peuvent occuper à long programme dans la tâche en arrière-plan pour traiter.
  • L'interface utilisateur peut être plus attrayant, ainsi par exemple que l'utilisateur clique sur un bouton pour déclencher une gestion des événements, vous pouvez pop une barre de progression pour montrer les progrès du processus
  • la vitesse de course pourrait accélérer
  • Sur réalisé certaines tâches, telles que l'attente pour l'entrée utilisateur, le document d'alphabétisation et réseau pour envoyer et recevoir des données, le fil est plus utile. Dans ce cas, nous pouvons libérer des ressources précieuses, telles que l'utilisation de la mémoire et ainsi de suite.

Discussions dans le processus de mise en œuvre et le processus est différent. Chacun a un thread séparé en cours d'exécution d'entrée, la séquence de sortie et les procédures pour la mise en œuvre de l'ordre. Mais le fil ne sont pas en mesure d'effectuer de façon indépendante, il doit exister en fonction de l'application, fournissant de multiples fils d'exécution contrôlées par l'application.

Chaque thread a son propre ensemble de registres CPU, appelé le contexte du fil, le contexte de fil reflète la dernière exécution de l'état du fil de registre de CPU.

pointeur d'instruction et pointeur de la pile des registres sont les deux plus importants registres de contexte de fil, le fil se fait toujours exécuter dans le contexte du processus, ces adresses sont utilisées pour marquer le processus qui possède le fil de l'espace d'adressage de la mémoire.

  • Discussion peut être préempté (interrompu).
  • Dans d'autres fils sont en cours d'exécution, le fil peut être maintenu en suspens (également connu sous le sommeil) - ce qui est le fil de concessions.

Commencer à apprendre fils Python

fils de Python utilisés de deux manières: avec une fonction ou une classe pour envelopper l'objet thread.

Fonctionnel: fonction d'appel module de fil start_new_thread () pour générer un nouveau thread. La syntaxe est la suivante:

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

Description Paramètre:

  • - Fonction de fil.
  • args - les paramètres de fil passés à la fonction, il doit être un type de tuple.
  • kwargs - en option.

exemple:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

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: unable to start thread"

while 1:
   pass

Les résultats de sortie du programme ci-dessus sont les suivantes:

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

L'extrémité du fil est généralement compter sur la fin naturelle de la fonction de thread; peut aussi appeler Thread.exit fonction de thread (), il jette exception SystemExit, atteindre l'objectif de sortie du fil.


Module threading

Python fournit un support pour enfiler à travers deux bibliothèques standard du fil et de filetage. fil fournit un niveau faible, le fil original et une serrure simple.

Autre module méthodes de fil fournit:

  • threading.currentThread (): Renvoie la variable de thread courant.
  • threading.enumerate (): Renvoie une liste de threads en cours d'exécution contient. Désigne l'exécution du fil a commencé avant la fin, il ne comprend pas le fil avant de commencer et après la résiliation.
  • threading.activeCount (): Retourne le nombre de threads qui sont en cours d'exécution, et len ​​(threading.enumerate ()) ont le même résultat.

En plus de l'utilisation de méthodes, module de filetage fournit également une classe Thread pour manipuler le fil, classe Thread fournit les méthodes suivantes:

  • run (): pour indiquer la méthode de threads actifs.
  • start (): démarrer l' activité de fil.

  • join ([temps]): Attendez jusqu'à ce que le fil est interrompue.Cela bloque le thread appelant jusqu'à rejoindre () la méthode du fil est appelé suspension - sortie normale ou de jeter une exception non gérée - ou timeout option se produit.
  • isAlive (): Retourne le fil est active.
  • getName (): Renvoie le nom de fil.
  • setName (): Définissez le nom de fil.

Utilisez Module Threading pour créer des threads

Utilisez le module Threading pour créer un fil, directement hérité de threading.Thread, puis remplacer __init__ méthode et exécuter des méthodes:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading
import time

exitFlag = 0

class myThread (threading.Thread):   #继承父类threading.Thread
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):                   #把要执行的代码写到run函数里面 线程在创建后会直接运行run函数 
        print "Starting " + self.name
        print_time(self.name, self.counter, 5)
        print "Exiting " + self.name

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            thread.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()

print "Exiting Main Thread"

Les résultats de l'exécution du programme ci-dessus sont les suivantes;

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

Synchronisation Thread

Si plusieurs threads d'une modification de données commune, des résultats imprévisibles peuvent se produire, afin d'assurer l'exactitude des données, nous avons besoin de synchroniser plusieurs threads.

objet Thread utilisant le verrou et RLOCK peut réaliser une synchronisation de fil simple, les deux objets ont des méthodes d'acquérir et de méthodes de libération, pour ceux qui ont besoin chacun permettant seulement une donnée de fonctionnement de fil, il peut être mis en service à acquérir et à libérer les méthodes de la la chambre. Comme suit:

Multithreading avantage est qu'il peut exécuter simultanément des tâches multiples (au moins se sent comme ça). Mais lorsque les discussions ont besoin de partager des données, il peut y avoir aucun problème de synchronisation des données.

Prenons un cas: une liste de tous les éléments sont nuls, le fil "set" de l'arrière vers l'avant tous les éléments en un seul, et le fil "print" d'avant en arrière en charge de la lecture de la liste et l'impression.

Ensuite, le fil peut être "réglé" a commencé à changer lorsque le fil "print" pour imprimer une liste, il serait la moitié de la sortie d'un demi-0, ce qui est les données ne sont pas synchronisées. Pour éviter cette situation, nous introduisons le concept de la serrure.

Verrouiller a deux états - verrouillé et déverrouillé. Chaque fois un fil tel que le "set" pour accéder aux données partagées, vous devez d'abord obtenir le verrou, si vous avez déjà un autre thread, comme "print" pour obtenir enfermé, puis laisser le fil "set" pause, ce qui est le blocage synchrone; attendre jusqu'à ce que le fil " imprimer "l'accès est terminé, après la sortie de la serrure, laissez le fil" set "pour continuer.

Après ce processus, lorsque vous imprimez une liste de toutes les sorties 0 ou 1 sortie complète, ne semble plus la moitié embarras 0 1 demi.

exemple:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

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
       # 获得锁,成功获得锁定后返回True
       # 可选的timeout参数不填时将一直阻塞直到获得锁定
       # 否则超时后将返回False
        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 "Exiting Main Thread"

file d'attente prioritaire Thread (file d'attente)

Le module Queue de Python fournit la synchronisation, les classes de file d'attente thread-safe, y compris FIFO (first in first out) file d'attente de file d'attente, LIFO (dernier entré, premier sorti) file d'attente LifoQueue et file d'attente prioritaire PriorityQueue. Ces files d'attente sont mises en œuvre primitives de verrouillage peuvent être utilisés directement dans plusieurs threads. Vous pouvez utiliser la file d'attente pour obtenir une synchronisation entre les threads.

module Queue méthodes couramment utilisées:

  • Queue.qsize () retourne la taille de la file d'attente
  • Queue.empty () si la file d'attente est vide, renvoie True, False et vice versa
  • Queue.full () Si la file d'attente est pleine, le retour True, False et vice versa
  • Correspondant à la taille et maxsize Queue.full
  • Queue.get ([bloc [timeout]]) Obtient la file d'attente, délai d'attente le temps d'attente
  • Queue.get_nowait () plutôt Queue.get (Faux)
  • Queue.put (point) de file d'attente d'écriture, délai d'attente le temps d'attente
  • Queue.put_nowait (point) tout à fait Queue.put (point, False)
  • Queue.task_done () après l'achèvement d'une œuvre, Queue.task_done () fonction envoie un signal à la tâche a été achevée file d'attente
  • Queue.join () signifie vraiment jusqu'à ce que la file d'attente est vide, puis effectuer d'autres opérations

exemple:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

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

# 创建新线程
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 "Exiting Main Thread"

Les résultats du programme ci-dessus:

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