Heim  >  Artikel  >  Backend-Entwicklung  >  Multithreading in Python (Zusammenfassung)

Multithreading in Python (Zusammenfassung)

WBOY
WBOYnach vorne
2022-11-16 16:56:3214294Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über Python, das hauptsächlich den relevanten Inhalt zum Multithreading vorstellt, und jeder Thread führt unterschiedliche Aufgaben aus. Schauen wir uns das an, ich hoffe, es hilft alle.

Multithreading in Python (Zusammenfassung)

【Verwandte Empfehlung: Python3-Video-Tutorial

Python-Multithreading

1. Das Konzept des Threads

Thread ist die Grundeinheit für die CPU, um Ressourcen zuzuweisen. Wenn ein Programm ausgeführt wird, wird das Programm zu einem Prozess, und ein Prozess entspricht einem oder mehreren Threads. Wenn es keine Multi-Thread-Programmierung gibt, entspricht ein Prozess einem Haupt-Thread. Wenn es eine Multi-Thread-Programmierung gibt, enthält ein Prozess mehrere Threads (einschließlich des Haupt-Threads). Mithilfe von Threads kann eine umfangreiche Programmentwicklung erreicht werden.

Mehrere Threads können im selben Programm ausgeführt werden, und jeder Thread führt unterschiedliche Aufgaben aus.

Multithread-Hintergrunddienstprogramm kann mehrere Aufgaben gleichzeitig bearbeiten, ohne zu blockieren.

Das Merkmal der Multithread-Programmierung besteht darin, dass sie die Effizienz der Programmausführung und die Verarbeitungsgeschwindigkeit verbessern kann. Python-Programme können mehrere relativ unabhängige Threads gleichzeitig parallel ausführen.

2. Multithreads erstellen

Python unterstützt zwei Möglichkeiten zum Erstellen von Multithreads:

~Erstellt durch threading.Thread ().

~Durch die Erbung der threading.Thread-Klasse.

1. Erstellen Sie

durch threading.Thread () Grammatikform:

thread.Thread(group=Nore,targt=None,args=(),kwargs={},*,daemon=None)

Parametererklärung:

~group: muss Keine sein, bezogen auf die ThreadGroup-Klasse, im Allgemeinen nicht verwendet.

~Ziel: Das vom Thread aufgerufene Objekt ist die Zielfunktion.

~Name: Geben Sie dem Thread diesen Namen. Der Standardwert ist Tread-x, x ist die Seriennummer, beginnend bei 1, und der Name des ersten erstellten Threads ist Tread-1.

~args: Übergeben Sie Schlüsselwortargumente, Wörterbuch für die Zielfunktion.

~Daemon: Wird verwendet, um festzulegen, ob der Thread beendet wird, wenn der Hauptthread beendet wird.

Beispiel:

import threading
def test (x,y):
 for i in range(x,y):
   print(i)
thread1 = threading.Thread(name='t1',target= test,args=(1,10))
thread2 = threading.Thread(name='t2',target= test,args=(11,20))
thread1.start()   #启动线程1
thread2.start()   #启动线程2

Ausgabe:

1
2
3
4
5
6
7
8
9
11
12
13
14
15
16
17
18
19

Erläuterung: Die beiden Programme werden gleichzeitig ausgeführt, daher sind die Ergebnisse nicht unbedingt jedes Mal sequentiell 1~10. Dies basiert auf dem Zeitsegment, das die CPU den beiden Threads zuweist. Entscheiden. Sie können sehen, dass die Ergebnisse jedes Mal unterschiedlich sind.

2. Vererbung durch Vererbung der threading.Thread-Klasse

threading.Thread ist eine Klasse und kann vererbt werden.

Beispiel:

import threading
class mythread(threading.Thread):
  def run(self):
    for i in range(1,10):
      print(i)
thread1 = mythread();
thread2 = mythread();
thread1.start()
thread2.start()

Ausgabe:

1
2
3
4
5
6
7
8
9
1
2
3
4
5
6
7
8
9

Erläuterung: Passen Sie eine Klasse an, um threading.Thread zu erben, und überschreiben Sie dann die Ausführungsmethode der übergeordneten Klasse. Diese Methode wird automatisch ausgeführt, wenn der Thread startet (führen Sie start() aus). .

3. Hauptthread

In Python ist der Hauptthread der erste Thread, der gestartet wird.

~Übergeordneter Thread: Wenn ein Thread B im Start-Thread A gestartet wird, ist A der übergeordnete Thread von B.

~Sub-Thread: B ist der Sub-Thread von A.

Beim Erstellen eines Threads gibt es ein Damon-Attribut. Verwenden Sie es, um den Hauptthread zu bestimmen. Wenn der Daemon auf „False“ gesetzt ist, wird der Thread nicht beendet, wenn der Hauptthread beendet wird, und der Hauptthread wartet, bis die Ausführung des untergeordneten Threads abgeschlossen ist. Wenn der Daemon auf True gesetzt ist, wird der Thread beendet, wenn der Haupt-Thread beendet wird, und andere untergeordnete Threads werden zum Beenden gezwungen, wenn der Haupt-Thread endet.

Hinweis bei Verwendung eines Daemons:

~Das Daemon-Attribut muss vor start() festgelegt werden, andernfalls wird eine RuntimeError-Ausnahme ausgelöst.

~Jeder Thread verfügt über ein Daemon-Attribut, das festgelegt oder nicht festgelegt werden kann. Der Standardwert ist None.

~Wenn der untergeordnete Thread das Daemon-Attribut nicht festlegt, verwenden Sie den Daemon des aktuellen Threads, um es festzulegen. Der untergeordnete Thread erbt den Daemon-Wert des untergeordneten Threads, was den gleichen Effekt hat wie die Einstellung „Keine“.

~Wenn das Daemon-Attribut nicht für alle vom Hauptthread erstellten Threads festgelegt ist, ist der Standardwert daemon=False.

Beispiel:

import time
import threading
def test():
 time.sleep(10)
 for i in range(10):
  print(i)
thread1 = threading.Thread(target=test,daemon=False)
thread1.start()
print('主线程完成了')

Ausgabe:

主线程完成了
0
1
2
3
4
5
6
7
8
9

Erläuterung: Wenn der Hauptthread seine Ausführung beendet und die Ausgabe ausgibt, warten Sie eine Weile und geben Sie dann 0 bis 9 aus. Wenn daemon=False in daemon=True geändert wird, wird die for i in range(10)-Anweisung nicht ausgeführt.

4. Threads blockieren

Wenn ein Thread die Join-Methode eines anderen Threads aufruft, wird der Aufrufer blockiert, bis der aufrufende Thread beendet wird.

Grammatikform:

join(timeout-=None)

Der Timeout-Parameter gibt an, wie lange der Aufrufer wartet. Wenn er nicht festgelegt ist, wartet er auf das Ende des aufgerufenen Threads. Unter anderem kann ein Thread durch Join mehrmals aufgerufen werden.

Beispiel:

import time
import threading
def test():
 time.sleep(5)
 for i in range(10):
  print(i)
thread1=threading.Thread(target=test)
thread1.start()
thread1.join()
print('主线程完成了')

Ausgabe:

0
1
2
3
4
5
6
7
8
9
主线程完成了

Erläuterung: Fügen Sie thread1.join() nach thread1.start() hinzu, um die Join-Methode hinzuzufügen. Bei der Ausgabe wartet der Hauptthread auf die Ausgabe von 0~9, bevor er sie ausführt eigene Druckausgabe.

5. Bestimmen Sie, ob der Thread aktiv ist

~run(): eine Methode zur Anzeige der Thread-Aktivität

~start(): Starten Sie den Thread

~join(): warten Sie, bis der Thread beendet ist

~isAlive( ): Gibt zurück, ob der Thread aktiv ist

~getName(): Gibt den Thread-Namen zurück

~setName(): Setzt den Thread-Namen

Beispiel:

from threading import Thread, Event
import time
def countdown(n, started_evt):
    print('正在运行')
    started_evt.set()
    while n > 0:
        print('时间', n)
        n -= 1
        time.sleep(2)
started_evt = Event()
print('开始倒计时')
t = Thread(target=countdown, args=(10, started_evt))
t.start()
started_evt.wait()
print('倒计时运行')

Ausgabe:

开始倒计时
正在运行
时间 10
倒计时运行
时间 9
时间 8
时间 7
时间 6
时间 5
时间 4
时间 3
时间 2
时间 1

Alive,顾名思义,它表示线程当前是否为可用状态,如果线程已经启动,并且当前没有任何异常的话,则返回true,否则为false

Thread.isAlive() :顾名思义,是表示当前线程时候为可用状态,即是否已经在启动,并且在运行的状态;

六、线程同步

1.同步概念

异步模式的情况下,同时有一个线程在修改共享数据,另一个线程在读取共享数据,当修改的共享数据的线程没有处理完毕,读取数据的线程肯定会得到错误的结果。如果采用多线程的同步控制机制,当处理共享数据的线程完成处理数据之后,读取线程就读取数据。

python的锁就解决这一问题,锁住线程,只允许一个线程操作,其他线程排队等待,待当前线程操作完毕后,再按顺序一个一个来运行。

2. python的锁

python的threading模块提供了RLock锁解决方法。在某一时间只能让一个线程操作的语句放到RLock的acquire方法和release方法之间,即acquire相当于给RLack上锁,而release相当于解锁。

示例:

import threading
class mythread(threading.Thread):
 def run(self):
  global x                   #声明一个全局变量
  lock.acquire()             #上锁
  x +=10
  print('%s:%d'%(self.name,x))
  lock.release()             #解锁
x = 0                        #设置全局变量初始值
lock = threading.RLock()     #创建可重入锁
list1 = []                   
for i in range(5):   
 list1.append(mythread())    #创建五个线程,放到同一列表中
for i in list1:
 i.start()                   #开启列表线程

输出:

Thread-1:10
Thread-2:20
Thread-3:30
Thread-4:40
Thread-5:50

解释:

3. python中的条件锁

条件锁常用的方法:

~acquire([timeout]):调用关联锁的方法

~release():解锁

~wait():使线程进入 Condition 的等待池等待通知并释放解锁。使用前线程必须已获得锁定,否则将抛出异常。

~notify():从等待池挑选一个线程并通知,收到通知的线程将自动调用 acquire() 尝试获得,其他线程仍然在等待池中等待通知,直到该线程收到通知 调用该方法,否则将会抛出异常。

~notify ALL():跟notify() 一样,但这个方法对应的是所有的线程。

示例:

题目:有几个生产车间生产,几个消费者购买,当生产达到一定数量时,停止生产。

import threading
import time
condtion = threading.Condition()
sheep = ['1件产品','1件产品','1件产品','1件产品','1件产品']
class Producer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) < 10:
                print(self.name + "生产了1件产品")
                sheep.append(&#39;1件产品&#39;)
                condtion.notifyAll()
                pass
            else:
                print("仓库满了,停止生产!")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
class Customer(threading.Thread):
    def __init__(self, name):
        super().__init__(name=name)
        pass
    def run(self):
        global condtion, sheep
        while True:
            time.sleep(0.1)
            condtion.acquire()
            if len(sheep) > 0:
                meat = sheep.pop()
                print(self.name + "购买了" + meat + "还剩多少" + str(len(sheep)) + "件")
                condtion.notifyAll()
                pass
            else:
                print("买光了,等待")
                condtion.wait()
                pass
            condtion.release()
        pass
    pass
if __name__ == "__main__":
    p1 = Producer("1号生产车间")
    p2 = Producer("2号生产车间")
    p3 = Producer("3号生产车间")
    p4 = Producer("4号生产车间")
    p5 = Producer("5号生产车间")
    p6 = Producer("6号生产车间")
    p1.start()
    p2.start()
    p4.start()
    p5.start()
    p6.start()
    c1 = Customer('小王')
    c2 = Customer('小李')
    c3 = Customer('小贾')
    c4 = Customer('小沈')
    c5 = Customer('小刘')
    c1.start()
    c2.start()
    c3.start()
    c4.start()
    c5.start()

【相关推荐:Python3视频教程

Das obige ist der detaillierte Inhalt vonMultithreading in Python (Zusammenfassung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen