Cursos / Redes de Computadores / Sistemas Operacionais / Aula
O ser humano não vive isoladamente; precisamos a todo o momento nos comunicar uns com os outros, seja verbalmente, seja por escrito ou através de gestos (por exemplo, através de um simples sinal de mão que você faz para seu colega numa partida de futebol dizendo que você está livre para receber a bola). No mundo da computação, mais especificamente quando falamos de processos, a comunicação é também muito importante. Por exemplo, quando mais de um processo compartilha o acesso da impressora, os processos precisam saber quando a impressora está disponível para ser utilizada.
Gerenciar a comunicação entre processos é uma tarefa um tanto complicada. Para entender melhor essa complexidade, imaginemos a seguinte situação: vamos supor que você e seu amigo desejam comprar o mesmo livro em um mesmo site de vendas e ambos realizam o pedido quase ao mesmo tempo. Após o pedido, o livro deverá ser colocado no seu carrinho de compra.
De acordo com a Figura 8, vemos que no estoque da loja virtual existe apenas uma unidade do livro que você deseja comprar (1). O processo da primeira compra verifica que o estoque do produto é igual a 1 e portanto ele registra essa informação entre seus dados internos (2); antes que esse processo adicione o livro no carrinho virtual de compras, o segundo processo verifica que ainda existe uma unidade do livro e registra essa informação internamente (3). Logo em seguida, ambos os processos gravam estoque zero para o sistema (4 e 5). E, no final, ambos os carrinhos virtuais estão com o mesmo livro de posse (6), provocando um erro.
Uma solução simples para evitar o erro seria deixar o primeiro processo gravar o estoque com zero antes que fosse verificada a situação do estoque pelo segundo processo; entretanto, no mundo real, a ordem de execução das ações de cada processo é imprevisível.
Essa situação é conhecida como condição de corrida, pois a velocidade de execução dos processos que competem pelo mesmo recurso (no exemplo, o livro) pode afetar o resultado final, colocando-o numa situação inconsistente.
Para solucionar o problema, é preciso encontrar uma maneira de proibir que mais de um processo leia e grave dados compartilhados ao mesmo tempo. Essa abordagem, utilizada para solucionar os problemas das disputas nos acessos a recursos comuns, é chamada nos livros como mecanismo de exclusão mútua, ou seja, uma forma de garantir que se um processo está utilizando-se de um recurso compartilhado, os outros processos estão impedidos de acessar o mesmo recurso.
A parte do programa que eventualmente pode levar a uma condição de corrida é conhecida como região crítica. A ação de alterar o estoque no exemplo anterior pode ser considerada então como uma região crítica e, caso ela esteja inserida em um programa, deve ser tratada de forma a garantir que toda vez que um processo começar a executá-la, ele realizará a ação completa, com exclusão mútua. Assim, considerando o exemplo anterior, o processo precisa inicialmente obter a autorização para o acesso exclusivo ao estoque e, na sequência, executar toda a ação associada, para então, ao final, disponibilizar o estoque atualizado para os demais processos.
É, portanto, papel do sistema operacional garantir que os processos cooperem de forma correta e eficientemente. Para tanto, o sistema operacional trabalha para assegurar que algumas condições de execução sejam atendidas, entre elas podemos citar:
Garantidas essas e outras condições, o sistema operacional permitirá que os processos se utilizem de recursos compartilhados sem a ocorrência de condições de corrida e sem situações de impasse na obtenção de exclusividade no acesso aos recursos.
Versão 5.3 - Todos os Direitos reservados