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.
LockeRLockprotegem seções críticas.queue.Queueé segura para linhas de execução; usemultiprocessing.Queueentre processos.Eventsinaliza 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
- Threads e o GIL
- ThreadPoolExecutor
- Noções básicas de multiprocessing
- Compartilhamento seguro de dados