Baixe o app para aproveitar ainda mais
Prévia do material em texto
SISTEMAS OPERACIONAIS Cleverson Lopes Ledur Componentes de um sistema operacional Objetivos de aprendizagem Ao final deste texto, você deve apresentar os seguintes aprendizados: � Identificar como funciona o gerenciamento de processos. � Descrever o gerenciamento de memória. � Definir o conceito de gerenciamento de arquivos. Introdução Um sistema operacional gerencia uma série de questões para abstrair complexidades do usuário e permitir que sistemas sejam executados. Entre essas questões que são abstraídas, temos processos, memória, discos e arquivos. Imagine tudo isso como uma grande orquestra, em que o sistema operacional sabe o momento certo de iniciar, executar, parar, acessar, remover, entre diversas outras ações realizadas. Inicialmente, o gerenciamento permite acompanhar todo o ciclo de vida de um processo utilizado para executar uma série de instruções de um programa. Logo, você irá conhecer também como ocorre o gerenciamento de memória, ou seja, como são armazenados os dados necessários para os processos. Por fim, sobre o gerenciamento de discos e arquivos, você vai aprender como os dados são persistidos temporariamente ou permanentemente em discos e outros dispositivos. Neste capítulo, você vai conhecer um pouco das ações que o sis- tema operacional realiza para gerenciar todos esses fatores. Você irá identificar como funciona o gerenciamento de processos, descrever o gerenciamento de memória e definir o conceito de gerenciamento de arquivos. Gerenciamento de processos Um processo é um programa em execução. O status da atividade atual de um processo é representado pelo valor do contador do programa e pelo conteúdo dos registradores do processador. O layout de memória de um processo é tipicamente dividido em várias seções, que incluem: � Seção de texto — o processo, conhecido também como “seção de texto”, inclui a atividade atual, representada pelo valor do contador de programa. � Seção de dados — inclui as variáveis globais do processo. � Seção heap — memória alocada dinamicamente durante o tempo de execução do programa. � Seção pilha (stack) — armazenamento de dados temporário ao invocar funções (como parâmetros de função, endereços de retorno e variáveis locais). Algo interessante a se considerar é que os tamanhos das seções de texto e dados são fixos, pois não são alterados durante o tempo de execução do programa. No entanto, as seções de pilha e heap podem diminuir e crescer dinamicamente durante a execução do programa. Cada vez que uma função é chamada, um registro de ativação contendo parâmetros de função, variáveis locais e o endereço de retorno é colocado na pilha. Quando o controle é retor- nado da função, o registro de ativação é retirado da pilha. Da mesma forma, o heap crescerá à medida que a memória for alocada dinamicamente e diminuirá quando a memória for retornada ao sistema. Embora as seções de pilha e heap cresçam uma em direção à outra, o sistema operacional deve garantir que elas não se sobreponham (SILBERSCHATZ; GAGNE; GALVIN, 2012). Além disso, devemos enfatizar que um programa por si só não é um pro- cesso. Um programa é uma entidade passiva, como um arquivo contendo uma lista de instruções armazenadas no disco (geralmente chamada de executável). Em contraste, um processo é uma entidade ativa, com um contador de programa especificando a próxima instrução a ser executada e um conjunto de recursos associados. Um programa se torna um processo quando um arquivo executável é carregado na memória. Existem duas técnicas comuns para carregar arquivos executáveis. Uma é clicar duas vezes em um ícone que representa o arquivo executável. A outra é digitar o nome do arquivo executável na linha de comando. Embora dois processos possam estar associados ao mesmo programa, são considerados duas sequências de execução separadas. Por exemplo, vários Componentes de um sistema operacional2 usuários podem estar executando cópias diferentes do programa de e-mail ou o mesmo usuário pode invocar várias cópias do programa do navegador da web. Cada um desses é um processo separado; e, embora as seções de texto sejam equivalentes, variam as seções de dados, heap e pilha. Também é comum ter um processo que gera outros processos durante a execução (SILBERSCHATZ; GAGNE; GALVIN, 2012). Conforme um processo é executado, ele muda de estado. O estado de um processo é definido em parte pela atividade atual desse processo. Um processo pode estar em um dos seguintes estados, também ilustrados na Figura 1: � Novo — o processo está sendo criado. � Execução — instruções estão sendo executadas. � Espera — o processo está aguardando a ocorrência de algum evento. � Pronto — o processo está aguardando para ser atribuído a um processador. � Terminado — o processo terminou a execução. Figura 1. Estados de um processo. Fonte: Adaptada de Felipe (2016). novo pronto espera terminado execução admitido interrompido escalado concluído suspenso atendido Esses nomes são arbitrários e variam de acordo com os sistemas operacio- nais. No entanto, os estados que eles representam são encontrados em todos os sistemas. Certos sistemas operacionais também delineiam mais precisamente os estados do processo. É importante perceber que apenas um processo pode ser executado em qualquer núcleo de processador a qualquer momento. Muitos processos podem estar prontos ou aguardando, no entanto. Além disso, cada processo é representado no sistema operacional por um bloco de controle de processo (PCB) — também chamado de bloco de 3Componentes de um sistema operacional controle de tarefas. Ele contém muitas informações associadas a um processo específico, incluindo: � Estado do processo — o estado pode ser novo, pronto, em execução, aguardando, interrompido e assim por diante. � Contador de programa — o contador indica o endereço da próxima instrução a ser executada para o processo. � Registros da CPU — os registros variam em número e tipo, dependendo da arquitetura do computador. Incluem acumuladores, registros de índice, ponteiros de pilha e registradores de propósito geral, além de qualquer informação de código de condição. Juntamente com o contador de programa, essas informações de estado devem ser salvas quando ocorre uma interrupção, para permitir que o processo seja continuado corretamente depois de ser reprogramado para execução. � Informações de agendamento de CPU — incluem uma prioridade de processo, ponteiros para filas de agendamento e quaisquer outros parâmetros de agendamento. � Informações de gerenciamento de memória — podem incluir itens como o valor dos registradores de base e limite, além das tabelas de páginas, ou tabelas de segmentos, dependendo do sistema de memória usado pelo sistema operacional. � Informação de Métricas — incluem a quantidade de CPU e tempo real usado, limites de tempo, números de conta, números de trabalho ou processo, e assim por diante. � Informações de status de E/S — incluem a lista de dispositivos de E/S alocados no processo, uma lista de arquivos abertos e assim por diante. Em resumo, o PCB serve simplesmente como o repositório de todos os dados necessários para iniciar ou reiniciar um processo, juntamente com algumas métricas. Um conceito muito interessante no contexto de processos é a thread. Até agora, você viu um modelo em que o processo é um programa que executa um único encadeamento de execução (de forma sequencial). Por exemplo, quando um processo está executando um processador de texto, um único encadeamento de instruções está sendo executado. Essa única thread de controle permite que o processo execute apenas uma tarefa por vez. Na Figura 2, você pode notar a diferença entre um processo e uma thread. Componentes de um sistema operacional4 Figura 2. Processo x Threads Fonte: Treinaweb (2018, documento on-line). Assim, o usuário não pode digitar caracteres e simultaneamente executar o verificador ortográfico. A maioriados sistemas operacionais modernos esten- deu o conceito de processo para permitir que ele tenha vários encadeamentos de execução e, assim, possa executar mais de uma tarefa por vez. Esse recurso é muito benéfico em sistemas multicore, em que vários segmentos podem ser executados em paralelo. Um processador de texto multithreaded poderia, por exemplo, atribuir um thread para gerenciar a entrada do usuário enquanto outro executa o verificador ortográfico. Em sistemas que suportam vários threads, o PCB é expandido para incluir informações para cada um deles. Outras alterações em todo o sistema também são necessárias para suportar a execução de múltiplos threads (SILBERSCHATZ; GAGNE; GALVIN, 2018). Gerenciamento de memória Um conceito muito importante no contexto de sistemas operacionais é o de hierarquia de memória, na qual os computadores podem ter: � poucos megabytes de memória cache, volátil, muito rápida e cara; � alguns gigabytes de memória principal, volátil, de média velocidade e com preço também médio; 5Componentes de um sistema operacional � alguns terabytes de armazenamento em disco magnético ou em estado sólido, não volátil, lento e barato. Além disso, existe o armazenamento removível, como dos DVDs e pen drives. É trabalho do sistema operacional abstrair essa hierarquia de forma utilizável para o usuário e, em seguida, gerenciar a abstração. A parte do sis- tema operacional que gerencia (parte da) hierarquia de memória é chamada de gerenciador de memória. Sua função é gerenciá-la de forma eficiente: rastrear quais partes estão em uso, alocar memória para os processos quando precisa- rem e desalocá-los quando forem concluídos (TANENBAUM; BOS, 2014). A abstração da memória é um dos fatores que permitiram a evolução histórica dos computadores. De forma geral, expor a memória física aos processos tem várias desvantagens importantes. Primeiro, se os programas do usuário puderem lidar com cada byte de memória, facilmente poderão destruir o sistema operacio- nal, intencional ou acidentalmente. Esse problema existiria mesmo se apenas um programa do usuário (aplicativo) estivesse em execução. Além disso, com este modelo, é difícil ter vários programas rodando ao mesmo tempo e sabemos que, em computadores pessoais, é comum ter vários programas abertos ao mesmo tempo (um processador de texto, um programa de e-mail, um navegador da Web), um deles tendo o foco atual, mas os outros sendo reativados ao clique do mouse. Como vemos, é muito difícil operar com computadores quando não há abstração da memória física. Assim, os sistemas operacionais evoluíram para permitir que vários aplicativos estejam em memória ao mesmo tempo, sem interferir um com o outro. Para tanto, usam os conceitos de proteção e realocação. O espaço de endereço foi a chave para tornar possível a criação de uma abstração para a memória. Assim como o conceito de processo cria um tipo de CPU abstrata para executar programas, o espaço de endereçamento cria um tipo de memória abstrata para os programas. Um espaço de endereçamento é o conjunto de endereços que um pro- cesso pode usar para endereçar a memória. Cada processo tem seu próprio espaço de endereçamento, independentemente daqueles pertencentes a outros processos (exceto em algumas circunstâncias especiais em que os processos desejam compartilhar seus espaços de endereçamento). Se a memória física do computador for grande o suficiente para conter todos os processos, os esquemas descritos até aqui funcionarão adequadamente. Na prática, porém, a quantidade total de RAM necessária para todos os processos é muitas vezes maior do que a capacidade de memória. Em um típico sistema Windows, OS X ou Linux, algo como 50 a 100 processos (até mais) podem ser iniciados assim que o computador é inicializado. Quando um aplicativo do Windows Componentes de um sistema operacional6 é instalado, por exemplo, ele geralmente emite comandos para que, na ini- cialização subsequente do sistema, seja iniciado um processo que não faça nada, exceto a verificação de atualizações no aplicativo. Esse processo pode ocupar facilmente de 5 a 10 MB de memória (TANENBAUM; BOS, 2014). Outros processos em segundo plano verificam se há mensagens recebidas, conexões de rede de entrada e muitas outras coisas. E tudo isso ocorre antes do primeiro programa do usuário ser iniciado. Programas sérios de aplicativos de usuários hoje em dia, como o Photoshop, podem facilmente requerer 500 MB apenas para inicializar e muitos gigabytes quando começarem a processar dados. Manter todos os processos o tempo todo requer uma quantidade enorme de memória e não pode ser feito se não houver espaço suficiente. Duas abor- dagens gerais para lidar com a sobrecarga de memória foram desenvolvidas ao longo dos anos. A estratégia mais simples, chamada swapping, consiste em inserir cada processo em sua totalidade, executá-lo por um tempo e de- pois colocá-lo de volta no disco. Os processos inativos são armazenados em disco, de modo que não ocupam memória quando não estão em execução. A outra estratégia, chamada memória virtual, permite que os programas sejam executados mesmo quando estão parcialmente na memória principal. Veja, na Figura 3 o utilitário chamado HTOP do Unix/Linux, que permite a leitura da utilização dos núcleos do processador, memória RAM e swap. Também é possível verificar os processos sendo executados na parte inferior, bem como terminá-los (TANENBAUM; BOS, 2014). Figura 3. Programa HTOP exibindo os processos em execução na parte inferior. Na parte superior, exibindo a utilização dos quatro núcleos de processamento, a utilização da me- mória e swap. 7Componentes de um sistema operacional Gerenciamento de arquivos A maior parte do armazenamento secundário para computadores modernos é fornecida por unidades de disco rígido (HDDs) e dispositivos de memória não volátil (NVM). Uma das responsabilidades do sistema operacional é usar o hardware com eficiência. Para os HDDs, atender a essa responsabilidade implica em minimizar o tempo de acesso e maximizar a largura de banda da transferência de dados. Para HDDs e outros dispositivos de armazenamento mecânico que usam discos, o tempo de acesso tem dois componentes principais. O tempo de busca é o tempo para o braço do dispositivo mover as cabeças para o cilindro que contém o setor desejado. A latência rotacional é o tempo adicional para que o prato gire o setor desejado para a cabeça. A largura de banda do dispositivo é o número total de bytes transferidos, dividido pelo tempo total entre a pri- meira solicitação de serviço e a conclusão da última transferência. Podemos melhorar o tempo de acesso e a largura de banda gerenciando a ordem na qual as solicitações de E/S de armazenamento são atendidas (SILBERSCHATZ; GAGNE; GALVIN, 2012). Sempre que um processo precisa de E/S para ou da unidade, ele emite uma chamada de sistema para o sistema operacional. A solicitação especifica várias informações: � operação é entrada ou saída; � identificador de arquivo aberto indicando o arquivo para operar; � qual é o endereço de memória para a transferência; � quantidade de dados para transferir. Se a unidade e o controlador desejados estiverem disponíveis, a solicitação poderá ser atendida imediatamente. Se a unidade ou o controlador estiver ocupado, todas as novas solicitações de serviço serão colocadas na fila de solicitações pendentes para essa unidade. Para um sistema de multiprograma- ção, com muitos processos, a fila de dispositivos pode ter muitas solicitações pendentes. A existência de uma fila de pedidos para um dispositivo que pode ter seu desempenho otimizado, evitando as buscas, permite que os drivers de dispositivos melhorem o desempenho. No passado, as interfaces de HDD exigiam que o host especificasse qual faixa e qual cabeça usar. Muito esforço foi dispendido em algoritmos de Componentes de um sistema operacional8 escalonamento de disco e, assim, as unidadesmais recentes, após a virada do século, não apenas não expõem esses controles ao host, mas também mapeiam o LBA para endereços físicos sob controle de unidade. As metas atuais do agendamento de disco incluem imparcialidade, pontualidade e otimizações, como leituras ou gravações de agrupamentos que aparecem em sequência, já que os discos têm melhor desempenho com E/S sequencial. Portanto, alguns esforços de escalonamento ainda são úteis. Os computadores podem armazenar informações em várias mídias, como dispositivos NVM, HDDs, fitas magnéticas e discos ópticos. Para que possam ser usados, o sistema operacional fornece uma visão lógica uniforme das informações armazenadas. Abstrai as propriedades físicas de seus dispositivos para definir uma unidade de armazenamento lógico, o arquivo. Os arquivos são mapeados pelo sistema operacional em dispositivos físicos. Esses dispo- sitivos de armazenamento geralmente não são voláteis, portanto, o conteúdo é persistente entre reinicializações do sistema (SILBERSCHATZ; GAGNE; GALVIN, 2012). Um arquivo é uma coleção nomeada de informações relacionadas que são registradas no armazenamento secundário. Da perspectiva de um usuário, um arquivo é o menor lote de armazenamento secundário lógico; ou seja, os dados não podem ser gravados no armazenamento secundário, a menos que estejam em um arquivo. Comumente, arquivos representam programas e dados. Os arquivos de dados podem ser numéricos, alfabéticos, alfanuméricos ou binários. Podem ser de forma livre, como arquivos de texto, ou podem ser formatados rigidamente. Em geral, um arquivo é uma sequência de bits, bytes, linhas ou registros, cujo significado é definido pelo criador e usuário do arquivo (SILBERSCHATZ; GAGNE; GALVIN, 2012). O conceito de um arquivo é, portanto, extremamente aberto para diferentes interpretações. Na Figura 4, você pode ver um exemplo de dois arquivos dentro de um diretório. Você irá entender mais sobre os diretórios a seguir. 9Componentes de um sistema operacional Figura 4. Exibindo dois arquivos dentro de um diretório no sistema operacional Linux. Como os arquivos são o método que os usuários e aplicativos usam para armazenar e recuperar dados, e como são de propósito geral, seu uso se estendeu para além de seus limites originais. A informação em um arquivo é definida por seu criador. Muitos tipos dife- rentes de informações podem ser armazenados em um arquivo — programas de origem ou executáveis, dados numéricos ou de texto, fotos, música, vídeo e assim por diante. Um arquivo tem uma estrutura definida, que depende do seu tipo. Um arquivo de texto, por exemplo, é uma sequência de caracteres organizados em linhas. Um arquivo de origem é uma sequência de funções, cada uma delas organizada posteriormente como declarações seguidas por instruções executáveis. Um arquivo executável é uma série de seções de código que o carregador pode trazer para a memória e executar. Cada arquivo pode conter atributos que ajudam a identificá-lo e dar infor- mações adicionais a respeito de sua origem, objetivo e conteúdo. Os atributos variam de um sistema operacional para outro, mas geralmente consistem em: � Nome — o nome do arquivo simbólico é a única informação mantida em formato legível. � Identificador — tag exclusiva, geralmente um número, identifica o arquivo no sistema de arquivos; é seu nome não legível. Componentes de um sistema operacional10 � Tipo — informação necessária para sistemas que suportam diferentes tipos de arquivos. � Localização — essa informação é um ponteiro para um dispositivo e para a localização do arquivo nesse dispositivo. � Tamanho — inclui o tamanho atual do arquivo (em bytes, palavras ou blocos) e, possivelmente, o tamanho máximo permitido. � Proteção — as informações de controle de acesso determinam quem pode ler, gravar, executar e assim por diante. � Timestamps e identificação do usuário — informações sobre criação, última modificação e último uso, que podem ser úteis para proteção, segurança e monitoramento de uso. Na Figura 5, você confere a exibição dos atributos de um arquivo no Linux. Figura 5. Exibição das propriedades de um arquivo no Linux. Outra abstração oferecida pelos sistemas operacionais é a do diretório, que pode ser visto como uma tabela de símbolos que traduz nomes de arquivos em seus blocos de controle e pode ser organizado de várias maneiras. A organização deve nos permitir inserir e excluir entradas, pesquisar uma entrada nomeada e listar todas as entradas no diretório. Nesta seção, examinamos vários esquemas para definir a estrutura lógica do sistema de diretórios (SILBERSCHATZ; GAGNE; GALVIN, 2012). 11Componentes de um sistema operacional Um diretório (ou subdiretório) contém um conjunto de arquivos ou sub- diretórios. Em muitas implementações, é simplesmente outro arquivo, mas é tratado de uma maneira especial. Todos os diretórios possuem o mesmo formato interno. Um bit em cada entrada de diretório define a entrada como um arquivo (0) ou como um subdiretório (1). Na Figura 6, você vê um diretório criado no sistema operacional Linux. Figura 6. Exibição de um diretório no Linux. Os mecanismos de proteção fornecem acesso controlado, limitando os tipos de acesso a arquivos. O acesso é permitido ou negado dependendo de vários fatores, um dos quais é justamente o tipo de acesso solicitado. Diversos tipos diferentes de operações podem ser controlados, como observa-se nos itens listados a seguir. � Ler — lê a partir do arquivo. � Escrever — escreve ou reescreve o arquivo. � Executar — carrega o arquivo na memória e o executa. � Acrescentar — escreve novas informações no final do arquivo. � Excluir — exclui o arquivo e libera seu espaço para possível reutilização. � Listar — lista o nome e os atributos do arquivo. � Atribuir mudança — altera os atributos do arquivo. Componentes de um sistema operacional12 Outras operações, como renomear, copiar e editar o arquivo, também podem ser controladas. Para muitos sistemas, no entanto, essas funções de nível superior podem ser implementadas por um programa do sistema que faz chamadas de sistema de nível inferior. Outra operação que é responsabilidade do sistema operacional é o geren- ciamento de espaço livre. O sistema mantém trilhas dos blocos de disco livre para alocar espaço para arquivos quando eles são criados. Além disso, para reutilizar o espaço liberado pela exclusão dos arquivos, o gerenciamento de espaço livre se torna crucial. O sistema mantém uma lista de espaços livres que controla os blocos de disco não alocados em algum arquivo ou diretório. A lista de espaços livres pode ser implementada principalmente como: � Bitmap ou bit vector — um bitmap ou bit vector é uma série ou coleção de bits em que cada um corresponde a um bloco de disco. O bit pode ter dois valores: 0 e 1. “0” indica que o bloco está alocado e “1” indica um bloco livre. � Linked list — nessa abordagem, os blocos de discos livres estão liga- dos entre si, de forma que um bloco livre contém um ponteiro para o próximo. O número de bloco do primeiro bloco de disco é armazenado em um local separado e também é armazenado em cache na memória. � Agrupamento — essa abordagem armazena o endereço dos blocos livres no primeiro bloco livre. Esse armazena o endereço de “n” blocos livres. Desses “n” blocos, os primeiros blocos “n-1” estão realmente livres e o último bloco contém o endereço dos próximos “n” blocos livres. Uma vantagem dessa abordagem é que os endereços de um grupo de blocos de discos livres podem ser encontrados facilmente. � Counting — essa abordagem armazena o endereço do primeiro bloco de disco livre e um número “n” de blocos contíguos livres que seguem o primeiro bloco. Cada entrada na lista contém o endereço do primeiro bloco e um número “n”. Ao utilizar o Linux, você pode verificar quais processos estão sendo executados através do comando ps. Veja um exemplo do uso deste comando no terminal do Linuxna imagem a seguir. 13Componentes de um sistema operacional Veja que podemos utilizar os parâmetros -aux para uma exibição mais completa dos processos, tendo informações sobre qual usuário executou o processo, seu PID (process ID), quantidade de CPU sendo utilizada por ele, quantidade de memória sendo utilizada por ele e outras informações mais detalhadas, como tempo de início/fim e nome do comando executado. O Linux também conta com diferentes utilitários de interface gráfica para o geren- ciamento de processos, que podem mudar de distribuição para distribuição. No Windows, você pode utilizar o Gerenciador de Tarefas, conforme a imagem a seguir. Neste, há uma grande quantidade de informações, além de poder finalizar os pro- cessos diretamente pela interface. Componentes de um sistema operacional14 FELIPE, N. Processos e Threads. Diário de Nilton Felipe. 14 out. 2016. Disponível em: <https://niltonfelipe.wordpress.com/2016/10/14/processos-e-threads/>. Acesso em: 9 jan. 2019. SILBERSCHATZ, A.; GAGNE, G.; GALVIN, P. B. Operating system concepts. 9. ed. Danvers: Wiley, 2012. TANENBAUM, A. S.; BOS, H. Modern operating system. 4. ed. Upper Saddle River: Prentice Hall, 2014. TREINAWEB. Concorrência, paralelismo, processos, threads, sistemas monotarefa e multitarefa. 28 jun. 2018. Disponível em: <https://www.treinaweb.com.br/blog/ concorrencia-paralelismo-processos-threads-sistemas-monotarefa-e-multitarefa/>. Acesso em: 9 jan. 2019. Leituras recomendadas ARPACI-DUSSEAU, R. H.; ARPACI-DUSSEAU, A. C. Operating systems: Three Easy Pieces. Madison: Arpaci-Dusseau Books, 2015. GERALDI, L. M. A.; GALASSI, C. R.; FORMICE, C. R. Elucidando os sistemas operacionais: um estudo sobre seus conceitos. Joinville: Clube dos autores, 2013. SILBERSCHATZ, A.; GAGNE, G.; GALVIN, P. B. Sistemas operacionais com Java. 8. ed. Rio de Janeiro: Campus, 2016. TANENBAUM, A. S.; BOS, H. Sistemas operacionais modernos. 4. ed. São Paulo: Pearson, 2015. 15Componentes de um sistema operacional Conteúdo:
Compartilhar