Dieser Artikel bietet Ihnen eine Einführung in die gemeinsame Nutzung von Ressourcen und häufig verwendete Sperrmechanismen zwischen Threads. Ich hoffe, dass er für Sie hilfreich ist.
In diesem Artikel werden kurz die Ressourcenfreigabe zwischen Threads und häufig verwendete Sperrmechanismen in der Multithread-Programmierung vorgestellt.
Bei der Multithread-Programmierung kommt es häufig zu Ressourcenfreigaben zwischen Threads:
Globale Variablen (global)
Warteschlange (aus der Warteschlangen-Importwarteschlange)
Häufig verwendeter Sperrmechanismus für die gemeinsame Nutzung von Ressourcen:
Sperre
RLock
Semphore
Bedingung
Die Verwendung globaler Variablen kann die Ressourcenfreigabe zwischen Threads realisieren, Stichwort global
Code-Demonstration:
from threading import Thread, Lock lock = Lock() total = 0 '''如果不使用lock那么,最后得到的数字不一定为0;同时loack不支持连续多次acquire,如果这样做了的后果是死锁!''' def add(): global total global lock for i in range(1000000): lock.acquire() total += 1 lock.release() def sub(): global total global lock for i in range(1000000): lock.acquire() total -= 1 lock.release() thread1 = Thread(target=add) thread2 = Thread(target=sub) # 将Thread1和2设置为守护线程,主线程完成时,子线程也一起结束 # thread1.setDaemon(True) # thread1.setDaemon(True) # 启动线程 thread1.start() thread2.start() # 阻塞,等待线程1和2完成,如果不使用join,那么主线程完成后,子线程也会自动关闭。 thread1.join() thread2.join() total
Verwenden Sie die Warteschlange, um Ressourcen zu teilen. Die Warteschlange ist threadsicher.
from threading import Thread, Lock from queue import Queue def add(q): if q.not_full: q.put(1) def sub(q): if q.not_empty: recv = q.get() print(recv) q.task_done() if __name__ =='__main__': # 设置q最多接收3个任务,Queue是线程安全的,所以不需要Lock qu = Queue(3) thread1 = Thread(target=add, args=(qu,)) thread2 = Thread(target=sub, args=(qu,)) thread1.start() thread2.start() # q队列堵塞,等待所有任务都被处理完。 qu.join()
Sperre
Lock kann keine kontinuierlichen Sperren erwerben, da es sonst zu einem Deadlock kommen kann. Der Wettbewerb um Lock-Ressourcen kann zu einem Deadlock führen.
Sperre verringert die Leistung.
from threading import Thread, Lock lock = Lock() total = 0 '''如果不使用lock那么,最后得到的数字不一定为0;同时lock不支持连续多次acquire,如果这样做了的后果是死锁!''' def add(): global total global lock for i in range(1000000): lock.acquire() total += 1 lock.release() def sub(): global total global lock for i in range(1000000): lock.acquire() total -= 1 lock.release() thread1 = Thread(target=add) thread2 = Thread(target=sub) # 将Thread1和2设置为守护线程,主线程完成时,子线程也一起结束 # thread1.setDaemon(True) # thread1.setDaemon(True) # 启动线程 thread1.start() thread2.start() # 阻塞,等待线程1和2完成,如果不使用join,那么主线程完成后,子线程也会自动关闭。 thread1.join() thread2.join() total
RLock
RLock kann kontinuierlich Sperren erwerben, es ist jedoch eine entsprechende Anzahl von Freigaben erforderlich, um die Sperren freizugeben
weil es kontinuierlich erfasst werden kann Sperre, also wird die Funktion mit Sperre implementiert
from threading import Thread, Lock, RLock lock = RLock() total = 0 def add(): global lock global total # RLock实现连续获取锁,但是需要相应数量的release来释放资源 for i in range(1000000): lock.acquire() lock.acquire() total += 1 lock.release() lock.release() def sub(): global lock global total for i in range(1000000): lock.acquire() total -= 1 lock.release() thread1 = Thread(target=add) thread2 = Thread(target=sub) thread1.start() thread2.start() thread1.join() thread2.join() total
from threading import Thread, Condition '''聊天 Peaple1 : How are you? Peaple2 : I`m fine, thank you! Peaple1 : What`s your job? Peaple2 : My job is teacher. ''' def Peaple1(condition): with condition: print('Peaple1 : ', 'How are you?') condition.notify() condition.wait() print('Peaple1 : ', 'What`s your job?') condition.notify() condition.wait() def Peaple2(condition): with condition: condition.wait() print('Peaple2 : ', 'I`m fine, thank you!') condition.notify() condition.wait() print('Peaple2 : ', 'My job is teacher.') condition.notify() if __name__ == '__main__': cond = Condition() thread1 = Thread(target=Peaple1, args=(cond,)) thread2 = Thread(target=Peaple2, args=(cond,)) # 此处thread2要比thread1提前启动,因为notify必须要有wait接收;如果先启动thread1,没有wait接收notify信号,那么将会死锁。 thread2.start() thread1.start() # thread1.join() # thread2.join()
Das obige ist der detaillierte Inhalt vonEine Einführung in die gemeinsame Nutzung von Ressourcen zwischen Threads und häufig verwendete Sperrmechanismen beim Python-Multithreading. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!