Amostra de deadlock no .net?
-
23-09-2019 - |
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.
- Monitor de deadlock Por Stephen Toub.
- 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.