Heim  >  Artikel  >  Backend-Entwicklung  >  Codebeispiel für Thread-Synchronisierungsprimitive in Python

Codebeispiel für Thread-Synchronisierungsprimitive in Python

不言
不言nach vorne
2018-11-20 16:06:093042Durchsuche

Der Inhalt dieses Artikels befasst sich mit den Codebeispielen für Thread-Synchronisationsprimitive in Python. Ich hoffe, dass er für Freunde hilfreich ist.

Das Threading-Modul ist ein Multithreading-Modul in Python3. Das Modul integriert viele Klassen, einschließlich Thread, Bedingung, Ereignis, Sperre, Rlock, Semaphore, Timer und so weiter. Der folgende Artikel verwendet hauptsächlich Fälle, um die Verwendung von Event und Segmaphore (Boundedsegmaphore) zu veranschaulichen.

Ereignis

Die Event-Klasse speichert intern einen Flags-Parameter, um zu markieren, ob das Ereignis wartet oder nicht.

Ereignisklasseninstanzfunktion

1. set() Flags auf True setzen, das Ereignis stoppt die Blockierung

2. Flags auf False zurücksetzen, Flags löschen Ereignis wird erneut blockiert

3. wait() setzt das Ereignis in den Wartezustand

4.is_set() ermittelt, ob Flags gesetzt sind, und gibt True zurück, wenn es gesetzt ist , andernfalls wird False zurückgegeben

(1) Ein einzelnes Ereignis wartet auf das Eintreten anderer Ereignisse

Spezifischer Code:

from time import ctime,sleep
event = Event()

def event_wait():
    print(ctime())
    event.wait()
    print('这是event_wait方法中的时间',ctime())

def event_set(n):
    sleep(n)
    event.set()
    print('这是event_set方法中的时间', ctime())

thread1 = Thread(target=event_wait)
thread2 = Thread(target=event_set,args=(3,))

thread1.start()
thread2.start()

Ergebnis:

Sat Nov 17 10:01:05 2018
这是event_wait方法中的时间 Sat Nov 17 10:01:08 2018
这是event_set方法中的时间  Sat Nov 17 10:01:08 2018

(2) Mehrere Ereignisse ereigneten sich nacheinander

Nehmen wir den Rennsport als einen Beispiel. Nehmen Sie an, dass es 5 Start- und Landebahnen mit jeweils einem Athleten ABCDE gibt.

Spezifischer Code:

from threading import Event
from  threading import Thread
import threading

event = Event()

def do_wait(athlete):
    racetrack = threading.current_thread().getName()
    print('%s准备就绪' % racetrack)
    event.wait()
    print('%s听到枪声,起跑!'%athlete)

thread1 = Thread(target=do_wait,args=("A",))
thread2 = Thread(target=do_wait,args=("B",))
thread3 = Thread(target=do_wait,args=("C",))
thread4 = Thread(target=do_wait,args=("D",))
thread5 = Thread(target=do_wait,args=("E",))

threads = []
threads.append(thread1)
threads.append(thread2)
threads.append(thread3)
threads.append(thread4)
threads.append(thread5)

for th in threads:
    th.start()

event.set()  #这个set()方法很关键,同时对5个线程中的event进行set操作

Ergebnis:

Thread-1准备就绪
Thread-2准备就绪
Thread-3准备就绪
Thread-4准备就绪
Thread-5准备就绪
E听到枪声,起跑!
A听到枪声,起跑!
B听到枪声,起跑!
D听到枪声,起跑!
C听到枪声,起跑!

Ja Es ist ersichtlich, dass die Menge () von Ereignissen in mehreren Threads zufällig ist und ihre interne Implementierung auf eine notify_all()-Methode zurückzuführen ist. Diese Methode gibt alle gesperrten Ereignisse auf einmal frei. Der Thread, der die Zeitscheibe des zuerst ausgeführten Threads übernimmt, gibt die Sperre zuerst frei.

Der Grund, warum alle Ereignisse durch den Aufruf nur einer set()-Funktion blockiert werden können, liegt darin, dass event.wait() innerhalb des Threads implementiert ist, während die set()-Funktion im Python-Prozess mehrfach aufgerufen wird -Threads teilen sich einen Prozessspeicherplatz. Dies kann nicht erreicht werden, wenn diese beiden Funktionen in unterschiedlichen Prozessen aufgerufen werden.

BoundedSegmaphore

Wenn der Host IO-intensive Aufgaben ausführt und dann ein Programm ausführt, das eine große Anzahl von Aufgaben (Multithreading) in kurzer Zeit erledigt, wird die Der Computer wird höchstwahrscheinlich ausgefallen sein.

Zu diesem Zeitpunkt können Sie diesem Programm eine Zählerfunktion hinzufügen, um die Anzahl der Threads zu einem bestimmten Zeitpunkt zu begrenzen. Jedes Mal, wenn Sie eine E/A-Operation ausführen, müssen Sie eine Ressource (Sperre) vom Segmaphor anfordern. Wenn diese nicht angefordert wird, wird sie blockiert und gewartet. Nur wenn die Anforderung erfolgreich ist, wird die Aufgabe ausgeführt.

Der Unterschied zwischen BoundedSegmaphore und Segmaphore

Die Anzahl der von BoundedSegmaphore angeforderten Sperren ist auf die übergebenen Parameter festgelegt, während die Anzahl der von Segmaphore angeforderten Sperren die übergebenen Parameter überschreiten kann.

Hauptfunktionen:

1. acquire() Anforderungssperre

2. release() Freigabesperre

Das Folgende ist ein Beispiel für die Anmietung eines Hauses Um dies zu veranschaulichen: Ein Mechanismus zum Festlegen der Anzahl der Schlösser. Angenommen, eine kleine Wohnung hat 6 Zimmer und wird ursprünglich von 2 Bewohnern bewohnt.

Spezifische Code-Implementierung:

from threading import BoundedSemaphore,Lock,Thread
from time import sleep
from random import randrange

lock = Lock()
num = 6
hotel = BoundedSemaphore(num)

def logout():
    lock.acquire()
    print('I want to logout')
    print('A customer logout...')
    try:
        hotel.release()
        print('Welcome again')
    except ValueError:
        print('Sorry,wait a moment.')
    lock.release()

def login():
    lock.acquire()
    print('I want to login')
    print('A customer login...')
    if hotel.acquire(False):
        print('Ok,your room number is...')
    else:
        print('Sorry,our hotel is full')
    lock.release()

#房东
def producer(loops):
    for i in range(loops):
        logout()
        print('还剩%s' % hotel._value, '房间')
        sleep(randrange(2))
#租客
def consumer(loops):
    for i in range(loops):
        login()
        print('还剩%s' % hotel._value, '房间')
        sleep(randrange(2))
def main():
    print('Start')
    room_num = hotel._value
    print('The hotel is full with %s room'%room_num)
    #原本有2个住户
    hotel.acquire()
    hotel.acquire()
    thread1 = Thread(target=producer,args=(randrange(2,8),))
    thread2 = Thread(target=consumer,args=(randrange(2,8),))
    thread1.start()
    thread2.start()

if __name__ == '__main__':
    main()

Ergebnis:

The hotel is full with 6 room
I want to logout
A customer logout...
Welcome again
还剩5 房间
I want to logout
A customer logout...
Welcome again
还剩6 房间
I want to login
A customer login...
Ok,your room number is...
还剩5 房间
I want to login
A customer login...
Ok,your room number is...
还剩4 房间

Es ist ersichtlich, dass die Anzahl der Räume Es wird niemals 6 überschreiten, da der _value-Wert (der Zähler innerhalb der BoundedSegmaphore) der eingehende Parameter 6 sein muss.

Das obige ist der detaillierte Inhalt vonCodebeispiel für Thread-Synchronisierungsprimitive in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Vorheriger Artikel:Was ist ein Python-Crawler?Nächster Artikel:Was ist ein Python-Crawler?