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

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
Sumário
Visual Basic de .NET ou Visual Basic 2005 oferece a possibilidade de utilizar threads de 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 segundo segmento 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 a hora em que é atribuída 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 conflito entre tarefas concorrentes? 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 do 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 				
Observando o código de assemblagem, pode ver quantas operações o processador está a efectuar no nível inferior para executar um cálculo de adição simples. Um thread poderá 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 é de 100, val1 é de 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 grave. 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 de processador expira 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 é determinantes, por conseguinte, não é possível 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 executar o thread de cada 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. Efectue este procedimento com moderação, porque se uma variável está bloqueada no Thread 1 e 2 do Thread 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 1SyncLock LeftVal SyncLock RightVal  'Perform operations on LeftVal and RightVal that require read and write. End SyncLockEnd SyncLock				
'Thread 2SyncLock RightVal SyncLock LeftVal  'Perform operations on RightVal and LeftVal that require read and write. End SyncLockEnd 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. Uma vez que o Thread 2 for parado, 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 Aguarde até que RightVal fica disponível. Cada thread de espera do 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 bloqueio não ocorrem sempre. Se for executado ambos os bloqueios do Thread 1 antes do processador pára que, do 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, podem ocorrer a execução correcta e incorrecta execução.

Sintomas

Um sintoma comum de impasse é que o programa ou um grupo de threads deixa de responder. É 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 foi atribuído 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 respectiva 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, é 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:

Aviso: Este artigo foi traduzido automaticamente

Propriedades

ID do Artigo: 317723 - Última Revisão: 10/29/2015 00:10:00 - Revisão: 4.0

Microsoft Visual Basic 2005, Microsoft Visual Basic .NET 2003 Standard Edition, Microsoft Visual Basic .NET 2002 Standard Edition

  • kbvs2005swept kbvs2005applies kbinfo kbmt KB317723 KbMtpt
Comentários