0Pricing
Python Academy · Aula

Compartilhamento seguro de dados

Use filas e bloqueios

Compartilhamento seguro de dados é uma aula grátis de Python Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Python Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Python Academy inclui 4 aulas no total.

O problema da condição de corrida

Quando várias linhas de execução modificam os mesmos dados, suas operações podem se intercalar e corromper o resultado. Isso é uma condição de corrida. Precisamos de ferramentas de sincronização para compartilhar dados com segurança.

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 ao resgate

Um threading.Lock garante que apenas uma linha de execução entre em uma seção crítica por vez. Use acquire com um bloco with ao redor da atualização compartilhada.

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

Um bloqueio pode ser usado manualmente com acquire() e release(), mas a forma com with é mais segura, pois libera o bloqueio mesmo quando ocorre um erro.

import threading

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

Filas seguras para linhas de execução

A classe queue.Queue já é segura para uso simultâneo por linhas de execução. Elas podem put e get sem bloqueios explícitos, o que torna essa a forma preferida de transferir dados.

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 e Consumer

O padrão clássico: produtores colocam o trabalho em uma fila com put, e consumidores o obtêm com get e o processam. A fila cuida de todos os bloqueios.

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

q.join() bloqueia até que cada item que foi colocado com put tenha uma chamada correspondente a task_done(). Assim, a linha de execução principal pode aguardar a conclusão de todo o trabalho.

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 para reentrância

Um Lock comum entra em interbloqueio se a mesma linha de execução tentar adquiri-lo duas vezes. Um threading.RLock (bloqueio reentrante) permite isso e contabiliza as aquisições.

import threading

rlock = threading.RLock()

def outer():
    with rlock:
        inner()

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

outer()

Event para sinalização

Um threading.Event permite que uma linha de execução sinalize outras. As linhas de execução chamam wait() até que outra chame set().

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

Compartilhamento entre processos

Entre processos, use multiprocessing.Queue. Ela serializa objetos entre espaços de memória separados.

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

Evitando interbloqueios

Um interbloqueio ocorre quando as linhas de execução esperam indefinidamente pelos bloqueios umas das outras. Evite-o adquirindo vários bloqueios sempre na mesma ordem em todos os lugares.

import threading

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

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

safe()

Prefira filas a bloqueios

Quando possível, prefira a troca de mensagens com filas ao estado mutável compartilhado protegido por bloqueios. Essa abordagem é mais fácil de entender e muito menos propensa a erros.

import queue

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

Verificação rápida

Teste sua compreensão do compartilhamento seguro de dados.

Recapitulação

Você aprendeu a compartilhar dados com segurança:

  • Condições de corrida corrompem estados compartilhados sem proteção.
  • Lock e RLock protegem seções críticas.
  • queue.Queue é segura para linhas de execução; use multiprocessing.Queue entre processos.
  • Event sinaliza entre linhas de execução; uma ordem consistente dos bloqueios evita interbloqueios.

Próximo curso: executando programas externos com subprocess.

Perguntas Frequentes

A aula “Compartilhamento seguro de dados” é grátis?

Sim — o texto completo de “Compartilhamento seguro de dados” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Python Academy, atualize para CoddyKit PRO. O curso de Python Academy inclui 4 aulas no total.

O que vou aprender em “Compartilhamento seguro de dados”?

Use filas e bloqueios Você pratica Python Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Python Academy?

Nenhuma experiência prévia é necessária. Python Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.

Quanto tempo leva a aula “Compartilhamento seguro de dados”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Python Academy?

Sim. Cada aula de Python Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Threads e o GIL
  2. ThreadPoolExecutor
  3. Noções básicas de multiprocessing
  4. Compartilhamento seguro de dados
← Voltar para Python Academy