Maison  >  Article  >  développement back-end  >  Exemple de code pour les primitives de synchronisation de threads en python

Exemple de code pour les primitives de synchronisation de threads en python

不言
不言avant
2018-11-20 16:06:092987parcourir

Le contenu de cet article concerne les exemples de code des primitives de synchronisation de threads en python. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.

Le module Threading est un module multi-threading en python3. Le module intègre de nombreuses classes, dont Thread, Condition, Event, Lock, Rlock, Semaphore, Timer, etc. L'article suivant utilise principalement des cas pour illustrer l'utilisation d'Event et de Segmaphore (Boundedsegmaphore).

Event

La classe Event stocke en interne un paramètre flags pour indiquer si l'événement est en attente ou non.

Fonction d'instance de classe d'événement

1. set() Définissez les indicateurs sur True, l'événement cesse de bloquer

2. Réinitialisez les indicateurs sur False, supprimez les indicateurs, le l'événement est rebloqué

3. wait() définit l'événement à l'état d'attente

4.is_set() détermine si les indicateurs sont définis et renvoie True s'il est défini. , sinon renvoie Faux

(1) Un seul événement attend l'apparition d'autres événements

Code spécifique :

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()

Résultat :

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) Plusieurs événements se sont produits les uns après les autres

Prenons l'exemple des courses. Supposons qu'il y ait 5 pistes, chacune avec un athlète, ABCDE.

Code spécifique :

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操作

Résultat :

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

On peut voir que le set() des événements dans plusieurs threads est aléatoire et que son implémentation interne est due à une méthode notify_all(). Cette méthode libérera tous les événements verrouillés en même temps. Quel que soit le thread qui saisit la tranche de temps du thread exécuté en premier, le verrou sera libéré en premier.

La raison pour laquelle tous les événements peuvent être bloqués en appelant une seule fonction set() est que event.wait() est implémenté à l'intérieur du thread, tandis que la fonction set() est appelée dans le processus Python multi. -les threads partagent un espace mémoire de processus. Ceci ne peut pas être réalisé si ces deux fonctions sont appelées dans des processus différents.

BoundedSegmaphore

Si l'hôte effectue des tâches gourmandes en E/S puis exécute un programme qui exécute un grand nombre de tâches (multi-threading) en peu de temps, le l'ordinateur aura Il sera probablement en panne.

À ce stade, vous pouvez ajouter une fonction de compteur à ce programme pour limiter le nombre de threads à un moment donné. Chaque fois que vous effectuez une opération IO, vous devez demander une ressource (verrouillage) au segmaphore. Si elle n'est pas demandée, elle se bloquera et attendra. Ce n'est que lorsque la demande est réussie que c'est comme exécuter la tâche.

La différence entre BoundedSegmaphore et Segmaphore

Le nombre de verrous demandés par BoundedSegmaphore est fixé aux paramètres entrants, tandis que le nombre de verrous demandés par Segmaphore peut dépasser les paramètres entrants.

Fonctions principales :

1. acquérir() Demander le verrouillage

2. release() Libérer le verrouillage

Ce qui suit est un exemple de location d'une maison. pour illustrer cela Un mécanisme pour fixer le nombre de serrures. Supposons qu’un petit appartement comporte 6 pièces et soit initialement occupé par 2 résidents.

Implémentation de code spécifique :

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()

Résultat :

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 房间

Vous pouvez voir Out, le nombre de pièces ne dépassera jamais 6, car la valeur _value (le compteur à l'intérieur de BoundedSegmaphore) doit être le paramètre entrant 6.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer