web-dev-qa-db-fra.com

Python création d'une variable partagée entre les threads

Je travaille sur un projet en Python en utilisant le module "thread".

Comment créer une variable globale (dans mon cas, j'ai besoin qu'elle soit vraie ou fausse) à laquelle tous les threads de mon projet (environ 4-6) peuvent accéder?

21
Shay

Nous pouvons définir la variable en dehors des classes de threads et la déclarer globale dans les méthodes des classes.

Veuillez voir ci-dessous un exemple trivial qui imprime AB alternativement. Deux variables flag et val sont partagées entre deux threads Thread_A et Thread_B. Thread_A imprime val=20 puis définit val sur 30. Thread_B imprime val=30, puisque val est modifié dans Thread_A. Thread_B définit ensuite val sur 20, qui est à nouveau utilisé dans Thread_A. Cela montre que la variable val est partagée entre deux threads. De même, la variable flag est également partagée entre deux threads.

import threading
import time
c = threading.Condition()
flag = 0      #shared between Thread_A and Thread_B
val = 20

class Thread_A(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        global flag
        global val     #made global here
        while True:
            c.acquire()
            if flag == 0:
                print "A: val=" + str(val)
                time.sleep(0.1)
                flag = 1
                val = 30
                c.notify_all()
            else:
                c.wait()
            c.release()


class Thread_B(threading.Thread):
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = name

    def run(self):
        global flag
        global val    #made global here
        while True:
            c.acquire()
            if flag == 1:
                print "B: val=" + str(val)
                time.sleep(0.5)
                flag = 0
                val = 20
                c.notify_all()
            else:
                c.wait()
            c.release()


a = Thread_A("myThread_name_A")
b = Thread_B("myThread_name_B")

b.start()
a.start()

a.join()
b.join()

La sortie ressemble à

A: val=20
B: val=30
A: val=20
B: val=30
A: val=20
B: val=30
A: val=20
B: val=30

Chaque thread affiche la valeur qui a été modifiée dans un autre thread.

23
user3343166

Sans aucune idée de ce que vous essayez vraiment de faire, optez pour l'approche de nio et utilisez des verrous, ou considérez les variables de condition:

De la docs

# Consume one item
cv.acquire()
while not an_item_is_available():
    cv.wait()
get_an_available_item()
cv.release()

# Produce one item
cv.acquire()
make_an_item_available()
cv.notify()
cv.release()

Vous pouvez l'utiliser pour laisser un thread informer un autre qu'une condition a été remplie, sans avoir à penser explicitement aux verrous. Cet exemple utilise cv pour indiquer qu'un élément est disponible.

7
doctorlove