Programação de Sistemas Impasse e carência Programação de Sistemas Impasse/Carência : 1/27 Introdução Acesso de unidades de execução a recursos críticos exige sincronização. Quando uma unidade se encontra na região crítica a aceder ao recurso, todas as outras que pretendem entrar ficam bloqueados. Esta estratégia pode gerar dois problemas: Impasse ( deadlock ): unidades de execução nunca avançam porque cada uma possui recursos e ficam à espera dos recursos de outras unidades para poder prosseguir. Carência ( starvation ): unidade de execução é sempre preterida no acesso a recursos. Programação de Sistemas Impasse/Carência : 2/27
Impasse (1) [Def] Impasse ( deadlock ): estado do sistem em que todos os processos se encontram bloqueados: cada processo possui um recurso e encontra-se à espera para adquirir mais recursos possuídos por outros processos. [Def] Um sistema manifesta a propriedade de animação ( liveness ) se nunca entrar num impasse. O impasse pode ocorrer em sistemas computacionais concorrentes e na vida real. A animação é uma propriedade difícil de verificar, sendo usadas ferramentas avançadas de verificação de modelos. (ex: SPIN dos Bell Labs e SMV da Canegie-Mellon University). Programação de Sistemas Impasse/Carência : 3/27 Impasse (2) Exemplo computacional Seja um sistema com uma unidade de disco (acesso protegido pelo semáforo U) e uma unidade de banda magnética (acesso protegido pelo semáforo T). Os dois dispositivos são requisitados pos dois processos. Processo P wait(t); wait(u); /* região crítica */ signal(t); signal(u); Processo C wait(u); wait(t); /* região crítica */ signal(u); signal(t); O sistema entra em impasse com o seguinte traço: A:wait(T); B:wait(U); Programação de Sistemas Impasse/Carência : 4/27
Impasse (3) Exemplos na vida real 1. Ponte de via única Cada metade da ponte é vista como recurso. Impasse resolvido por recuo de um dos veículos. Resolução do impasse por prioridade pode gerar carência. Programação de Sistemas Impasse/Carência : 5/27 Impasse (4) 2. Cruzamentos Sistemas com impasse revelam esperas circulares. Etapas no estudo dos impasses: Modelação: representação abstracta do sistema, por forma a determinar as suas propriedades. Prevenção: modificar programas, por forma que nunca ocorram impasses. Detecção: verificar se um impasse vai ocorrer, ou se já ocorreu. Recuperação: acções a desencadear aquando da ocorrência de um impasse. Programação de Sistemas Impasse/Carência : 6/27
Condições para ocorrência de impasse Os impasses podem ocorrer se forem satisfeitas 4 condições: 1. Exclusão mútua: recursos usados de cada vez apenas por uma unidade de execução. 2. Guarda e espera: depois da unidade de execução tomar posse do recurso tem de adquirir a posse de outro recurso para poder concluir a região crítica. 3. Não preempção: o recurso na posse de uma unidade de execução apenas é liberto voluntariamente pela unidade depois de concluída a região crítica. 4. Espera circular: existe conjunto de unidades de execução {U 1,U 2,,U n } que: U 1 espera por recurso na posse de U 2 U 2 espera por recurso na posse de U 3 U n espera por recurso na posse de U 1 Programação de Sistemas Impasse/Carência : 7/27 Modelação de impasses (1) As condições para ocorrência de impasse podem ser representadas por grafos de recursos. Nós representados por círculos (Processos) e quadrados (Recursos) Arco do recurso para processo representa o processo estar na posse do recurso. Arco do processo para o recurso representa o processo encontra-se bloqueado à espera do recurso. Figura 3-3, Modern Operating Systems Programação de Sistemas Impasse/Carência : 8/27
Modelação de impasses (2) Cada recurso possui instâncias, representadas por pontos dentro do quadrado (exemplo: computador com várias impressoras). Dependência circular pode representar, ou não, um impasse: à esquerda, o ciclo com P 1 P 2 e P 3 bloqueados não pode ser quebrado. à direita, o ciclo com P 1 e P 3 bloqueados é quebrado quando os processos fora do ciclo (P 2 e P 4 ) libertam recursos. Programação de Sistemas Impasse/Carência : 9/27 Prevenção de impasse (1) Assegurar que, pelo menos uma das 4 condições não é satisfeita. 1. Exclusão mútua: frequentemente impossível evitar. 2. Guarda e espera: garantir que um processo não esteja a guardar recursos quando requisita outro recurso. Solução: Requisitar de uma só vez todos os recursos necessários, ou Requisitar incrementalmente, mas libertar imediatamente todos os recursos previamente guardados logo que detecta a impossibilidade de guardar mais um recurso. Problemas: Sub-utilização de recursos. Nos sistemas interactivos não é possível conhecer antecipadamente os recursos necessários. Possibilidade de carência. Programação de Sistemas Impasse/Carência : 10/27
Prevenção de impasse (2) 3. Não preempção: garantir que um processo não esteja a guardar recursos quando requisita outro recurso. Solução: Permitir a preempção de recursos: quando um processo vê negado um recuso, liberta-o ou O processo que guarda o recurso solicitado, liberta-o. Problemas: Aplicável apenas a recursos para os quais é possível a salvaguarda e restauro do estado (ex: CPU e memória). Programação de Sistemas Impasse/Carência : 11/27 Prevenção de impasse (3) 4. Espera circular: impor uma ordem fixa na guarda de recursos. Demonstração para 2 processos: sejam processos P e Q e a ordenação da guarda de recursos R 1 <R 2. O impasse ocorre se (i) P guarda R 1 e requere R 2 e (ii) Q guarda R 2 e requere R 1. Tal é impossível verificar, porque a ordem R 1 <R 2 impede a condição (ii) Problemas: Ineficiência na utilização dos recursos (requisição segue ordem préfixada, que pode não coincidir com as necessidades). Pode ser impossível identificar uma ordenação na guarda de recurso que funcione. Programação de Sistemas Impasse/Carência : 12/27
Detecção de impasse (1) A detecção de impasse pode ser efectuada em diversas alturas: Sempre que é solicitado um novo recurso, pelo algoritmo Se cada recurso possuir uma única instância, identificar ciclo no grafo de recursos. Se houver recursos com várias instâncias, usar o algoritmo do banqueiro. Periódica. Quando a utilização do CPU for baixa. Programação de Sistemas Impasse/Carência : 13/27 Detecção de impasse (2) Algoritmo do banqueiro: proposto por Dijkstra, implementado no sistema operativo THE. Estados inseguros Impasse Estados seguros [Def] Sequência <P 1, P 2,, P n > é segura se, para cada P i, os recursos que P i pode solicitar podem ser satisfeitos por todos os recursos disponíveis + recursos guardados por todos P j, j<i. Se o recurso que P i necessita não se encontrar imediatamente disponível, então P i espera até um P j ter libertado recursos. Quando P j libertar um recurso, se P i puder receber os recursos que necessita, então guardar o recurso executar, libertar os recursos, e terminar. Quando P i termina, P i+1 pode obter os recursos necessários. Programação de Sistemas Impasse/Carência : 14/27
Detecção de impasse (3) Parâmetros #define N número de processos #define M número de tipos de recursos int available[m]; se available[j]=k, então R j possui k instâncias disponíveis. j int max[m,n]; se max[i,j]=k, então o processo P i requere k instâncias do recurso R j para poder concluir o seu programa. Variáveis bool finish[n]; se finish[i]=true, então o processo P i conclui a sua tarefa. int alloc[m,n]; se alloc[i,j]=k, então o processo P i guarda correntemente k instâncias do recurso R j Programação de Sistemas Impasse/Carência : 15/27 Detecção de impasse (4) Algoritmo 1.for( i=0;i<n;i++ ) finish[i] = false; 2.while(1) { update = false; varrer_i_por_todos_processos { if( finish[i]==false && max-alloc[i]<available[i] ) { 3. available[i]+=alloc[i]; Comparação vectorial finish[i] = true; update = true; } Soma vectorial 4. if( update==false ) { for( i=0;i<n;i++ ) if(!finish[i]) break; if( i==n ) printf( Estado inseguro!\n ); } } Programação de Sistemas Impasse/Carência : 16/27
Detecção de impasse (5) Objectivos dos 4 passos A inicialização é feita no passo 1, colocando todos os processos como inacabados. No passo 2 é feita uma procura do primeiro processo, para o qual há instâncias de cada recurso disponíveis que faltam para terminar. No passo 3, o processo seleccionado termina e a tabela available é actualizada. No passo 4, detecta-se impasse se houver processos inacabados e não tiver havido uma actualização da tabela available nos passos 2 e 3. O algoritmo tem custo O(NM) Programação de Sistemas Impasse/Carência : 17/27 Detecção de impasse (6) Sejam 5 processos e 3 tipos de recursos A,B,C alloc A B C P0 0 1 0 2 0 0 P2 3 0 2 P3 2 1 1 P4 0 0 2 max A B C P0 7 5 3 3 2 2 P2 9 0 2 P3 2 2 2 P4 4 3 3 available A B C 3 3 2 1. O processo pode ser servido dos recursos necessários o max(,a)-alloc(,a) available(a): 3-2 3 o max(,b)-alloc(,b) available(b): 2-0 3 o max(,c)-alloc(,c) available(c): 2-0 2 available alterado para [ 3+2,3+0,2+0 ] Programação de Sistemas Impasse/Carência : 18/27
Detecção de impasse (7) alloc A B C P0 0 1 0 P2 3 0 2 P3 2 1 1 P4 0 0 2 max A B C P0 7 5 3 P2 9 0 2 P3 2 2 2 P4 4 3 3 available A B C 5 3 2 2. O processo P3 pode ser servido dos recursos necessários o max(p3,a)-alloc(p3,a) available(a): 2-2 5 o max(p3,b)-alloc(p3,b) available(b): 2-1 3 o max(p3,c)-alloc(p3,c) available(c): 2-1 2 available alterado para [ 5+2,3+1,2+1 ] Programação de Sistemas Impasse/Carência : 19/27 Detecção de impasse (8) alloc A B C max A B C available A B C P0 0 1 0 P0 7 5 3 P2 3 0 2 P2 9 0 2 P3 P3 P4 0 0 2 P4 4 3 3 7 4 3 3. O processo P4 pode ser servido dos recursos necessários o max(p4,a)-alloc(p4,a) available(a): 4-0 7 o max(p4,b)-alloc(p4,b) available(b): 3-0 4 o max(p4,c)-alloc(p4,c) available(c): 3-2 3 available alterado para [ 7+0,4+0,3+2 ] Programação de Sistemas Impasse/Carência : 20/27
Detecção de impasse (9) alloc A B C P0 0 1 0 P2 3 0 2 P3 P4 max A B C P0 7 5 3 P2 9 0 2 P3 P4 available A B C 7 4 5 4. O processo P2 pode ser servido dos recursos necessários o max(p2,a)-alloc(p2,a) available(a): 9-3 7 o max(p2,b)-alloc(p2,b) available(b): 0-0 4 o max(p2,c)-alloc(p2,c) available(c): 2-2 5 available alterado para [ 7+3,4+0,5+2 ] Programação de Sistemas Impasse/Carência : 21/27 Detecção de impasse (10) alloc A B C P0 0 1 0 P2 P3 P4 max A B C P0 7 5 3 P2 P3 P4 available A B C 10 4 7 5. O processo P0 pode ser servido dos recursos necessários o max(p0,a)-alloc(p0,a) available(a): 7-0 10 o max(p0,b)-alloc(p0,b) available(b): 5-1 4 o max(p0,c)-alloc(p0,c) available(c): 3-0 7 available alterado para [ 10+0,4+1,7+0 ] O traço <,P3,P4,P2,P0> é seguro. Programação de Sistemas Impasse/Carência : 22/27
Detecção de impasse (11) Inconvenientes do algoritmo do banqueiro: Obriga os processos a conhecer antecipadamente todos os recursos que necessitam, o que é impraticável para sistemas interactivos. Aumento do custo de requisição de um recurso ( overhead ). A maior parte dos impasses ocorre nos processos do utilizador, não nos processos do sistema operativo. Estratégias adoptadas pelo Unix: Ignorar os impasses (considera ser melhor aceitar que ocorram de vez em quando e que sejam tratados pelos utilizadores, que sobrecarregar o sistema). Limitar-se a negar pedidos para recursos indisponíveis. Programação de Sistemas Impasse/Carência : 23/27 Recuperação do impasse (1) Estratégias de recuperação dos impasses: A. Terminação de processos: abortar sucessivamente processos até terminar o impasse Problema: que critérios a seguir para terminar processos? Prioridade Tempo de computação Quantidade de recursos usados Quantidade de recursos que necessita para concluir Tipo de processo (interactivo ou lotes) Programação de Sistemas Impasse/Carência : 24/27
Recuperação do impasse (2) B. Preempção de recursos: retirar sucessivamente recursos aos processos até terminar o impasse Problema: que recursos e que processo seleccionar? Número de recursos detidos pelos processos bloqueados. Tempo de computação que os processos já usaram. Problema: que fazer ao processo a quem foram retidos recursos? Retornar o processo a um estado segura e continuar a partir daí. Abortar o processo e começar de novo. Problema: como evitar carência de processos? Programação de Sistemas Impasse/Carência : 25/27 Carência (1) Múltiplos processos a requerer o mesmo recurso obrigam definir políticas de atribuição dos recursos. [Def] Carência ( starvation ): um processo nunca consegue aceder a um recurso, enquanto outros processos conseguem aceder ao recuso. [Def] Um sistema manifesta a propriedade de equidade ( fairness ) se nenhum processo for carente. Programação de Sistemas Impasse/Carência : 26/27
Carência (2) A propriedade de equidade é mais difícil de verificar que a animação, uma vez que para falhar a animação exige uma execução finita, a equidade exige uma execução infinita. A falha na equidade pode ser detectada com ferramentas de verificação de modelos. A estratégia de distribuição por fila (FCFS- First Come, First Served ) é justa e frequentemente a adoptada. Programação de Sistemas Impasse/Carência : 27/27