


Detaillierte Einführung in Multithreading in Python (Codebeispiel)
Dieser Artikel bietet Ihnen eine detaillierte Einführung in Multithreading in Python (Codebeispiele). Ich hoffe, dass er Ihnen als Referenz dienen wird.
In diesem Artikel werden die beim Erlernen von Python auftretenden Probleme und einige häufige Verwendungen beschrieben. Beachten Sie, dass die Python-Version dieser Entwicklungsumgebung 2.7 ist.
1. Benennung von Python-Dateien
Bei der Benennung von Python-Dateien müssen Sie darauf achten, dass kein Konflikt mit dem Standardmodulnamen des Systems entsteht, da sonst ein Fehler gemeldet wird.
Wie im folgenden Beispiel lautet der Dateiname beim Lernen von Threads threading.py
und das Python-Skript ist völlig normal, es wird jedoch der folgende Fehler gemeldet: AttributeError: 'module' object has no attribute 'xxx'
.
threading.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_test.py @time: 18/8/25 09:14 """ import threading # 获取已激活的线程数 print(threading.active_count())
Ausführung:
➜ baseLearn python threading/threading.py Traceback (most recent call last): File "threading/threading.py", line 9, in <module> import threading File "/Users/kaiyiwang/Code/python/baseLearn/threading/threading.py", line 12, in <module> print(threading.active_count()) AttributeError: 'module' object has no attribute 'active_count' ➜ baseLearn
Problemort:
Sehen Sie sich die Quelldatei der import
-Bibliothek an und finden Sie die Quelldatei existiert und hat keine Fehler, es gibt auch .pyc
Dateien mit Quelldateien
Problemlösung:
1 Verwenden Sie beim Benennen des Py-Skripts nicht Python reserviert Wörter oder Modulnamen Das Gleiche wie
- 2. Löschen Sie die
-Datei der Bibliothek (da das Py-Skript bei jeder Ausführung eine .pyc-Datei generiert; in dem Fall, in dem die .pyc-Datei bereits generiert wurde Wenn der Code nicht aktualisiert wird, wird pyc beim Ausführen weiterhin verwendet. Löschen Sie daher die .pyc-Datei und führen Sie den Code erneut aus oder suchen Sie eine Umgebung, in der sich der Code befinden kann Führen Sie die .pyc-Datei des aktuellen Computers aus, kopieren Sie sie und ersetzen Sie sie
.pyc
um und führen Sie sie dann aus. Es wird kein Fehler gemeldet. threading_test.py
➜ baseLearn python threading/threading_test.py 1 ➜ baseLearn
ist schnell und einfach zu starten In diesem Abschnitt zeigen wir Ihnen, wie Sie es verwenden. threading
threading_test.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_test.py @time: 18/8/25 09:14 """ import threading # 获取已激活的线程数 # print(threading.active_count()) # 查看所有线程信息 # print(threading.enumerate()) # 查看现在正在运行的线程 # print(threading.current_thread()) def thread_job(): print('This is a thread of %s' % threading.current_thread()) def main(): thread = threading.Thread(target=thread_job,) # 定义线程 thread.start() # 让线程开始工作 if __name__ == '__main__': main()
Thread-Arbeit länger dauern T1
threading_join.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_join.py @time: 18/8/25 09:14 """ import threading import time def thread_job(): print('T1 start\n') for i in range(10): time.sleep(0.1) # 任务时间0.1s print("T1 finish\n") def main(): added_thread = threading.Thread(target=thread_job, name='T1') # 定义线程 added_thread.start() # 让线程开始工作 print("all done\n") if __name__ == '__main__': main()
T1 start T1 finish all done
➜ baseLearn python threading/threading_join.py T1 start all done T1 finish ➜ baseLearn
, bevor die Thread-Aufgabe abgeschlossen ist. Wenn Sie der Reihenfolge folgen möchten, können Sie nach dem Starten des Threads all done
darauf aufrufen: join
added_thread.start() added_thread.join() print("all done\n")
➜ baseLearn python threading/threading_join.py T1 start T1 finish all done
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_join.py @time: 18/8/25 09:14 """ import threading import time def thread_job(): print('T1 start\n') for i in range(10): time.sleep(0.1) # 任务时间0.1s print("T1 finish\n") def main(): added_thread = threading.Thread(target=thread_job, name='T1') # 定义线程 added_thread.start() # 让线程开始工作 added_thread.join() print("all done\n") if __name__ == '__main__': main()
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_join.py @time: 18/8/25 09:14 """ import threading import time def T1_job(): print('T1 start\n') for i in range(10): time.sleep(0.1) # 任务时间0.1s print("T1 finish\n") def T2_job(): print("T2 start\n") print("T2 finish\n") def main(): thread_1 = threading.Thread(target=T1_job, name='T1') # 定义线程 thread_2 = threading.Thread(target=T2_job, name='T2') # 定义线程 thread_1.start() # 开启T1 thread_2.start() # 开启T2 print("all done\n") if __name__ == '__main__': main()
T1 start T2 start T2 finish all done T1 finish
. Beachten Sie, dass dort „eins“ steht, da das Auftreten von „all done“ vollständig von zwei abhängt Aufgrund der Ausführungsgeschwindigkeit eines Threads ist es durchaus möglich, dass T2-Finish erscheint, nachdem alles erledigt ist. Wir können diese chaotische Ausführungsmethode nicht tolerieren, daher müssen wir Join verwenden, um sie zu steuern. join
:thread_1.join()
thread_1.start() thread_1.join() # notice the difference! thread_2.start() print("all done\n")
T1 start T1 finish T2 start all done T2 finish
in der Multithread-Funktion, um den Rückgabewert zu speichern. Queue
, definieren Sie ein Multi -Thread-Liste und Initialisierung einer mehrdimensionalen Datenliste, die zur Verarbeitung verwendet wird: 代替return
threading_queue.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_queue.py @time: 18/8/25 09:14 """ import threading import time from queue import Queue def job(l, q): for i in range(len(l)): l[i] = l[i] ** 2 q.put(l) #多线程调用的函数不能用return返回值 def multithreading(): q = Queue() #q中存放返回值,代替return的返回值 threads = [] data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]] for i in range(4): #定义四个线程 t = threading.Thread(target=job, args=(data[i], q)) #Thread首字母要大写,被调用的job函数没有括号,只是一个索引,参数在后面 t.start() #开始线程 threads.append(t) #把每个线程append到线程列表中 for thread in threads: thread.join() results = [] for _ in range(4): results.append(q.get()) #q.get()按顺序从q中拿出一个值 print(results) if __name__ == '__main__': multithreading()
➜ baseLearn python threading/threading_queue.py Traceback (most recent call last): File "threading/threading_queue.py", line 11, in <module> from queue import Queue ImportError: No module named queue
Typischerweise würden Sie portierbare Versionsimporte wie folgt schreiben:
In Python3 so zitiert: >
try: import queue except ImportError: import Queue as queue
from Queue import Queue
baseLearn python ./threading/threading_queue.py [[1, 4, 9], [9, 16, 25], [16, 16, 16], [25, 25, 25]]
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_queue.py @time: 18/8/25 09:14 """ import threading # import time from Queue import Queue def job(l, q): for i in range(len(l)): l[i] = l[i] ** 2 q.put(l) #多线程调用的函数不能用return返回值 def multithreading(): q = Queue() #q中存放返回值,代替return的返回值 threads = [] data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]] for i in range(4): #定义四个线程 t = threading.Thread(target=job, args=(data[i], q)) #Thread首字母要大写,被调用的job函数没有括号,只是一个索引,参数在后面 t.start() #开始线程 threads.append(t) #把每个线程append到线程列表中 for thread in threads: thread.join() results = [] for _ in range(4): results.append(q.get()) #q.get()按顺序从q中拿出一个值 print(results) if __name__ == '__main__': multithreading()
Was ist GIL ? threading_queue.py
. Dieses Ding ermöglicht es Python, immer noch nur eine Sache gleichzeitig zu verarbeiten.
Erklärung von GIL:
尽管Python完全支持多线程编程, 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上,解释器被一个全局解释器锁保护着,它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 (比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行)。在讨论普通的GIL之前,有一点要强调的是GIL只会影响到那些严重依赖CPU的程序(比如计算型的)。 如果你的程序大部分只会涉及到I/O,比如网络交互,那么使用多线程就很合适, 因为它们大部分时间都在等待。实际上,你完全可以放心的创建几千个Python线程, 现代操作系统运行这么多线程没有任何压力,没啥可担心的。测试GIL
我们创建一个 job
, 分别用 threading 和 一般的方式执行这段程序. 并且创建一个 list 来存放我们要处理的数据. 在 Normal 的时候, 我们这个 list 扩展4倍, 在 threading 的时候, 我们建立4个线程, 并对运行时间进行对比.
threading_gil.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_gil.py @time: 18/8/25 09:14 """ import threading from Queue import Queue import copy import time def job(l, q): res = sum(l) q.put(l) #多线程调用的函数不能用return返回值 def multithreading(l): q = Queue() #q中存放返回值,代替return的返回值 threads = [] for i in range(4): #定义四个线程 t = threading.Thread(target=job, args=(copy.copy(l), q), name="T%i" % i) #Thread首字母要大写,被调用的job函数没有括号,只是一个索引,参数在后面 t.start() #开始线程 threads.append(t) #把每个线程append到线程列表中 [t.join() for t in threads] total = 0 for _ in range(4): total = q.get() #q.get()按顺序从q中拿出一个值 print(total) def normal(l): total = sum(l) print(total) if __name__ == '__main__': l = list(range(1000000)) s_t = time.time() normal(l*4) print('normal:', time.time() - s_t) s_t = time.time() multithreading(l) print('multithreading: ', time.time() - s_t)
如果你成功运行整套程序, 你大概会有这样的输出. 我们的运算结果没错, 所以程序 threading 和 Normal 运行了一样多次的运算. 但是我们发现 threading 却没有快多少, 按理来说, 我们预期会要快3-4倍, 因为有建立4个线程, 但是并没有. 这就是其中的 GIL 在作怪.
1999998000000 normal: 0.10034608840942383 1999998000000 multithreading: 0.08421492576599121
5、线程锁Lock
不使用 Lock 的情况
threading_lock.py
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_lock.py @time: 18/8/25 09:14 """ import threading # 全局变量A的值每次加1,循环10次,并打印 def job1(): global A for i in range(10): A+=1 print('job1',A) # 全局变量A的值每次加10,循环10次,并打印 def job2(): global A for i in range(10): A+=10 print('job2',A) # 定义两个线程,分别执行函数一和函数二 if __name__== '__main__': A=0 t1=threading.Thread(target=job1) t2=threading.Thread(target=job2) t1.start() t2.start() t1.join() t2.join()
打印输出数据:
➜ baseLearn python ./threading/threading_lock.py ('job1', ('job2'1) , (11)'job1' ('job2', 22) ('job2', 32) ('job2', 42) ('job2', 52) ('job2', 62) ('job2', 72) ('job2', 82) ('job2', 92) ('job2', 102) , 12) ('job1', 103) ('job1', 104) ('job1', 105) ('job1', 106) ('job1', 107) ('job1', 108) ('job1', 109) ('job1', 110)
可以看出,打印的结果非常混乱
使用 Lock 的情况
lock在不同线程使用同一共享内存
时,能够确保线程之间互不影响,使用lock的方法是, 在每个线程执行运算修改共享内存之前,执行lock.acquire()
将共享内存上锁, 确保当前线程执行时,内存不会被其他线程访问,执行运算完毕后,使用lock.release()
将锁打开, 保证其他的线程可以使用该共享内存。
函数一和函数二加锁
def job1(): global A,lock lock.acquire() for i in range(10): A+=1 print('job1',A) lock.release() def job2(): global A,lock lock.acquire() for i in range(10): A+=10 print('job2',A) lock.release()
主函数中定义一个Lock
if __name__== '__main__': lock=threading.Lock() A=0 t1=threading.Thread(target=job1) t2=threading.Thread(target=job2) t1.start() t2.start() t1.join() t2.join()
完整代码:
# -*- coding:utf-8 -*- """ @author: Corwien @file: threading_lock.py @time: 18/8/25 09:14 """ import threading def job1(): global A,lock lock.acquire() for i in range(10): A+=1 print('job1',A) lock.release() def job2(): global A,lock lock.acquire() for i in range(10): A+=10 print('job2',A) lock.release() if __name__== '__main__': lock = threading.Lock() A=0 t1=threading.Thread(target=job1) t2=threading.Thread(target=job2) t1.start() t2.start() t1.join() t2.join()
打印输出:
➜ baseLearn python ./threading/threading_lock.py ('job1', 1) ('job1', 2) ('job1', 3) ('job1', 4) ('job1', 5) ('job1', 6) ('job1', 7) ('job1', 8) ('job1', 9) ('job1', 10) ('job2', 20) ('job2', 30) ('job2', 40) ('job2', 50) ('job2', 60) ('job2', 70) ('job2', 80) ('job2', 90) ('job2', 100) ('job2', 110)
从打印结果来看,使用lock
后,一个一个线程执行完。使用lock
和不使用lock,最后打印输出的结果是不同的。
相关推荐:
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in Multithreading in Python (Codebeispiel). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Python zeichnet sich in Gaming und GUI -Entwicklung aus. 1) Spielentwicklung verwendet Pygame, die Zeichnungen, Audio- und andere Funktionen bereitstellt, die für die Erstellung von 2D -Spielen geeignet sind. 2) Die GUI -Entwicklung kann Tkinter oder Pyqt auswählen. Tkinter ist einfach und einfach zu bedienen. PYQT hat reichhaltige Funktionen und ist für die berufliche Entwicklung geeignet.

PHP und Python haben jeweils ihre eigenen Vorteile und wählen nach den Projektanforderungen. 1.PHP ist für die Webentwicklung geeignet, insbesondere für die schnelle Entwicklung und Wartung von Websites. 2. Python eignet sich für Datenwissenschaft, maschinelles Lernen und künstliche Intelligenz mit prägnanter Syntax und für Anfänger.

Die Readdir -Funktion im Debian -System ist ein Systemaufruf, der zum Lesen des Verzeichnisgehalts verwendet wird und häufig in der C -Programmierung verwendet wird. In diesem Artikel wird erläutert, wie Readdir in andere Tools integriert wird, um seine Funktionalität zu verbessern. Methode 1: Kombinieren Sie C -Sprachprogramm und Pipeline zuerst ein C -Programm, um die Funktion der Readdir aufzurufen und das Ergebnis auszugeben:#include#include#includeIntmain (intargc, char*argv []) {Dir*Dir; structDirent*Eintrag; if (argc! = 2) {{

Um die Effizienz des Lernens von Python in einer begrenzten Zeit zu maximieren, können Sie Pythons DateTime-, Zeit- und Zeitplanmodule verwenden. 1. Das DateTime -Modul wird verwendet, um die Lernzeit aufzuzeichnen und zu planen. 2. Das Zeitmodul hilft, die Studie zu setzen und Zeit zu ruhen. 3. Das Zeitplanmodul arrangiert automatisch wöchentliche Lernaufgaben.

In diesem Artikel werden Sie begleitet, wie Sie Ihr NginXSSL -Zertifikat auf Ihrem Debian -System aktualisieren. Schritt 1: Installieren Sie zuerst CertBot und stellen Sie sicher, dass Ihr System Certbot- und Python3-CertBot-Nginx-Pakete installiert hat. If not installed, please execute the following command: sudoapt-getupdatesudoapt-getinstallcertbotpython3-certbot-nginx Step 2: Obtain and configure the certificate Use the certbot command to obtain the Let'sEncrypt certificate and configure Nginx: sudocertbot--nginx Follow the prompts to select

Das Konfigurieren eines HTTPS -Servers auf einem Debian -System umfasst mehrere Schritte, einschließlich der Installation der erforderlichen Software, der Generierung eines SSL -Zertifikats und der Konfiguration eines Webservers (z. B. Apache oder NGINX) für die Verwendung eines SSL -Zertifikats. Hier ist eine grundlegende Anleitung unter der Annahme, dass Sie einen Apacheweb -Server verwenden. 1. Installieren Sie zuerst die erforderliche Software, stellen Sie sicher, dass Ihr System auf dem neuesten Stand ist, und installieren Sie Apache und OpenSSL: sudoaptupdatesudoaptupgradesudoaptinsta

Die Entwicklung eines Gitlab -Plugins für Debian erfordert einige spezifische Schritte und Kenntnisse. Hier ist ein grundlegender Leitfaden, mit dem Sie mit diesem Prozess beginnen können. Wenn Sie zuerst GitLab installieren, müssen Sie GitLab in Ihrem Debian -System installieren. Sie können sich auf das offizielle Installationshandbuch von GitLab beziehen. Holen Sie sich API Access Token, bevor Sie die API -Integration durchführen. Öffnen Sie das GitLab -Dashboard, finden Sie die Option "AccessTokens" in den Benutzereinstellungen und generieren Sie ein neues Zugriffs -Token. Wird generiert

Apache ist der Held hinter dem Internet. Es ist nicht nur ein Webserver, sondern auch eine leistungsstarke Plattform, die enormen Datenverkehr unterstützt und dynamische Inhalte bietet. Es bietet eine extrem hohe Flexibilität durch ein modulares Design und ermöglicht die Ausdehnung verschiedener Funktionen nach Bedarf. Modularität stellt jedoch auch Konfigurations- und Leistungsherausforderungen vor, die ein sorgfältiges Management erfordern. Apache eignet sich für Serverszenarien, die hoch anpassbare und entsprechende komplexe Anforderungen erfordern.
