Frage

In Python gesagt, wie Variablen erhält zwischen Threads gemeinsam?

Obwohl ich threading.Thread verwendet habe, bevor ich nie wirklich verstanden, oder sah Beispiele dafür, wie Variablen geteilt wurde. Geteilt werden sie zwischen dem Haupt-Thread und die Kinder oder nur unter den Kindern? Wann brauche ich, um Thread-Lokalspeicher verwenden, um diesen Austausch zu vermeiden?

Ich habe viele Warnungen gesehen Zugriff auf gemeinsam genutzte Daten zwischen Threads zu synchronisieren durch Sperren verwenden, aber ich habe noch ein wirklich gutes Beispiel für das Problem zu sehen.

Vielen Dank im Voraus!

War es hilfreich?

Lösung

In Python, alles geteilt wird, mit Ausnahme der Funktion lokale Variablen (weil jeder Funktionsaufruf einen eigenen Satz von Einheimischen bekommt, und Threads sind immer getrennte Funktionsaufrufe.) Und selbst dann nur die Variablen selbst (die Namen, die verweisen auf Objekte) sind auf die Funktion lokal; Objekte selbst immer global sind, und alles, was auf sie verweisen können. Das Thread Objekt für einen bestimmten Thread ist kein spezielles Objekt in dieser Hinsicht. Wenn Sie das Thread Objekt irgendwo alle Threads (wie eine globale Variable) zugreifen können gespeichert werden, dann können alle Threads zugreifen, die ein Thread Objekt. Wenn Sie atomar ändern möchten alles , dass Sie gerade nicht in diesem selben Thread erstellen und speichern Sie nicht überall ein anderer Thread auf sie bekommen können, müssen Sie es durch ein Schloss zu schützen. Und alle Themen natürlich teilen diese gleiche Sperre muss, oder es wäre nicht sehr effektiv sein.

Wenn Sie aktuelle Thread-Local Storage wollen, das ist, wo threading.local kommt Attribute threading.local nicht zwischen Threads gemeinsam genutzt. jeder Thread sieht nur die Attribute sie sich in dort platziert. Wenn Sie über die Implementierung neugierig sind, dann ist die Quelle in _threading_local.py in der Standardbibliothek.

Andere Tipps

Betrachten Sie den folgenden Code ein:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread, local

data = local()

def bar():
    print("I'm called from", data.v)

def foo():
    bar()

class T(Thread):
    def run(self):
        sleep(random())
        data.v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-1 

Hier threading.local () als schnelle und schmutzige Art und Weise verwendet, um einige Daten von Lauf () übergeben bar () ohne die Schnittstelle foo Ändern ().

Beachten Sie, dass globale Variablen nicht den Trick tun:

#/usr/bin/env python

from time import sleep
from random import random
from threading import Thread

def bar():
    global v
    print("I'm called from", v)

def foo():
    bar()

class T(Thread):
    def run(self):
        global v
        sleep(random())
        v = self.getName()   # Thread-1 and Thread-2 accordingly
        sleep(1)
        foo()
 >> T().start(); T().start()
I'm called from Thread-2
I'm called from Thread-2 

Inzwischen, wenn Sie durch als Argument foo diese Daten leisten können () über - es wäre eine elegante und gut gestaltete Art und Weise:

from threading import Thread

def bar(v):
    print("I'm called from", v)

def foo(v):
    bar(v)

class T(Thread):
    def run(self):
        foo(self.getName())

Das ist aber nicht immer möglich, wenn von Drittanbietern oder schlecht konzipiert Code.

Sie können Thread-Lokalspeicher mit threading.local() erstellen.

>>> tls = threading.local()
>>> tls.x = 4 
>>> tls.x
4

Die Daten zu dem tls gespeichert werden jeden Thread eindeutig sein, die dazu beitragen wird, dass ein unbeabsichtigter Austausch findet nicht statt.

Genau wie in jeder anderen Sprache, hat jeder Thread in Python Zugriff auf die gleichen Variablen. Es gibt keinen Unterschied zwischen dem ‚Haupt-Thread‘ und Kind Threads.

Ein Unterschied mit Python ist, dass die Global Interpreter Lock bedeutet, dass nur ein Thread zu einem Zeitpunkt Python Code ausgeführt werden. Dies ist keine große Hilfe, wenn es um den Zugang zu synchronisieren, aber, wie alle üblichen Vorkaufsrecht Fragen noch anwenden, und Sie haben Threading Primitiven, wie in anderen Sprachen nur zu verwenden. Es bedeutet, dass Sie zu überdenken müssen, wenn Sie wurden Themen für die Leistung verwenden, jedoch.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top