0Pricing
Python Academy · Lektion

Daten sicher gemeinsam nutzen

Queues und Locks verwenden

Daten sicher gemeinsam nutzen ist eine kostenlose Python Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Python Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Python Academy-Kurs umfasst insgesamt 4 Lektionen.

Das Problem mit Race Conditions

Wenn mehrere Threads dieselben Daten ändern, können sich ihre Operationen überschneiden und das Ergebnis beschädigen. Das ist eine Race Condition. Wir benötigen Synchronisationswerkzeuge, um Daten sicher gemeinsam zu nutzen.

import threading

counter = 0

def bump():
    global counter
    for _ in range(100000):
        counter += 1

ts = [threading.Thread(target=bump) for _ in range(2)]
for t in ts: t.start()
for t in ts: t.join()
print('counter (may be < 200000):', counter)

Lock als Lösung

Ein threading.Lock stellt sicher, dass immer nur ein Thread gleichzeitig einen kritischen Abschnitt betritt. Erwerben Sie ihn mit einem with-Block, der die gemeinsame Aktualisierung umschließt.

import threading

counter = 0
lock = threading.Lock()

def bump():
    global counter
    for _ in range(100000):
        with lock:
            counter += 1

ts = [threading.Thread(target=bump) for _ in range(2)]
for t in ts: t.start()
for t in ts: t.join()
print('counter:', counter)

acquire und release

Ein Lock kann mit acquire() und release() manuell verwendet werden. Die with-Variante ist jedoch sicherer, weil sie den Lock auch bei einem Fehler freigibt.

import threading

lock = threading.Lock()
lock.acquire()
try:
    print('inside critical section')
finally:
    lock.release()
print('released')

Threadsichere Queues

Die Klasse queue.Queue ist bereits threadsicher. Threads können put und get ohne explizite Locks verwenden, weshalb sie die bevorzugte Methode zur Datenübergabe ist.

import queue, threading

q = queue.Queue()

def producer():
    for i in range(3):
        q.put(i)

t = threading.Thread(target=producer)
t.start()
t.join()
while not q.empty():
    print('got', q.get())

Producer und Consumer

Das klassische Muster: Producer legen Arbeit mit put in eine Queue, Consumer holen sie mit get und verarbeiten sie. Die Queue übernimmt die gesamte Synchronisierung.

import queue, threading

q = queue.Queue()
results = []

def consumer():
    while True:
        item = q.get()
        if item is None:
            break
        results.append(item * 10)
        q.task_done()

t = threading.Thread(target=consumer)
t.start()
for i in range(3):
    q.put(i)
q.put(None)
t.join()
print(results)

join und task_done

q.join() blockiert, bis für jedes per put eingefügte Element ein passender Aufruf von task_done() erfolgt ist. So kann der Hauptthread warten, bis die gesamte Arbeit abgeschlossen ist.

import queue, threading

q = queue.Queue()

def worker():
    while True:
        item = q.get()
        q.task_done()

threading.Thread(target=worker, daemon=True).start()
for i in range(5):
    q.put(i)
q.join()
print('all items processed')

RLock für Reentranz

Ein gewöhnlicher Lock führt zu einem Deadlock, wenn derselbe Thread versucht, ihn zweimal zu erwerben. Ein threading.RLock (re-entrant Lock) erlaubt dies und zählt die Erwerbungen.

import threading

rlock = threading.RLock()

def outer():
    with rlock:
        inner()

def inner():
    with rlock:
        print('re-entered safely')

outer()

Mit Event signalisieren

Mit einem threading.Event kann ein Thread anderen Threads ein Signal geben. Threads rufen wait() auf, bis ein anderer Thread set() aufruft.

import threading

start = threading.Event()

def worker():
    start.wait()
    print('go!')

t = threading.Thread(target=worker)
t.start()
print('setting event')
start.set()
t.join()

Gemeinsame Datennutzung zwischen Prozessen

Verwenden Sie zwischen Prozessen stattdessen multiprocessing.Queue. Diese serialisiert Objekte zwischen getrennten Speicherbereichen.

import multiprocessing as mp

def producer(q):
    for i in range(3):
        q.put(i * i)

if __name__ == '__main__':
    q = mp.Queue()
    p = mp.Process(target=producer, args=(q,))
    p.start()
    p.join()
    while not q.empty():
        print('received', q.get())

Deadlocks vermeiden

Ein Deadlock entsteht, wenn Threads für immer auf die Locks des jeweils anderen warten. Vermeiden Sie dies, indem Sie mehrere Locks überall in der gleichen Reihenfolge erwerben.

import threading

lock_a = threading.Lock()
lock_b = threading.Lock()

def safe():
    with lock_a:
        with lock_b:
            print('acquired in consistent order')

safe()

Queues gegenüber Locks bevorzugen

Wenn möglich, sollten Sie die Nachrichtenübermittlung mit Queues dem gemeinsam genutzten, veränderlichen Zustand mit Locks vorziehen. Sie ist leichter nachzuvollziehen und verursacht deutlich seltener Fehler.

import queue

q = queue.Queue()
for word in ['safe', 'simple', 'clear']:
    q.put(word)
while not q.empty():
    print(q.get())

Kurztest

Testen Sie Ihr Verständnis der sicheren Datennutzung.

Rückblick

Sie haben gelernt, Daten sicher gemeinsam zu nutzen:

  • Race Conditions beschädigen ungeschützten gemeinsam genutzten Zustand.
  • Lock und RLock schützen kritische Abschnitte.
  • queue.Queue ist threadsicher; verwenden Sie zwischen Prozessen multiprocessing.Queue.
  • Event übermittelt Signale zwischen Threads; eine einheitliche Reihenfolge beim Erwerben von Locks verhindert Deadlocks.

Nächster Kurs: externe Programme mit subprocess ausführen.

Häufig gestellte Fragen

Ist die Lektion „Daten sicher gemeinsam nutzen“ kostenlos?

Ja — der vollständige Text von „Daten sicher gemeinsam nutzen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Python Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Python Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Daten sicher gemeinsam nutzen“?

Queues und Locks verwenden Du übst Python Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Python Academy zu starten?

Keine Vorkenntnisse erforderlich. Python Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Daten sicher gemeinsam nutzen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Python Academy-Lektion Code schreiben und ausführen?

Ja. Jede Python Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Threads und der GIL
  2. ThreadPoolExecutor
  3. Grundlagen von multiprocessing
  4. Daten sicher gemeinsam nutzen
← Zurück zu Python Academy