Programação multitarefa em Python - compartilhamento de variáveis entre threads

Tags relacionadas:1. Potencialize sua web com Python
2. Shodan e API Python

Problema: erro ao compartilhar dados de variáveis globais entre threads



import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _


Resultado da operação:




Teoricamente, são executados 1 milhão de loops, e a cada execução do loop é adicionado 1 à variável global, portanto o resultado final deveria ser 2.000.000. O resultado real é mostrado acima.

Motivo:



Duas threads operam sobre variáveis globais ao mesmo tempo. Quando a thread 1 lê a variável global, a thread 2 também lê a variável global. Ao realizar uma operação sobre a variável, é lida a variável original, não a variável após a operação. Como a thread 1 não confirmou a alteração após a operação, a thread 2 também leu o valor anterior da variável.
Solução

Usar sincronização de processos para garantir que apenas uma thread opere sobre os dados por vez.

1. Usar o método join()

import threading

g_num = 0


def task1 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )

def task2 ():
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
first.join ( ) _
second.start ( ) _
Resultados:



Princípio: o método first.join() faz com que o programa aguarde a conclusão da primeira thread; a segunda thread só começa a executar após a primeira ser concluída, garantindo que apenas uma thread opere sobre a variável por vez.
Sincronização de threads: após a execução de uma tarefa, outra tarefa pode ser executada, sendo que apenas uma tarefa é executada por vez.

2. Mutex

import threading

g_num = 0

# Criar um mutex é essencialmente uma função via
LOCK = threading.Lock ( ) _
def task1 ():
# bloquear
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK1:' , g_num )
# liberar bloqueio
LOCK.release ( ) _


def task2 ():
LOCK.acquire ( ) _
for i in range ( 1000000 ):
global g_num
g_num += 1
print ( 'TASK2:' , g_num )
LOCK.release ( ) _


if __name__ == "__main__" :
first = threading.Thread ( target = task1 ) _ _
second = threading.Thread ( target = task2 ) _ _
first.start ( ) _
second.start ( ) _

Resultados:





Princípio: com o bloqueio de dados compartilhados, apenas uma thread opera por vez; múltiplas threads competem pelo acesso, e a função de bloqueio do threading é usada para determinar qual thread obtém o acesso primeiro. Ao executar a primeira thread, primeiro bloqueia-se a thread atual com lock.acquire(); durante esse período, outras threads não podem executar. Quando o loop termina, usa-se lock.release() para liberar a thread atual, permitindo que outras threads operem. Isso garante que apenas uma thread esteja em execução por vez.
No entanto, os locks mutex afetam a eficiência do código em certa medida, transformando a multitarefa em execução de tarefa única, e também podem causar problemas de deadlock (causados pela falta de liberação oportuna dos locks).

Aviso de direitos autorais: o conteúdo deste artigo é contribuído por usuários registrados com nome real da Alibaba Cloud. Os direitos autorais pertencem ao autor original. A Comunidade de Desenvolvedores Alibaba Cloud não detém os direitos autorais e não assume responsabilidade legal correspondente. Para regras específicas, consulte o "Acordo de Serviço ao Usuário da Comunidade de Desenvolvedores Alibaba Cloud" e as "Diretrizes de Proteção à Propriedade Intelectual da Comunidade de Desenvolvedores Alibaba Cloud". Se você encontrar qualquer conteúdo suspeito de plágio nesta comunidade, preencha o formulário de reclamação de infração para denunciá-lo. Uma vez verificado, esta comunidade excluirá imediatamente o conteúdo supostamente infrator.

Artigos relacionados

Explorar mais ofertas especiais

  1. Short Message Service (SMS) e Serviço de e-mail

    Pacote de 50.000 e-mails a partir de US$ 1,99, 120 mensagens curtas a partir de apenas US$ 1,00

phone Fale Conosco
Oi, eu sou o assistente de IA da Alibaba Cloud!
Posso ajudar com perguntas e soluções.