Latest web development tutorials

python3 Multithreading

Mehrere Threads ausgeführt gleichzeitig ist ähnlich zu einer Anzahl von verschiedenen Programmen, multithreaded Betrieb hat die folgenden Vorteile:

  • Mit Threads können lange Programm in der Aufgabe in den Hintergrund zu besetzen, zu beschäftigen.
  • Die Benutzeroberfläche kann attraktiver sein, so zum Beispiel der Benutzer auf eine Schaltfläche klickt einige Event-Handling auszulösen, können Sie einen Fortschrittsbalken Pop der Fortschritt des Prozesses zu zeigen,
  • Laufgeschwindigkeit könnte beschleunigen
  • Auf realisiert einige Aufgaben, wie zum Beispiel eine Benutzereingabe wartet, Dokumenten Lese-, Schreib- und Netzwerkdaten zu senden und zu empfangen, ist der Faden nützlicher. In diesem Fall können wir einige wertvolle Ressourcen, wie Speichernutzung usw. frei.

Themen in den Umsetzungsprozess und der Prozess ist anders. Jedes verfügt über einen separaten Thread ausgeführt Eingang, Ausgang Folge und Verfahren für die Durchführung des Auftrages. Aber der Faden ist unabhängig auszuführen nicht in der Lage, es muss entsprechend existieren an die Anwendung, mehrere Ausführungs-Threads Bereitstellung durch die Anwendung gesteuert.

Jeder Thread hat seinen eigenen Satz von CPU-Register, genannt spiegelt der Kontext des Themas, der Thread-Kontext den letzten Lauf des Threads CPU-Register-Zustand.

Befehlszeiger und Stapelzeigerregister sind die beiden wichtigsten Thread-Kontext-Register, der Faden immer in Zusammenhang mit dem Prozess ausgeführt wird, werden diese Adressen verwendet, um den Prozeß zu kennzeichnen, die den Faden von dem Speicheradressenraum besitzt.

  • Gewinde können vorbelegt werden (unterbrochen).
  • In anderen Threads ausgeführt werden, kann der Faden in der Schwebe (auch bekannt als Schlaf) gehalten werden - dies ist der Faden der Zugeständnisse ist.

Gewinde können unterteilt werden:

  • Kernel - Themen: der Betriebssystemkern erstellt und zerstört.
  • Benutzer - Thread: Kernel - Unterstützung und erfordert keine Anwenderprogramm implementiert Thread.

Python3 gemeinsamen Faden zwei Modulen:

  • _thread
  • Threading (empfohlen)

Gewinde-Modul wurde aufgegeben. Benutzer können stattdessen das Einfädeln Modul verwenden. Also, in Python3 kann nicht mehr den "Faden" Modul verwenden. Für die Kompatibilität wird Python3 thread "_thread" umbenennen.


Starten Sie das Lernen Python-Threads

Python-Threads auf zwei Arten verwendet: mit einer Funktion oder Klasse, um die Thread-Objekt zu wickeln.

Funktional: Rufen Sie _thread Modul start_new_thread () Funktion einen neuen Thread zu erzeugen. Die Syntax lautet wie folgt:

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

Parameter Beschreibung:

  • Funktion - Thread-Funktion.
  • args - die Faden Parameter an die Funktion übergeben, muss er ein Tupel-Typ sein.
  • kwargs - Optional.

Beispiel:

#!/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

Die oben genannten Programmausgabe Ergebnisse sind wie folgt:

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

Nach dem oben beschriebenen Prozess ausführen Strg-C zu beenden können drücken.


Threading-Modul

Python3 bieten Unterstützung für durch zwei Standardbibliothek _thread Einfädeln und Gewinden.

_thread bietet eine Low-Level, das ursprüngliche Gewinde und ein einfaches Schloss, es verglichen wird, um das Einfädeln Funktionsbaustein noch relativ begrenzt ist.

Andere Verfahren zusätzlich zu threading Modul enthält _thread Modul alle Methoden, sondern auch zur Verfügung zu stellen:

  • threading.currentThread (): Gibt den aktuellen Thread-Variable.
  • threading.enumerate (): Gibt ein laufender Thread-Liste enthält. Bezieht sich laufenden Thread vor dem Ende begonnen, es nicht den Faden sind vor dem Start und nach der Beendigung.
  • threading.activeCount (): Gibt die Anzahl der Threads, die ausgeführt werden, und len (threading.enumerate ()) haben das gleiche Ergebnis.

Neben der Verwendung von Methoden, threading-Modul bietet auch eine Thread-Klasse den Faden, Thread-Klasse stellt die folgenden Methoden zu behandeln:

  • run (): die Methode der aktiven Threads anzuzeigen.
  • () Starten: Thread - Aktivität starten.

  • join ([Zeit]): Warten , bis der Thread abgebrochen.Dies blockiert den Aufruf Thread, bis der Thread join () Methode wird Suspension genannt - normale Ausfahrt oder eine nicht behandelte Ausnahme werfen - oder optionale Timeout auftritt.
  • IsAlive (): Gibt der Thread aktiv ist.
  • getName (): Gibt den Thread - Namen.
  • setName (): Stellen Sie den Thread - Namen.

Verwenden Sie threading Modul einen Thread erstellen,

Wir können direkt von threading.Thread eine neue Unterklasse, nach dem Aufruf Start- und instanziiert () -Methode zu starten einen neuen Thread geerbt geschaffen werden, die es den Thread run () -Methode ruft:

#!/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 ("退出主线程")

Die oben genannten Programmausführung Ergebnisse sind wie folgt;

开始线程: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
退出主线程

Themen-Synchronisation

Wenn mehrere Threads einer gemeinsamen Datenänderung kann unvorhersagbare Ergebnisse auftreten, um die Richtigkeit der Daten zu gewährleisten, müssen wir mehrere Threads zu synchronisieren.

Thread-Objekt mit dem Schloss und RLOCK können eine einfache Thread-Synchronisation zu erreichen, die beiden Objekte haben Methoden erwerben und Freisetzung Methoden, für diejenigen, die jeweils so dass nur ein Thread Betriebsdaten benötigen, kann sie in Betrieb acquire platziert werden und lassen Sie Methoden der Zimmer. Wie folgt:

Multithreading Vorteil ist, dass es mehrere Aufgaben gleichzeitig ausgeführt werden können (zumindest fühlt sich an wie diese). Aber wenn Threads benötigen, um Daten zu teilen, kann es keine Daten-Synchronisierungsprobleme sein.

Betrachten wir einen Fall: eine Liste aller Elemente Null sind, der Thread "set" von hinten nach vorne alle Elemente in einem, und der Faden "Drucken" von vorne in Ladung Rückseite der Liste und drucken zu lesen.

Dann kann der Faden "gesetzt" werden, begann sich zu ändern, wenn der Thread "Drucken" eine Liste zu drucken, wäre es eine 0 Hälfte der Ausgang der Hälfte sein, die die Daten nicht synchronisiert ist. Um diese Situation zu vermeiden, führen wir das Konzept des Schlosses.

Sperre hat zwei Zustände - verriegelt und entriegelt. Jedes Mal, wenn ein Thread wie "set" die gemeinsamen Daten zugreifen zu können, müssen Sie zuerst die Sperre erhalten, wenn Sie bereits ein anderes Gewinde haben, wie zum Beispiel "Drucken" zu erhalten eingesperrt, dann lassen Sie den Faden "set" Pause, die synchrone Sperrung ist, bis der Faden warten " drucken "Zugriff abgeschlossen ist, nach der Freigabe des Schlosses, lassen Sie den Faden" Set ", um fortzufahren.

Nach diesem Prozess, wenn Sie eine Liste aller Ausgaben entweder 0 oder 1 volle Leistung zu drucken, wird nicht mehr die Hälfte Verlegenheit 0 1 halb.

Beispiel:

#!/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 ("退出主线程")

Das obige Programm, das Ausgabe ist:

开启线程: 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
退出主线程

Thread-Priorität-Warteschlange (Queue)

Pythons Queue-Modul ermöglicht die Synchronisierung, Thread-sichere Warteschlange Klassen, einschließlich FIFO (first in first out) Warteschlange Queue, LIFO (last in, first out) Warteschlange LifoQueue und Prioritätswarteschlange Priorityqueue.

Diese Warteschlangen implementiert sind Verriegelungs Primitive direkt in einem multithreaded verwendet werden kann, können Sie die Warteschlange verwenden Synchronisation zwischen Threads zu erreichen.

Queue-Modul häufigsten verwendeten Methoden:

  • Queue.qsize () gibt die Größe der Warteschlange
  • Queue.empty (), wenn die Warteschlange leer ist, gibt True, False und umgekehrt
  • Queue.full () Wenn die Warteschlange voll ist, zurückgeben True, False und umgekehrt
  • Entsprechend der Größe und maxsize Queue.full
  • Queue.get ([Block [, timeout]]) Ruft die Warteschlange, Timeout Wartezeit
  • Queue.get_nowait () eher Queue.get (False)
  • Queue.put (Artikel) Schreibwarteschlange, Timeout Wartezeit
  • Queue.put_nowait (Artikel) ganz Queue.put (item, False)
  • Queue.task_done () nach Beendigung eines Arbeits, Queue.task_done () Funktion sendet ein Signal an die Aufgabenwarteschlange abgeschlossen wurde
  • Queue.join () bedeutet, wirklich, bis die Warteschlange leer ist, dann andere Operationen ausführen

Beispiel:

#!/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 ("退出主线程")

Die Ergebnisse des obigen Programms:

开启线程: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
退出主线程