


Ein Artikel bietet Ihnen eine umfassende Analyse verschiedener Threads
Vorwort
Bevor wir die heutigen Wissenspunkte durchgehen, wissen Sie zunächst etwas über Threads, Prozesse und Coroutinen eine vorläufige Verständnis Bar.
Thread
Die Planungseinheit des Zentralprozessors ist vereinfacht gesagt der End-Executor im Programm, der der Position des jüngeren Bruders entspricht.
Einige Leute sagen, dass Threads in Python nutzlos sind, aber es ist nicht blind nutzlos, wenn es um IO-Operationen geht, aber es ist unbefriedigend, wenn es darum geht, Berechnungen durchzuführen. Werfen wir einen Blick auf die spezifische Verwendung von Threads:
1. Importieren Sie das Thread-Modul:
2. So verwenden Sie Threads:
import threading as t
Nach dem Login kopieren
import threading as t
3 . Erstellen Sie einen Thread
Threads können mit der Thread-Methode erstellt werden, oder Sie können die Ausführungsmethodenimplementierung der Thread-Klasse überschreiben. Threads können in einzelne Threads und Multi-Threads unterteilt werden.
3.1 使用Thread方法来创建:
3.1.1 单线程
def xc():
for y in range(100):
print('运行中'+str(y))
tt=t.Thread(target=xc,args=()) #方法加入到线程
tt.start() #开始线程
tt.join() #等待子线程结束
Nach dem Login kopieren3.1.2 多线程
def xc(num):
print('运行:'+str(num))
c=[]
for y in range(100):
tt=t.Thread(target=xc,args=(y,))
tt.start() #开始线程
c.append(tt) #创建列表并添加线程
for x in c:
x.join() #等待子线程结束
Nach dem Login kopieren
3.2 重写线程的类方法
3.2.1 单线程
class Xc(t.Thread): #继承Thread类
def __init__(self):
super(Xc, self).__init__()
def run(self): #重写run方法
for y in range(100):
print('运行中'+str(y))
x=Xc()
x.start() #开始线程
x.join() #等待子线程结束
也可以这么写:
Xc().run() 和上面的效果是一样的
Nach dem Login kopieren3.2.2 多线程
class Xc(t.Thread): #继承Thread类
def __init__(self):
super(Xc, self).__init__()
def run(self,num): #重写run方法
print('运行:'+str(num))
x=Xc()
for y in range(10):
x.run(y) #运行
Nach dem Login kopieren4.线程锁
def xc(): for y in range(100): print('运行中'+str(y)) tt=t.Thread(target=xc,args=()) #方法加入到线程 tt.start() #开始线程 tt.join() #等待子线程结束
def xc(num): print('运行:'+str(num)) c=[] for y in range(100): tt=t.Thread(target=xc,args=(y,)) tt.start() #开始线程 c.append(tt) #创建列表并添加线程 for x in c: x.join() #等待子线程结束
class Xc(t.Thread): #继承Thread类 def __init__(self): super(Xc, self).__init__() def run(self): #重写run方法 for y in range(100): print('运行中'+str(y)) x=Xc() x.start() #开始线程 x.join() #等待子线程结束 也可以这么写: Xc().run() 和上面的效果是一样的
class Xc(t.Thread): #继承Thread类 def __init__(self): super(Xc, self).__init__() def run(self,num): #重写run方法 print('运行:'+str(num)) x=Xc() for y in range(10): x.run(y) #运行
为什么要加锁,看了这个你就知道了:
多线程在运行时同时访问一个对象会产生抢占资源的情况,所以我们必须得束缚它,所以就要给他加一把锁把他锁住,这就是同步锁。要了解锁,我们得先创建锁,线程中有两种锁:Lock和RLock。
4.1 Lock
使用方法:
# 获取锁 当获取不到锁时,默认进入阻塞状态,设置超时时间,直到获取到锁,后才继续。非阻塞时,timeout禁止设置。如果超时依旧未获取到锁,返回False。 Lock.acquire(blocking=True,timeout=1) #释放锁,已上锁的锁,会被设置为unlocked。如果未上锁调用,会抛出RuntimeError异常。 Lock.release()
互斥锁,同步数据,解决多线程的安全问题:
n=10 lock=t.Lock() def xc(num): lock.acquire() print('运行+:'+str(num+n)) print('运行-:'+str(num-n)) lock.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
这样就显得有条理了,而且输出也是先+后-。Lock在一个线程中多次使用同一资源会造成死锁。
死锁问题:
n=10 lock1=t.Lock() lock2=t.Lock() def xc(num): lock1.acquire() print('运行+:'+str(num+n)) lock2.acquire() print('运行-:'+str(num-n)) lock2.release() lock1.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
4.2 RLock
相比Lock它可以递归,支持在同一线程中多次请求同一资源,并允许在同一线程中被多次锁定,但是acquire和release必须成对出现。
使用递归锁来解决死锁:
n=10 lock1=t.RLock() lock2=t.RLock() def xc(num): lock1.acquire() print('运行+:'+str(num+n)) lock2.acquire() print('运行-:'+str(num-n)) lock2.release() lock1.release() c=[] for y in range(10): tt=t.Thread(target=xc,args=(y,)) tt.start() c.append(tt) for x in c: x.join()
这时候,输出变量就变得仅仅有条了,不在随意抢占资源。关于线程锁,还可以使用with更加方便:
#with上下文管理,锁对象支持上下文管理 with lock: #with表示自动打开自动释放锁 for i in range(10): #锁定期间,其他人不可以干活 print(i) #上面的和下面的是等价的 if lock.acquire(1):#锁住成功继续干活,没有锁住成功就一直等待,1代表独占 for i in range(10): #锁定期间,其他线程不可以干活 print(i) lock.release() #释放锁
4.3 条件锁
等待通过,Condition(lock=None),可以传入lock或者Rlock,默认Rlock,使用方法:
Condition.acquire(*args) 获取锁 Condition.wait(timeout=None) 等待通知,timeout设置超时时间 Condition.notify(num)唤醒至多指定数目个数的等待的线程,没有等待的线程就没有任何操作 Condition.notify_all() 唤醒所有等待的线程 或者notifyAll()
def ww(c): with c: print('init') c.wait(timeout=5) #设置等待超时时间5 print('end') def xx(c): with c: print('nono') c.notifyAll() #唤醒所有线程 print('start') c.notify(1) #唤醒一个线程 print('21') c=t.Condition() #创建条件 t.Thread(target=ww,args=(c,)).start() t.Thread(target=xx,args=(c,)).start()
这样就可以在等待的时候唤醒函数里唤醒其他函数里所存在的其他线程了。
5.信号量
信号量可以分为有界信号量和无解信号量,下面我们来具体看看他们的用法:
5.1 有界信号量
它不允许使用release超出初始值的范围,否则,抛出ValueError异常。
#构造方法。value为初始信号量。value小于0,抛出ValueError异常 b=t.BoundedSemaphore(value=1) #获取信号量时,计数器减1,即_value的值减少1。如果_value的值为0会变成阻塞状态。获取成功返回True BoundedSemaphore.acquire(blocking=True,timeout=None) #释放信号量,计数器加1。即_value的值加1,超过初始化值会抛出异常ValueError。 BoundedSemaphore.release() #信号量,当前信号量 BoundedSemaphore._value
可以看到了多了个release后报错了。
5.2 无界信号量
它不检查release的上限情况,只是单纯的加减计数器。
可以看到虽然多了个release,但是没有问题,而且信号量的数量不受限制。
6.Event
线程间通信,通过线程设置的信号标志(flag)的False 还是True来进行操作,常见方法有:
event.set() flag设置为True event.clear() flag设置为False event.is_set() flag是否为True,如果 event.isSet()==False将阻塞线程; 设置等待flag为True的时长,None为无限等待。等到返回True,未等到超时则返回False event.wait(timeout=None)
下面通过一个例子具体讲述:
import time e=t.Event() def ff(num): while True: if num<5: e.clear() #清空信号标志 print('清空') if num>=5: e.wait(timeout=1) #等待信号标志为真 e.set() print('启动') if e.isSet(): #如果信号标志为真则清除标志 e.clear() print('停止') if num==10: e.wait(timeout=3) e.clear() print('退出') break num+=1 time.sleep(2) ff(1)
设置延迟后可以看到效果相当明显,我们让他干什么事他就干什么事。
7.local
可以为各个线程创建完全属于它们自己的变量(线程局部变量),而且它们的值都在当前调用它的线程当中,以字典的形式存在。下面我们来看下:
l=t.local() #创建一个线程局部变量 def ff(num): l.x=100 #设置l变量的x方法的值为100 for y in range(num): l.x+=3 #改变值 print(str(l.x)) for y in range(10): t.Thread(target=ff,args=(y,)).start() #开始执行线程
那么,可以将变量的x方法设为全局变量吗?我们来看下:
可以看出他报错了,产生错误的原因是因为这个类中没有属性x,我们可以简单的理解为局部变量就只接受局部。
8.Timer
设置定时计划,可以在规定的时间内反复执行某个方法。他的使用方法是:
t.Timer(num,func,*args,**kwargs) #在指定时间内再次重启程序
下面我们来看下:
def f(): print('start') global t #防止造成线程堆积导致最终程序退出 tt= t.Timer(3, f) tt.start() f()
这样就达到了每三秒执行一次f函数的效果。
总结
Das obige ist der detaillierte Inhalt vonEin Artikel bietet Ihnen eine umfassende Analyse verschiedener Threads. 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

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

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

PHP ist hauptsächlich prozedurale Programmierung, unterstützt aber auch die objektorientierte Programmierung (OOP). Python unterstützt eine Vielzahl von Paradigmen, einschließlich OOP, funktionaler und prozeduraler Programmierung. PHP ist für die Webentwicklung geeignet, und Python eignet sich für eine Vielzahl von Anwendungen wie Datenanalyse und maschinelles Lernen.

PHP eignet sich für Webentwicklung und schnelles Prototyping, und Python eignet sich für Datenwissenschaft und maschinelles Lernen. 1.PHP wird für die dynamische Webentwicklung verwendet, mit einfacher Syntax und für schnelle Entwicklung geeignet. 2. Python hat eine kurze Syntax, ist für mehrere Felder geeignet und ein starkes Bibliotheksökosystem.

Python eignet sich besser für Anfänger mit einer reibungslosen Lernkurve und einer kurzen Syntax. JavaScript ist für die Front-End-Entwicklung mit einer steilen Lernkurve und einer flexiblen Syntax geeignet. 1. Python-Syntax ist intuitiv und für die Entwicklung von Datenwissenschaften und Back-End-Entwicklung geeignet. 2. JavaScript ist flexibel und in Front-End- und serverseitiger Programmierung weit verbreitet.

VS -Code -Erweiterungen stellen böswillige Risiken dar, wie das Verstecken von böswilligem Code, das Ausbeutetieren von Schwachstellen und das Masturbieren als legitime Erweiterungen. Zu den Methoden zur Identifizierung böswilliger Erweiterungen gehören: Überprüfung von Verlegern, Lesen von Kommentaren, Überprüfung von Code und Installation mit Vorsicht. Zu den Sicherheitsmaßnahmen gehören auch: Sicherheitsbewusstsein, gute Gewohnheiten, regelmäßige Updates und Antivirensoftware.

VS -Code kann zum Schreiben von Python verwendet werden und bietet viele Funktionen, die es zu einem idealen Werkzeug für die Entwicklung von Python -Anwendungen machen. Sie ermöglichen es Benutzern: Installation von Python -Erweiterungen, um Funktionen wie Code -Abschluss, Syntax -Hervorhebung und Debugging zu erhalten. Verwenden Sie den Debugger, um Code Schritt für Schritt zu verfolgen, Fehler zu finden und zu beheben. Integrieren Sie Git für die Versionskontrolle. Verwenden Sie Tools für die Codeformatierung, um die Codekonsistenz aufrechtzuerhalten. Verwenden Sie das Lining -Tool, um potenzielle Probleme im Voraus zu erkennen.

VS -Code kann unter Windows 8 ausgeführt werden, aber die Erfahrung ist möglicherweise nicht großartig. Stellen Sie zunächst sicher, dass das System auf den neuesten Patch aktualisiert wurde, und laden Sie dann das VS -Code -Installationspaket herunter, das der Systemarchitektur entspricht und sie wie aufgefordert installiert. Beachten Sie nach der Installation, dass einige Erweiterungen möglicherweise mit Windows 8 nicht kompatibel sind und nach alternativen Erweiterungen suchen oder neuere Windows -Systeme in einer virtuellen Maschine verwenden müssen. Installieren Sie die erforderlichen Erweiterungen, um zu überprüfen, ob sie ordnungsgemäß funktionieren. Obwohl VS -Code unter Windows 8 möglich ist, wird empfohlen, auf ein neueres Windows -System zu upgraden, um eine bessere Entwicklungserfahrung und Sicherheit zu erzielen.

Im VS -Code können Sie das Programm im Terminal in den folgenden Schritten ausführen: Erstellen Sie den Code und öffnen Sie das integrierte Terminal, um sicherzustellen, dass das Codeverzeichnis mit dem Terminal Working -Verzeichnis übereinstimmt. Wählen Sie den Befehl aus, den Befehl ausführen, gemäß der Programmiersprache (z. B. Pythons Python your_file_name.py), um zu überprüfen, ob er erfolgreich ausgeführt wird, und Fehler auflösen. Verwenden Sie den Debugger, um die Debugging -Effizienz zu verbessern.

PHP entstand 1994 und wurde von Rasmuslerdorf entwickelt. Es wurde ursprünglich verwendet, um Website-Besucher zu verfolgen und sich nach und nach zu einer serverseitigen Skriptsprache entwickelt und in der Webentwicklung häufig verwendet. Python wurde Ende der 1980er Jahre von Guidovan Rossum entwickelt und erstmals 1991 veröffentlicht. Es betont die Lesbarkeit und Einfachheit der Code und ist für wissenschaftliche Computer, Datenanalysen und andere Bereiche geeignet.
