Descrição das condições de conflito entre tarefas concorrentes e bloqueios

Traduções de Artigos Traduções de Artigos
Artigo: 317723 - Ver produtos para os quais este artigo se aplica.
Expandir tudo | Reduzir tudo

Nesta página

Sumário

Visual Basic .NET ou Visual Basic 2005 oferece a possibilidade de utilizar threads em aplicações do Visual Basic pela primeira vez. Threads introduzem depuração questões como as condições de conflito entre tarefas concorrentes e bloqueios. Este artigo explora os dois aspectos.

Mais Informação

Condições de conflito entre tarefas concorrentes

Uma condição de corrida ocorre quando dois threads acederem a uma variável partilhada ao mesmo tempo. O thread primeiro lê a variável e o thread de segundo lê o mesmo valor da variável. Em seguida, o thread de primeiro e segundo thread efectuam as operações no valor e competir para ver qual o thread pode escrever o valor última para a variável partilhada. O valor do thread que escreve o respectivo valor última é preservado, porque o thread está a escrever sobre o valor que escreveu o thread anterior.

Detalhes e exemplo

Cada thread foi alocado um período de tempo para executar num processador predefinido. Quando o tempo que é atribuído para o thread expira, o contexto do thread é guardado até que a sua próxima jogada no processador e o processador começa a execução do thread seguinte.

Como é que um comando de uma linha pode provocar uma condição de corrida? Examine o seguinte exemplo para ver como uma condição de corrida ocorre. Existem dois threads e ambos estiverem a actualizar uma variável partilhada denominada total (que é representado como dword ptr ds: [031B49DCh] no código de assemblagem).

Código de Visual Basic:
   'Thread 1
   Total = Total + val1
				
   'Thread 2
   Total = Total - val2
				
Código de assemblagem (com números de linha) da elaboração do anterior código do Visual Basic:
 'Thread 1
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   add         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        7611097F 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
 'Thread 2
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   sub         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        76110BE7 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
Pode ver quantas operações observando o código de assemblagem, o processador está a efectuar no nível inferior para executar um cálculo de adição simples. Um thread poderá conseguir executar a totalidade ou parte do respectivo código de assemblagem durante o período de tempo no processador. Agora observe como uma condição de corrida ocorre a partir deste código.

Total é 100, val1 é 50 e val2 é 15. O thread 1 obtém uma oportunidade para executar, mas apenas concluir os passos 1 a 3. Isto significa que o Thread 1 ler a variável e concluído a adição. O thread 1 apenas está a aguardar para escrever o novo valor de 150. Depois do Thread 1 for parado, o Thread 2 obtém completa execução. Isto significa que que tenha escrito o valor-calculado (85) para o Total de variável. Finalmente, o Thread 1 controlo da mesma e terminar a execução. Escreve, o respectivo valor (150). Por conseguinte, quando o Thread 1 estiver concluída, o valor do Total é agora 150 em vez de 85.

Pode ver como isto pode ser um problema significativo. Se este fosse um programa de operações bancárias, o cliente teria de dinheiro na sua conta que não deve estar presente.

Este erro é aleatório, porque é possível para o Thread 1 concluir a respectiva execução antes do tempo no expira o processador e, em seguida, Thread 2 pode começar a sua execução. Se estes eventos ocorrem, o problema não ocorre. A execução dos threads é não determinantes, por conseguinte, não pode controlar a hora ou a ordem de execução. Repare também que os threads podem ser executado uma forma diferente em tempo de execução versus o modo de depuração. Além disso, pode ver que se realiza a cada thread na série, o erro não ocorre. Este aleatoriedade torna estes erros muito mais difíceis de localizar e de depuração.

Para impedir que as condições de conflito entre tarefas concorrentes ocorra, pode bloquear variáveis partilhadas, para que apenas um thread de cada vez tenha acesso à variável partilhada. Efectuar esta operação com moderação, porque se uma variável está bloqueada no Thread 1 e Thread 2 também precisa da variável, a execução de Thread 2 pára enquanto aguarda Thread 2 para o Thread 1 libertar a variável. (Para mais informações, consulte "SyncLock" na secção "Referências" deste artigo.)

Sintomas

O sintoma mais comuns de uma condição de corrida é imprevisíveis valores de variáveis que são partilhados entre vários threads. Isto resulta da imprevisibilidade da ordem pela qual os threads executar se. Algures no wins de um thread e algures na parte de outro wins de thread. Noutras alturas, execução funciona correctamente. Além disso, se cada thread é executado separadamente, o valor da variável funciona correctamente.

Bloqueios fatais

Um impasse ocorre quando dois threads cada bloquear uma variável diferente ao mesmo tempo e, em seguida, tenta bloquear a variável que já bloqueado por outro thread. Como resultado, cada thread pára a execução e aguarda que outro thread libertar a variável. Uma vez que cada thread está a manter a variável que pretende que outro thread, não acontece nada e os threads permanecem impasse.

Detalhes e exemplo

O seguinte código tem dois objectos, LeftVal e RightVal:
'Thread 1
SyncLock LeftVal
 SyncLock RightVal
  'Perform operations on LeftVal and RightVal that require read and write.
 End SyncLock
End SyncLock
				
'Thread 2
SyncLock RightVal
 SyncLock LeftVal
  'Perform operations on RightVal and LeftVal that require read and write.
 End SyncLock
End SyncLock
				
Um impasse ocorre quando o Thread 1 é permitida para bloquear LeftVal. O processador pára a execução do Thread 1 e começa a execução de Thread 2. 2 Bloqueios RightVal e, em seguida, tenta bloquear LeftVal do thread. Porque está bloqueado LeftVal, o Thread 2 pára e aguarda LeftVal devem ser lançadas. Porque o Thread 2 for parado, o Thread 1 está autorizada a continuar a executar. O thread 1 tenta bloquear RightVal mas não consegue, porque o Thread 2 bloqueou. Como resultado, o Thread 1 começa a aguardar até RightVal ficar disponível. Cada thread aguarda por outro thread, porque cada thread bloqueou a variável que outro thread está à espera de e nenhum thread é desbloquear a variável que está a manter.

Um impasse não ocorrem sempre. Se for executado ambos os bloqueios do Thread 1 antes do processador pára-lo, Thread 1 pode efectuar as suas operações e, em seguida, desbloquear a variável partilhada. Depois do Thread 1 desbloqueia a variável, Thread 2 pode continuar com a sua execução, conforme esperado.

Este erro parece evidente quando estes fragmentos de código são colocados lado a lado, mas na prática, o código poderá aparecer nas áreas do código ou módulos separados. Este um erro muito grave para identificarem porque, deste mesmo código, tanto a execução correcta e a execução incorrecta podem ocorrer.

Sintomas

Um sintoma comum de impasse é que o programa ou um grupo de threads deixa de responder. Este é também conhecido como um deixar de responder. Pelo menos dois threads estão à espera que uma variável que outro thread bloqueado. Os threads não continue, uma vez que nenhum thread irá libertar a variável até chegar a outra variável. Todo o programa pode deixar de responder se o programa está à espera de uma ou ambas as threads para a execução completa.

O que é um Thread?

Processos são utilizados para separar as aplicações diferentes que estão a executar um determinado momento, num único computador. O sistema operativo não executar processos, mas não de threads. Um thread é uma unidade de execução. O sistema operativo atribui tempo de processador para um thread para a execução de tarefas do thread. Um único processo pode conter vários threads de execução. Cada thread mantém a suas própria processadores de excepções, prioridades e um conjunto de estruturas que o sistema operativo utiliza para guardar o contexto do thread, se o thread não é possível concluir a respectiva execução durante o período em que tiver sido atribuído para o processador de agendamento. O contexto é mantido até à próxima vez que o thread recebe tempo do processador. O contexto inclui todas as informações que o thread necessita para continuar sem interrupções a sua execução. Estas informações incluem o conjunto de thread de registos de processador e a pilha de chamadas dentro do espaço de endereços do processo anfitrião.

Referências

Para mais informações, procure a ajuda do Visual Studio para as seguintes palavras-chave:
  • SyncLock. Permite que um objecto a ser bloqueado. Se outro thread tentar bloquear o mesmo objecto, será bloqueado até que o thread primeiro lança. Utilize SyncLock cuidadosamente, porque poderão ocorrer problemas da utilização abusiva de SyncLock. Por exemplo, este comando pode impedir que as condições de conflito entre tarefas concorrentes mas provocar bloqueios fatais.
  • InterLocked. Permite que um conjunto de operações de seguro para thread em variáveis numéricas básicos.
Para obter informações adicionais, clique no número de artigo abaixo para visualizar o artigo na Microsoft Knowledge Base:
316422 INFO: Plano de threads no Visual Basic .NET
Para mais informações, consulte o seguinte Web site da MSDN:
Threads e Threading

Propriedades

Artigo: 317723 - Última revisão: 29 de outubro de 2013 - Revisão: 3.0
A informação contida neste artigo aplica-se a:
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
Palavras-chave: 
kbvs2005swept kbvs2005applies kbinfo kbmt KB317723 KbMtpt
Tradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 317723

Submeter comentários

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com