Artigo: 317723 - Última revisão: quarta-feira, 6 de Dezembro de 2006 - Revisão: 2.3

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

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Visual Basic .NET ou Visual Basic 2005 permite a utilização threads de aplicações do Visual Basic pela primeira vez. Threads introduzir depuração questões como as condições de conflito entre tarefas concorrentes e bloqueios. Este artigo explora estes dois problemas.

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 segundo thread lê o mesmo valor da variável de. Em seguida, o thread primeiro e segundo thread executam as respectivas operações no valor e Pilote para ver qual thread pode escrever o valor pela última vez 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 é atribuído um período de tempo para executar num processador predefinido. Quando o tempo atribuído para o thread expirar, o contexto do thread é guardado até a próxima jogada no processador e o processador começa a execução do thread seguinte.

Como é que um comando de uma linha pode causar uma condição de corrida? Examine o exemplo seguinte 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 do Visual Basic:
   'Thread 1
   Total = Total + val1
				
   'Thread 2
   Total = Total - val2
				
o código de assemblagem (com números de linha) de compilação do código Visual Basic anterior:
 '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 
				
por observar o código de assemblagem, pode ver quantas operações o processador está a executar o nível inferior para executar um cálculo adição simples. Um thread poderá não conseguir executar todo 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 deste código.

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

Pode ver como isto pode ser um problema principal. Se este fosse um programa de banco, o cliente teria dinheiro na sua conta não deve estar presente.

Este erro é aleatório, porque é possível que o thread 1 concluir a respectiva execução antes a hora no expira o processador e, em seguida, thread 2 podem começar a respectiva execução. Se estes eventos ocorrem, o problema não ocorre. A execução dos threads é nondeterministic, portanto não pode controlar a hora ou ordem de execução. Tenha também em atenção que os threads poderão executar diferentes em tempo de execução em modo de depuração. Além disso, pode ver que se executar cada thread numa série, o erro não ocorre. Este aleatoriedade torna estes erros muito mais difícil de localizar e de depuração.

Para evitar as condições de conflito entre tarefas concorrentes, pode bloquear partilhadas variáveis, para que apenas um thread de cada vez tenha acesso à variável partilhada. Efectue este procedimento com moderação, porque se uma variável está bloqueada no thread 1 e 2 thread tem também a variável, a execução de thread 2 pára enquanto 2 threads aguarda 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 partilhadas por vários threads. Isto resulta da unpredictability da ordem pela qual os threads executar. Algures no wins de um módulo e algures outros wins de thread. Noutras alturas, execução funciona correctamente. Além disso, se cada thread é executado em separado, 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 o thread já bloqueou. Como resultado, cada thread pára a execução e aguarda o outro módulo libertar a variável. Uma vez que cada thread está a manter a variável que pretende que o thread, não acontece nada e os threads permanecem deadlocked.

Detalhes e exemplo

O código seguinte 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 é permitido para bloquear LeftVal. O processador pára a execução do thread 1 e começa a execução do thread 2. Thread 2 bloqueios RightVal e, em seguida, tenta bloquear LeftVal. Porque está bloqueado LeftVal, thread 2 pára e aguarda LeftVal que serão lançados. Porque o thread 2 for parado, thread 1 é permitida para continuar a executar. Thread 1 tenta bloquear RightVal mas não é possível, porque o thread 2 bloqueou. Como resultado, thread 1 começa a aguardar RightVal fica disponível. Cada thread aguarda por outro thread, porque cada thread bloqueou a variável que o thread está à espera de e nenhum thread é desbloquear a variável que está a manter.

Um impasse sempre não ocorre. Se 1 thread executa ambos os bloqueios antes do processador pára que, thread 1 pode executar as respectivas operações e, em seguida, desbloquear a variável partilhada. Depois de thread 1 desbloqueia a variável, thread 2 pode continuar com a respectiva execução, como previsto.

Este erro parece óbvio 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 controlar porque, este mesmo código, podem ocorrer o execução correcta e incorrecta de execução.

Sintomas

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

O que é um módulo?

Processos são utilizados para separar as aplicações diferentes que estão a executar a uma hora específica num único computador. O sistema operativo não executa processos, mas executar threads. Um thread é uma unidade de execução. O sistema operativo atribui tempo do 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 as suas próprias processadores de excepções, agendar 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 tempo que foi atribuído para o processador. 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 respectiva execução. Estas informações incluem conjunto o thread de registos de processador e a pilha de chamadas dentro o espaço de endereços do processo anfitrião.

Referências

Para mais informações, consulte a ajuda do Visual Studio para as seguintes palavras-chave:
  • SyncLock . Permite que um objecto a ser bloqueado. Se outro thread tenta bloquear esse mesmo objecto, é bloqueado até que o thread primeiro liberta. Utilize SyncLock cuidadosamente, porque poderão ocorrer problemas de utilização ilícita de SyncLock. Por exemplo, este comando pode impedir que as condições de conflito entre tarefas concorrentes mas provocar bloqueios.
  • interLocked . Permite um conjunto seleccionado de operações de segurança do thread variáveis numéricas básicas.
Para obter informações adicionais, clique no número de artigo existente abaixo para visualizar o artigo na base de dados de conhecimento da Microsoft:
316422  (http://support.microsoft.com/kb/316422/EN-US/ ) INFO: O plano de threading no Visual Basic .NET
Para mais informações, consulte o seguinte Web site da MSDN:
Threads and Threading (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconthreadsthreading.asp)

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: 
kbmt kbvs2005swept kbvs2005applies kbinfo KB317723 KbMtpt
Tradução automáticaTraduçã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  (http://support.microsoft.com/kb/317723/en-us/ )