Pergunta

Ao escrever aplicativos multithread, um dos problemas mais comuns enfrentados são os impasses.

Minhas perguntas para a comunidade são:

  1. O que é um impasse?

  2. Como você os detecta?

  3. Você lida com eles?

  4. E, finalmente, como você evita que eles ocorram?

Foi útil?

Solução

A trancar ocorre quando vários processos tentam acessar o mesmo recurso ao mesmo tempo.

Um processo perde e deve esperar o outro terminar.

A impasse ocorre quando o processo de espera ainda está retendo outro recurso que o primeiro precisa antes de poder terminar.

Então, um exemplo:

O recurso A e o recurso B são usados ​​pelo processo X e pelo processo Y

  • X começa a usar A.
  • X e Y tentam começar a usar B
  • Y 'ganha' e obtém B primeiro
  • agora Y precisa usar A
  • A está bloqueado por X, que está esperando por Y

A melhor maneira de evitar impasses é evitar que os processos se cruzem dessa maneira.Reduza a necessidade de bloquear qualquer coisa tanto quanto possível.

Nos bancos de dados, evite fazer muitas alterações em tabelas diferentes em uma única transação, evite gatilhos e mude para leituras otimistas/sujas/nolock tanto quanto possível.

Outras dicas

Deixe-me explicar um exemplo do mundo real (não realmente real) para uma situação de impasse nos filmes policiais.Imagine que um criminoso mantém um refém e, contra isso, um policial também mantém como refém um amigo do criminoso.Nesse caso, o criminoso não vai deixar o refém ir se o policial não deixar o amigo ir.Além disso, o policial não vai deixar o amigo do criminoso ir embora, a menos que o criminoso liberte o refém.Esta é uma situação infinitamente indigna de confiança, porque ambos os lados estão insistindo um no outro para dar o primeiro passo.

Cena criminal e policial

enter image description here

Simplesmente, quando dois threads precisam de dois recursos diferentes e cada um deles possui o bloqueio do recurso que o outro precisa, é um impasse.

Outra explicação de alto nível do impasse:Corações partidos

Você está namorando uma garota e um dia depois de uma discussão, ambos os lados estão com o coração partido e esperando por uma Sinto muito e senti sua falta chamar.Nesta situação, ambos os lados querem comunicar-se se e somente se um deles receber uma mensagem. Sinto muito ligue do outro.Como nenhum de cada um iniciará a comunicação e aguardará em estado passivo, ambos aguardarão que o outro inicie a comunicação, o que terminará em situação de impasse.

Os impasses só ocorrerão quando você tiver dois ou mais bloqueios que podem ser adquiridos ao mesmo tempo e eles forem capturados em ordem diferente.

As maneiras de evitar impasses são:

  • evite ter bloqueios (se possível),
  • evite ter mais de um cadeado
  • sempre pegue as fechaduras na mesma ordem.

Para definir o impasse, primeiro eu definiria o processo.

Processo : Como sabemos, o processo nada mais é do que um program em execução.

Recurso : Para executar um processo de programa são necessários alguns recursos.As categorias de recursos podem incluir memória, impressoras, CPUs, arquivos abertos, unidades de fita, CD-ROMS, etc.

Impasse : Deadlock é uma situação ou condição quando dois ou mais processos estão retendo alguns recursos e tentando adquirir mais recursos, e não conseguem liberar os recursos até que terminem sua execução.

Condição ou situação de impasse

enter image description here

No diagrama acima, existem dois processos P1 e p2 e há dois recursos R1 e R2.

Recurso R1 é alocado para processar P1 e recurso R2 é alocado para processar p2.Para concluir a execução do processo P1 precisa de recurso R2, então P1 Pedido para R2, mas R2 já está alocado para P2.

Da mesma forma Processo P2 para completar suas necessidades de execução R1, mas R1 já está alocado para P1.

ambos os processos não podem liberar seus recursos até e a menos que concluam sua execução.Então ambos estão esperando por outros recursos e vão esperar para sempre.Então este é um IMPASSE Doença.

Para que ocorra o deadlock, quatro condições devem ser verdadeiras.

  1. Exclusão mútua - Cada recurso está atualmente alocado para exatamente um processo ou está disponível.(Dois processos não podem controlar simultaneamente o mesmo recurso ou estar em sua seção crítica).
  2. Segure e espere - os processos que atualmente detêm recursos podem solicitar novos recursos.
  3. Sem preempção - Uma vez que um processo detém um recurso, ele não pode ser retirado por outro processo ou pelo kernel.
  4. Espera circular - Cada processo está aguardando para obter um recurso que está em poder de outro processo.

e todas essas condições são satisfeitas no diagrama acima.

Um deadlock acontece quando um thread está esperando por algo que nunca ocorre.

Normalmente, isso acontece quando um thread está aguardando um mutex ou semáforo que nunca foi liberado pelo proprietário anterior.

Também acontece frequentemente quando você tem uma situação envolvendo dois threads e dois bloqueios como este:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

Você geralmente os detecta porque as coisas que você espera que aconteçam nunca acontecem ou o aplicativo trava completamente.

Você pode dar uma olhada nisso artigos maravilhosos, na seção Impasse.Está em C# mas a ideia ainda é a mesma para outras plataformas.Cito aqui para facilitar a leitura

Um impasse acontece quando dois fios esperam um recurso mantido pelo outro, para que nenhum deles possa prosseguir.A maneira mais fácil de ilustrar isso é com dois bloqueios:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}

Deadlock é um problema comum em problemas de multiprocessamento/multiprogramação no sistema operacional.Digamos que existam dois processos P1, P2 e dois recursos globalmente compartilháveis ​​R1, R2 e na seção crítica ambos os recursos precisam ser acessados

Inicialmente, o SO atribui R1 ao processo P1 e R2 ao processo P2.Como ambos os processos estão sendo executados simultaneamente, eles podem começar a executar seu código, mas o PROBLEMA surge quando um processo atinge a seção crítica.Então o processo R1 irá aguardar o processo P2 liberar R2 e vice-versa...Então eles vão esperar para sempre (CONDIÇÃO DE ADLOCK).

Uma pequena ANALOGIA...

Sua mãe (OS),
Você (P1),
Seu irmão (P2),
maçã (R1),
Faca (R2),
seção crítica (cortar maçã com faca).

Sua mãe lhe dá a maçã e a faca para seu irmão no começo.
Ambos estão felizes e brincando (Executando seus códigos).
Qualquer um de vocês quer cortar a maçã (seção crítica) em algum momento.
Você não quer dar a maçã ao seu irmão.
Seu irmão não quer te dar a faca.
Então vocês dois vão esperar muito, muito tempo :)

Um impasse ocorre quando há uma cadeia circular de threads ou processos em que cada um contém um recurso bloqueado e tenta bloquear um recurso mantido pelo próximo elemento da cadeia.Por exemplo, dois threads que contêm respectivamente o bloqueio A e o bloqueio B, e ambos estão tentando adquirir o outro bloqueio.

O deadlock ocorre quando dois threads adquirem bloqueios que impedem o progresso de qualquer um deles.A melhor maneira de evitá-los é com um desenvolvimento cuidadoso.Muitos sistemas embarcados protegem contra eles usando um temporizador de vigilância (um temporizador que reinicia o sistema sempre que ele trava por um determinado período de tempo).

Um deadlock é um estado de um sistema no qual nenhum processo/thread é capaz de executar uma ação.Conforme mencionado por outros, um deadlock é normalmente o resultado de uma situação em que cada processo/thread deseja adquirir um bloqueio para um recurso que já está bloqueado por outro (ou mesmo o mesmo) processo/thread.

Existem vários métodos para encontrá-los e evitá-los.Alguém está pensando muito e/ou tentando muitas coisas.No entanto, lidar com o paralelismo é notoriamente difícil e a maioria (se não todas) das pessoas não conseguirá evitar completamente os problemas.

Alguns métodos mais formais podem ser úteis se você quiser realmente lidar com esse tipo de questão.O método mais prático que conheço é usar a abordagem teórica do processo.Aqui você modela seu sistema em alguma linguagem de processo (por exemplo,CCS, CSP, ACP, mCRL2, LOTOS) e usar as ferramentas disponíveis para (modelar) verificar se há conflitos (e talvez algumas outras propriedades também).Exemplos de conjunto de ferramentas a serem usados ​​são FDR, mCRL2, CADP e Uppaal.Algumas almas corajosas podem até provar que seus sistemas estão livres de impasses usando métodos puramente simbólicos (prova de teoremas;procure Owicki-Gries).

No entanto, estes métodos formais normalmente requerem algum esforço (por ex.aprendendo os fundamentos da teoria do processo).Mas acho que isso é simplesmente uma consequência do facto de estes problemas serem difíceis.

Deadlock é uma situação que ocorre quando há menos recursos disponíveis conforme solicitado pelos diferentes processos.Isso significa que quando a quantidade de recursos disponíveis torna-se menor do que a solicitada pelo usuário então nesse momento o processo entra em estado de espera. Algumas vezes a espera aumenta mais e não há chance de verificar o problema de falta de recursos então esta situação é conhecida como impasse.Na verdade, o impasse é um grande problema para nós e ocorre apenas em sistemas operacionais multitarefa. O impasse não pode ocorrer em sistemas operacionais de tarefa única porque todos os recursos estão presentes apenas para a tarefa que está em execução no momento......

Acima, algumas explicações são boas.Espero que isso também possa ser útil:https://ora-data.blogspot.in/2017/04/deadlock-in-oracle.html

Em um banco de dados, quando uma sessão (por exemplo.ora) deseja um recurso mantido por outra sessão (por exemplo,data), mas essa sessão (data) também deseja um recurso que é mantido pela primeira sessão (ora).Pode haver mais de 2 sessões envolvidas também, mas a ideia será a mesma.Na verdade, os Deadlocks impedem que algumas transações continuem funcionando.Por exemplo:Suponhamos que ORA-DATA mantenha o bloqueio A e solicite o bloqueio B E o SKU mantém o bloqueio B e solicita o bloqueio A.

Obrigado,

O deadlock ocorre quando um thread está aguardando a conclusão de outro thread e vice-versa.

Como evitar?
- Evite bloqueios aninhados
- Evite bloqueios desnecessários
- Use junção de thread()

Como você detecta isso?
execute este comando no cmd:

jcmd $PID Thread.print

referência :geeksforgeeks

Um programa clássico e muito simples de entender Impasse situação:-

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

Quando o thread principal invoca Lazy.main, ele verifica se a classe Lazy foi inicializado e começa a inicializar a classe.O thread principal agora define inicializado como false , cria e inicia um plano de fundo thread cujo método run define inicializado como true e aguarda a conclusão do thread em segundo plano.

Desta vez, a classe está sendo inicializada por outro thread.Nessas circunstâncias, o thread atual, que é o thread em segundo plano, aguarda no objeto Class até que a inicialização seja concluída.Infelizmente, o fio que está fazendo a inicialização, o thread principal, está aguardando o plano de fundo thread para concluir.Como os dois threads agora estão esperando um pelo outro, o programa é IMPOSSÍVEL.

O problema do impasse

  • Os primeiros sistemas operacionais de computador executavam apenas um programa de cada vez
  • Todos os recursos do sistema estavam disponíveis para este programa
  • Mais tarde, os sistemas operacionais executaram vários programas ao mesmo tempo, intercalando-os
  • Os programas eram obrigados a especificar com antecedência o que recursos de que necessitavam para evitar conflitos com outros programas em execução ao mesmo tempo
  • Eventualmente, alguns sistemas operacionais ofereceram alocação dinâmica de recursos
  • Os programas poderiam solicitar novas alocações de recursos depois de terem começado a correr
  • Isso levou ao problema do impasse

Um conjunto de processos bloqueados, cada um contendo um recurso e aguardando para adquirir um recurso mantido por outro processo em o conjunto

Situação em que 02 ou mais ações concorrentes são cada um esperando o outro terminar, e assim nem nunca faz

Caracterização de impasse

  • Exclusão mútua
  • Espere e espere
  • Sem preempção
  • Espera Circular

Métodos para lidar com impasses

  • Certifique-se de que o sistema nunca entrará em estado de deadlock
  • Permitir que o sistema entre em um estado de deadlock e, em seguida, recuperar
  • Ignore o problema e finja que os impasses nunca ocorrem no sistema;usado pela maioria dos sistemas operacionais, incluindo UNIX

Prevenção de impasse

  • Exclusão mútua – não é necessário para recursos compartilháveis;deve valer para recursos não compartilháveis

  • Segure e espere – deve garantir que sempre que um processo solicita um recurso, ele não contém nenhum outro recurso

  • Sem preempção – Se um processo que está segurando algum recursos solicita outro recurso que não pode ser imediatamente alocados a ele, então todos os recursos atualmente sendo Detidos são liberados

  • Espera Circular – Impor uma ordenação total de todos os recursos e exigem que cada processo solicite recursos em um aumentando a ordem de enumeração

Em essência, o mutex é um bloqueio que fornece acesso protegido a recursos compartilhados.No Linux, o tipo de dados mutex do thread é pthread_mutex_t.Antes de usar, inicialize-o.

Para acessar recursos compartilhados, você deve bloquear o mutex.Se o mutex já estiver bloqueado, a chamada bloqueará o thread até que o mutex seja desbloqueado.Após a conclusão da visita aos recursos compartilhados, você deverá desbloqueá-los.

No geral, existem alguns princípios básicos não escritos:

  • Obtenha o bloqueio antes de usar os recursos compartilhados.

  • Segurando a fechadura o menor tempo possível.

  • Libere o bloqueio se o thread retornar um erro.

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