Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Industrial programming >> Python

Python Multithreading: Effiziente Nebenläufigkeitstechniken

Vorteile von Threads

Das Ausführen mehrerer Threads ähnelt dem gleichzeitigen Ausführen mehrerer Programme, bietet aber Vorteile:

Ein Thread hat einen Anfang, eine Ausführungssequenz und ein Ende. Er besitzt einen Instruktionszeiger, der verfolgt, wo er sich in seinem Kontext befindet.

Einen neuen Thread starten

Um einen weiteren Thread zu erzeugen, rufen Sie folgende Methode aus dem thread-Modul auf (Python 2; in Python 3 heißt es _thread):

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

Dies ermöglicht eine schnelle und effiziente Thread-Erstellung unter Linux und Windows. Der Aufruf kehrt sofort zurück; der Kindthread startet und ruft function mit der übergebenen args-Liste auf. Wenn die Funktion zurückkehrt, endet der Thread.

args ist ein Tupel von Argumenten; leeres Tupel für Aufruf ohne Argumente. kwargs ist ein optionales Dictionary für Keyword-Argumente.

Beispiel

#!/usr/bin/python
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

Ausgabe (Beispiel):

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

Obwohl effektiv für Low-Level-Threading, ist das thread-Modul im Vergleich zum neueren threading-Modul sehr begrenzt.

Das threading-Modul

Das neuere threading-Modul (ab Python 2.4) bietet leistungsfähigere, höherwertige Thread-Unterstützung.

Es stellt alle Methoden des thread-Moduls bereit plus zusätzliche:

Zusätzlich definiert es die Thread-Klasse mit folgenden Methoden:

Thread mit threading erstellen

Schritte:

  1. Neue Unterklasse von Thread definieren.
  2. __init__(self[, args]) überschreiben für zusätzliche Argumente.
  3. run(self[, args]) überschreiben für Thread-Logik.

Instanz erstellen und start() aufrufen (ruft intern run() auf).

Beispiel

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

thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)
thread1.start()
thread2.start()
print("Exiting Main Thread")

Ausgabe (Beispiel):

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

Threads synchronisieren

Das threading-Modul bietet einen einfachen Locking-Mechanismus zur Synchronisation.

Beispiel

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

Ausgabe (Beispiel):

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

Multithreaded Priority Queue

Das Queue-Modul (Python 3: queue) erstellt Queue-Objekte mit fester Kapazität.

Beispiel

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

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")

Ausgabe (Beispiel):

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

  1. Gewindeformen vs. Gewindewalzen: Die wesentlichen Unterschiede verstehen
  2. Python-Datentypen meistern: Praxisleitfaden
  3. Python-Operatoren meistern: Umfassender Leitfaden
  4. Python pass-Statement meistern: Praxisleitfaden
  5. Python-Funktionsargumente meistern: Positional, Keyword & Default-Parameter
  6. Python-Dictionaries meistern: Erstellung, Manipulation und fortgeschrittene Techniken
  7. Python Objektorientierte Programmierung meistern: Klassen, Vererbung, Kapselung & Polymorphie
  8. Python Netzwerkprogrammierung: Sockets & erweiterte Protokolle meistern
  9. Python Extension Programming mit C: Schnelle, native Module erstellen
  10. Fanuc G76 Gewindezyklus meistern: Kompletter Leitfaden für CNC-Zerspaner