Python Academy · Les

Gegevens veilig delen

Gebruik queues en locks

Les 4 van 413 stappen

Gegevens veilig delen is een gratis Python Academy-les op CoddyKit. Dit is les 4 van 4. Je kunt de volledige les hieronder gratis lezen en daarna in de browser praktisch oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject Python Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus Python Academy bevat in totaal 4 lessen.

Het probleem van racecondities

Wanneer meerdere threads dezelfde gegevens wijzigen, kunnen hun bewerkingen elkaar afwisselen en het resultaat beschadigen. Dit is een raceconditie. We hebben synchronisatiehulpmiddelen nodig om gegevens veilig te delen.

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)

Een Lock als oplossing

Een threading.Lock zorgt ervoor dat slechts één thread tegelijk een kritieke sectie binnengaat. Verkrijg de vergrendeling met een with-blok rond de gedeelde wijziging.

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 en release

Je kunt een vergrendeling handmatig gebruiken met acquire() en release(), maar de vorm met with is veiliger omdat de vergrendeling ook bij een fout wordt vrijgegeven.

import threading

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

Threadveilige wachtrijen

De klasse queue.Queue is al threadveilig. Threads kunnen put en get gebruiken zonder expliciete vergrendelingen, waardoor dit de voorkeursmanier is om gegevens door te geven.

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())

Producent en consument

Het klassieke patroon: producenten plaatsen werk met put in een wachtrij en consumenten halen het met get op en verwerken het. De wachtrij regelt alle vergrendeling.

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 en task_done

q.join() blokkeert totdat elk item dat met put is geplaatst een overeenkomstige aanroep van task_done() heeft gekregen. Zo kan de hoofdthread wachten totdat al het werk is voltooid.

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 voor herintreding

Een gewone Lock loopt vast als dezelfde thread de vergrendeling twee keer probeert te verkrijgen. Een threading.RLock (herintredende vergrendeling) staat dit wel toe en telt de verkrijgingen.

import threading

rlock = threading.RLock()

def outer():
    with rlock:
        inner()

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

outer()

Event voor signalering

Met een threading.Event kan één thread signalen naar andere threads sturen. Threads roepen wait() aan totdat een andere thread set() aanroept.

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()

Delen tussen processen

Gebruik tussen processen in plaats daarvan multiprocessing.Queue. Deze serialiseert objecten tussen afzonderlijke geheugenruimten.

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 voorkomen

Een deadlock ontstaat wanneer threads voor altijd op elkaars vergrendelingen wachten. Voorkom dit door meerdere vergrendelingen overal altijd in de zelfde volgorde te verkrijgen.

import threading

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

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

safe()

Geef de voorkeur aan wachtrijen boven vergrendelingen

Geef waar mogelijk de voorkeur aan het doorgeven van berichten met wachtrijen boven een gedeelde veranderlijke toestand die door vergrendelingen wordt beschermd. Dit is gemakkelijker te begrijpen en leidt veel minder vaak tot fouten.

import queue

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

Korte controle

Toets je begrip van het veilig delen van gegevens.

Samenvatting

Je hebt geleerd gegevens veilig te delen:

  • Racecondities beschadigen onbeveiligde gedeelde toestand.
  • Lock en RLock beschermen kritieke secties.
  • queue.Queue is threadveilig; gebruik multiprocessing.Queue tussen processen.
  • Event stuurt signalen tussen threads; een consistente volgorde van vergrendelingen voorkomt deadlocks.

Volgende cursus: externe programma's uitvoeren met subprocess.

Gratis beginnen

Leer Python met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
76
Lessen
320

Veelgestelde vragen

Is de les “Gegevens veilig delen” gratis?

Ja — de volledige tekst van “Gegevens veilig delen” kun je hier gratis op het web lezen. Als je interactief wilt oefenen met een ingebouwde code-editor en een AI-begeleider die 24/7 beschikbaar is, en de rest van de cursus Python Academy wilt ontgrendelen, kun je upgraden naar CoddyKit PRO. De cursus Python Academy bevat in totaal 4 lessen.

Wat leer ik in “Gegevens veilig delen”?

Gebruik queues en locks Je oefent met Python Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met Python Academy te beginnen?

Ervaring vooraf is niet nodig. Python Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 4 van 4.

Hoe lang duurt de les “Gegevens veilig delen”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over Python Academy?

Ja. Elke les over Python Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Threads en de GIL
  2. ThreadPoolExecutor
  3. Basisprincipes van multiprocessing
  4. Gegevens veilig delen
← Terug naar Python Academy