Semaphoren in Python

Haider Ali 21 Juni 2023
Semaphoren in Python

In diesem Handbuch erfahren Sie, wie Sie mit Multi-Threading in Python mithilfe von Semaphoren umgehen. Wie erhält man synchronisierten Zugriff auf die Threads und die begrenzte Menge an Ressourcen?

Semaphoren

Ein Synchronisationscontroller ist ein Semaphor. Semaphore bietet synchronisierten Zugriff auf eine begrenzte Anzahl von Ressourcen für Threads.

Ein Semaphor kann als eine Variable angesehen werden, die darstellt, wie viele Ressourcen jetzt verfügbar sind.

Beispielsweise stehen auf einem Parkplatz in einem Einkaufszentrum, der als Semaphor fungiert, mehrere Stellplätze auf einer bestimmten Ebene zur Verfügung.

Der Wert des Semaphors muss größer oder kleiner als die verfügbaren Ressourcen sein. Die Operationen Erfassen und Freigeben sind mit der Semaphore verbunden.

Der Wert des Semaphors wird verringert, wenn eine der für die Synchronisation verwendeten Ressourcen von einem Thread “erworben” wird. Der Wert des Semaphors wird erhöht, wenn eine der synchronisierten Ressourcen von einem Thread “freigegeben” wird.

Semaphoren in Python

Pythons Implementierung des Semaphor-Konzepts verwendet eine Klasse aus dem threading-Modul. Semaphore ist der Name dieser Klasse.

Eine acquire()- und eine release()-Funktion sind beide in der Semaphore-Klasse enthalten, zusammen mit einem Funktionskonstruktor.

Wenn die Anzahl der Semaphoren größer als Null ist, wird die Funktion acquire() verwendet, um die Anzahl zu verringern. Wenn nicht, wird es blockiert, bis der Zählerstand größer als 0 ist.

Einer der Threads, die auf dem Semaphor sitzen, wird mit der Funktion release() geweckt, was auch die Anzahl des Semaphors erhöht. Lassen Sie uns nun die Syntax des Semaphors verstehen.

object_name = threading.Semaphore(count)

Das Objekt der Klasse Semaphore wird in der obigen Syntax durch object_name angezeigt.

Die Anzahl der Threads, die gleichzeitig zugreifen dürfen, wird durch das Argument count der Klasse Semaphore angegeben. Der Standardwert dieses Parameters ist 1.

Der Wert des Parameters count wird jedes Mal um eins verringert, wenn ein Thread die Funktion acquire() verwendet. Der Wert des Parameters count wird jedes Mal um eins erhöht, wenn ein Thread die Funktion release() verwendet.

Gemäß dieser Aussage wird der Wert des Parameters count jedes Mal sinken, wenn wir die Methode acquire() aufrufen; Wenn wir jedoch die Funktion release() aufrufen, wird der Wert des Parameters count erhöht. Sehen Sie sich den folgenden Code an.

# import threading module
import threading

# creating instance of semaphore
sema = threading.Semaphore(1)


def test():
    # appling semaphore
    print(f"Value Of Semaphore --> {sema._value}")
    sema.acquire()
    print(f"acquired lock --> {threading.current_thread().name}")
    print(f"Value Of Semaphore --> {sema._value}")
    print(f"release lock --> {threading.current_thread().name}")
    sema.release()
    print(f"Value Of Semaphore --> {sema._value}")


# initializing threads
t1 = threading.Thread(target=test)
t2 = threading.Thread(target=test)
t3 = threading.Thread(target=test)
# executing threads
t1.start()
t2.start()
t3.start()

Die Threads werden synchronisiert, wenn count wie im obigen Code auf 1 gesetzt ist. Wenn wir uns die Ausgabe des obigen Codes ansehen, werden wir feststellen, dass es sich um den ersten und den zweiten Thread handelt, dann hat der dritte Thread Zugriff auf den Code zwischen acquire und release.

Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
Value Of Semaphore --> 0
release lock --> Thread-3 (test)
Value Of Semaphore --> 1

Wenn Sie den Wert von count von 1 auf 2 ändern würden, würden Sie zwei Threads gleichzeitig für den eingeschränkten Code zulassen. Die Ausgabe wird also anders sein.

Value Of Semaphore --> 2
acquired lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
release lock --> Thread-1 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 1
acquired lock --> Thread-3 (test)
acquired lock --> Thread-2 (test)
Value Of Semaphore --> 0
Value Of Semaphore --> 0
release lock --> Thread-2 (test)
release lock --> Thread-3 (test)
Value Of Semaphore --> 1
Value Of Semaphore --> 2

Beachten Sie, dass die Zeit, die der Semaphor benötigt, um den Thread freizugeben, von der Geschwindigkeit Ihres Geräts abhängt und jedes Mal anders ist. Sie können den obigen Code testen, indem Sie den Wert von count in der Instanz des Semaphors ändern.

Autor: Haider Ali
Haider Ali avatar Haider Ali avatar

Haider specializes in technical writing. He has a solid background in computer science that allows him to create engaging, original, and compelling technical tutorials. In his free time, he enjoys adding new skills to his repertoire and watching Netflix.

LinkedIn