Por que não podemos matar o processo de estado D ininterrupto?

6

Frequentemente tenho problemas com processos presos no estado D, devido a compartilhamentos NFS por trás de firewalls. Se eu perder conexões, os processos ficam presos no estado D e não posso matá-los. A única solução torna-se difícil reiniciar. Eu queria saber se existem outras maneiras, mas todas as soluções e informações que posso encontrar é "você simplesmente não pode matá-lo". Todo mundo parece estar bem e aceitar o jeito que é. Eu sou um pouco crítico sobre isso. Eu pensei que deve haver uma maneira de raspar o processo da memória para que não haja necessidade de reinicialização. É muito chato se isso acontece com freqüência. E se o recurso retornar o IO, ele pode simplesmente ser ignorado nesse caso. Por que isso não é possível? Kernel Linux é IMHO muito avançado e você deve ser capaz de fazer coisas como esta. Especialmente em servidores ...

Não consegui encontrar uma resposta satisfatória, por que não é / não pode ser implementada?

Eu também estaria interessado em respostas sobre programação e natureza algorítmica, o que explicaria essa questão.

    
por Genom 10.05.2017 / 10:35

1 resposta

6

Matar um processo enquanto ele está em uma chamada de sistema é possível, e isso funciona principalmente. O difícil é fazê-lo funcionar o tempo todo. Passar de 99,99% para 100% é a parte difícil.

Normalmente, quando um processo é eliminado, todos os recursos que ele usa são liberados. Se houver alguma E / S acontecendo com o processo, o código que faz esta E / S será notificado e sairá, permitindo que os recursos que ele está usando sejam liberados.

O sono ininterrupto acontece visivelmente quando "o código é notificado e sai" leva um tempo não desprezível. Isso significa que o código não está funcionando como deveria. É um bug. Sim, é teoricamente possível escrever código sem erros, mas é praticamente impossível.

Você diz "se o recurso retornar o IO, ele pode simplesmente ser ignorado". Bem, tudo bem. Mas suponha, por exemplo, que um periférico tenha sido programado para gravar na memória pertencente ao processo. Para matar o processo sem cancelar o pedido para o periférico, a memória deve ser mantida em uso de alguma forma. Você não pode simplesmente se livrar desse recurso. Existem recursos que devem ficar por perto. E a liberação dos outros recursos só pode ser feita se o kernel souber quais recursos são seguros para liberar, o que requer que o código seja escrito de forma que seja sempre possível dizer. Os casos em que o sono ininterrupto dura por um período de tempo visível são casos em que é impossível dizer, e a única coisa segura é o caminho.

É possível projetar um sistema operacional no qual é garantido que a execução de um processo funcione (sob certas suposições sobre o funcionamento correto do hardware). Por exemplo, sistemas operacionais em tempo real garantem que matar um processo leva no máximo uma certa quantidade fixa de tempo (supondo que ele ofereça uma facilidade de matar). Mas é difícil, especialmente se o sistema operacional também deve suportar uma ampla gama de periféricos e oferecer um bom desempenho de casos comuns. O Linux favorece o comportamento de casos comuns sobre o pior comportamento de muitas maneiras.

Obter todos os caminhos de código abordados é extremamente difícil, especialmente quando não havia uma estrutura rigorosa para fazê-lo a partir do primeiro dia. No grande esquema das coisas, processos inutilizáveis são extremamente raros (você não percebe quando não acontece). É um sintoma de drivers de buggy. Uma quantidade finita de esforço foi colocada na escrita de drivers Linux. Eliminar mais casos de sono ininterrupto prolongado exigiria mais pessoas na tarefa ou levaria a menos hardware suportado e pior desempenho.

    
por 11.05.2017 / 00:56