Pergunta

Alguém pode fornecer um código de amostra simples de impasse em C#? E diga a maneira mais simples de encontrar o impasse no seu exemplo de código C#. (Pode ser a ferramenta que detectará o bloqueio morto no código de amostra fornecido.)

Nota: eu tenho vs 2008

Nenhuma solução correta

Outras dicas

Uma maneira comum é se você tiver bloqueios aninhados que não são adquiridos na mesma ordem. O tópico 1 poderia adquirir o bloqueio A e o Thread 2 poderia adquirir o bloqueio B e eles estavam deadlock.

var a = new object();
var b = new object();

lock(a) {
   lock(b) {

   }
}

// other thread
lock (b) { 
  lock(a) {

  }
}

EDIT: Exemplo não-localizado .. Usando WaitHandles. Suponha que Sócrates e Descartes estejam tendo bifes e os dois, sendo filósofos bem-educados, exigem um garfo e uma faca para comer. No entanto, eles têm apenas um conjunto de talheres, por isso é possível pegar um utensílio e depois esperar para sempre que o outro entregue seu utensílio.

Veja o Problema do filósofo para jantar

WaitHandle fork = new AutoResetEvent(), knife = new AutoResetEvent();

while(Socrates.IsHungry) {
   fork.WaitOne();
   knife.WaitOne();
   Eat();
   fork.Set();
   knife.Set();
} 

// other thread
while(Descartes.IsHungry) {
   knife.WaitOne();
   fork.WaitOne();
   Eat();
   knife.Set();
   fork.Set();
} 

Este é um código típico para criar um impasse no código C#. Confira este artigo do MSDN: http://msdn.microsoft.com/en-us/magazine/cc188793.aspx

using System;

using System.Threading;


public class Simple {

    static object A = new object();

    static object B = new object();


    static void MethodA()
    {
        Console.WriteLine("Inside methodA");
        lock (A)
        {
            Console.WriteLine("MethodA: Inside LockA and Trying to enter LockB");
            Thread.Sleep(5000);           
            lock (B)
            {
                Console.WriteLine("MethodA: inside LockA and inside LockB");
                Thread.Sleep(5000);
            }
            Console.WriteLine("MethodA: inside LockA and outside LockB");
        }
        Console.WriteLine("MethodA: outside LockA and outside LockB");
    }

    static void MethodB()
    {
        Console.WriteLine("Inside methodB");
        lock (B)
        {
            Console.WriteLine("methodB: Inside LockB");
            Thread.Sleep(5000);
            lock (A)
            {
                Console.WriteLine("methodB: inside LockB and inside LockA");
                Thread.Sleep(5000);
            }
            Console.WriteLine("methodB: inside LockB and outside LockA");
        }
        Console.WriteLine("methodB: outside LockB and outside LockA");
    }

    public static void Main(String[] args)
    {

        Thread Thread1 = new Thread(MethodA);
        Thread Thread2 = new Thread(MethodB);
        Thread1.Start();
        Thread2.Start();
        Console.WriteLine("enter.....");
        Console.ReadLine();

    }
}

Para o código de amostra de impasse, tente usar lock(this) Na sua classe para simular o cenário de impasse. Confira este exemplo.

Após dois artigos dignos de leitura detecta o impasse em tempo de execução e discute maneiras de evitá -los.

  1. Monitor de deadlock Por Stephen Toub.
  2. Timedlock novamente Por Ian Griffiths.

Há mais uma maneira de alcançar um impasse em C#. Como o número .NET 2.0 SP1 de threads no pool são limitados a 250 (de 25 na versão anterior) por núcleo.

Portanto, tecnicamente, você pode iniciar muitas tarefas no pool que aguardam a conclusão de outra operação assíncrona (que é executada através do pool de threads). Portanto, a tarefa no pool não será lançada e a tarefa assíncrona não será iniciada porque não há threads disponíveis.

Você pode encontrar exemplo e explicações mais precisas aqui:Programando o pool de threads. Deadlocks

Para responder à parte de sua pergunta sobre a detecção de impasse, duvido que isso seja possível. É semelhante em questão com o problema de interrupção, você não pode efetivamente calcular a semântica. Uma maneira de superar isso é usar um cão de guarda que pesquise periodicamente cada tópico se ainda estiver vivo e dar um certo tempo para responder, se dois tópicos não responderem, você pode assumir que eles estão ocupados ou estão mortos- trancado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top