Heim > Backend-Entwicklung > Python-Tutorial > Python-Multithread-Programmierung 3: Verwenden Sie Mutex-Sperren, um Threads zu synchronisieren

Python-Multithread-Programmierung 3: Verwenden Sie Mutex-Sperren, um Threads zu synchronisieren

高洛峰
Freigeben: 2016-10-18 11:33:20
Original
1244 Leute haben es durchsucht

Position der Frage

Im Beispiel im vorherigen Abschnitt ist jeder Thread unabhängig voneinander und hat keine Beziehung zueinander. Nehmen wir nun ein Beispiel an: Es gibt eine globale Anzahl num, jeder Thread erhält diese globale Anzahl, führt einige Verarbeitungen basierend auf num durch und addiert dann 1 zu num. Es ist einfach, Code wie diesen zu schreiben:

# encoding: UTF-8
import threading
import time
  
class MyThread(threading.Thread):
    def run(self):
        global num
        time.sleep(1)
        num = num+1
        msg = self.name+' set num to '+str(num)
        print msg
num = 0
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
Nach dem Login kopieren

, aber das Laufergebnis ist falsch:


Thread-5 set num to 2

Thread-3 hat die Nummer auf 3 gesetzt

Thread-2 hat die Nummer auf 5 gesetzt

Thread-1 hat die Nummer auf 5 gesetzt

Thread-4 hat die Nummer auf 4 gesetzt


Der Grund für das Problem liegt darin, dass der Zugriff mehrerer Threads auf dieselbe Ressource nicht kontrolliert wird, was zu Datenschäden führt und die Ergebnisse des Thread-Betriebs unvorhersehbar macht. Dieses Phänomen wird als „Thread unsicher“ bezeichnet.

Mutex-Sperrsynchronisation

Das obige Beispiel führt zum häufigsten Problem der Multithread-Programmierung: der Datenfreigabe. Wenn mehrere Threads bestimmte gemeinsam genutzte Daten ändern, ist eine Synchronisationssteuerung erforderlich.

Thread-Synchronisierung kann sicherstellen, dass mehrere Threads sicher auf konkurrierende Ressourcen zugreifen. Der einfachste Synchronisierungsmechanismus besteht darin, eine Mutex-Sperre einzuführen. Ein Mutex führt einen Zustand für eine Ressource ein: gesperrt/entsperrt. Wenn ein Thread gemeinsam genutzte Daten ändern möchte, muss er diese zunächst sperren. Zu diesem Zeitpunkt ist der Status der Ressource „gesperrt“ und andere Threads können ihn nicht ändern, bis der Thread die Ressource freigibt und den Status der Ressource in „sperrt“. entsperrt“, andere Threads können die Ressource wieder sperren. Die Mutex-Sperre stellt sicher, dass jeweils nur ein Thread Schreibvorgänge ausführt und stellt so die Korrektheit der Daten in Multithread-Situationen sicher.

Die Lock-Klasse ist im Threading-Modul definiert, das das Sperren bequem handhaben kann:

#Create lock

mutex = threading.Lock()

#Lock

mutex.acquire([timeout])

#Release

mutex.release()

Daunter kann die Sperrmethode „acquire“ vorhanden sein ein Timeout-Zeitraum. Optionaler Parameter timeout. Wenn eine Zeitüberschreitung festgelegt ist, kann der Rückgabewert verwendet werden, um zu bestimmen, ob die Sperre nach der Zeitüberschreitung erhalten wird, sodass eine andere Verarbeitung durchgeführt werden kann.

Der Code zum Implementieren des obigen Beispiels mithilfe eines Mutex lautet wie folgt:

import threading
import time
  
class MyThread(threading.Thread):
    def run(self):
        global num
        time.sleep(1)
  
        if mutex.acquire(1): 
            num = num+1
            msg = self.name+' set num to '+str(num)
            print msg
            mutex.release()
num = 0
mutex = threading.Lock()
def test():
    for i in range(5):
        t = MyThread()
        t.start()
if __name__ == '__main__':
    test()
Nach dem Login kopieren

Laufergebnis:


Thread-3 setze num auf 1

Thread-4 setze num auf 2

Thread-5 setze num auf 3

Thread-2 setze num auf 4

Thread -1 num auf 5 setzen

Sie können sehen, dass die laufenden Ergebnisse nach dem Hinzufügen der Mutex-Sperre den Erwartungen entsprechen.

Synchronisierte Blockierung

Wenn ein Thread die acquire()-Methode der Sperre aufruft, um die Sperre zu erhalten, wechselt die Sperre in den Status „gesperrt“. Es kann jeweils nur ein Thread die Sperre erhalten. Wenn zu diesem Zeitpunkt ein anderer Thread versucht, die Sperre zu erhalten, wird der Thread „blockiert“, was als „synchrones Blockieren“ bezeichnet wird (siehe Grundkonzept von Multithreading).

Bis der Thread, der die Sperre besitzt, die Methode release() der Sperre aufruft, um die Sperre freizugeben, wechselt die Sperre in den Status „entsperrt“. Der Thread-Scheduler wählt einen der Threads im synchronen Blockierungszustand aus, um die Sperre zu erhalten, und versetzt den Thread in den laufenden Zustand.

Dies sind die grundlegendsten Inhalte von Mutex-Sperren. Im nächsten Abschnitt werden die Probleme mit Wiedereintrittssperren (RLock) und Deadlocks erläutert.


Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage