Curso de Ciências da Computação 2. NÍVEL DE SISTEMA OPERACIONAL (Cont.) 2.6. Exemplos de Sistemas Operacionais Aqui estudaremos 3 características que muitos sistemas operacionais oferecem: Memória virtual; E/S virtual, e; Processamento paralelo. Em quase nenhum sistema real as coisas são tão limpas e simples como descrevemos. Portanto, vale a pena dar uma olhada mais detalhada nos sistemas operacionais reais utilizados pelas nossas máquinas exemplo para ver como estas ideias são aplicadas na prática. As linhas tanto Intel quanta Motorola possuem uma variedade de sistemas operacionais disponíveis a nossa escolha podemos escolher (Ex. MS Windows, LINUX, etc.). A escolha para as CPUs 680x0 é relativamente fácil: o mundo usa Microsoft. Embora alguns sistemas 68000, como o Macintosh e o antigo Atari, executem sistemas operacionais proprietários, a maioria dos computadores baseados em 68020 e 68030 executam UNIX. Assim, usaremos UNIX como nosso exemplo diverso aqui. Vamos tratar do UNIX porque ele é o sistema escolhido para o 680x0. Embora ele não seja, nem de perto, tão popular quanto o Windows, ele é muito mais interessante e possui algumas ideias somente encontradas no UNIX. Como o UNIX apareceu primeiro, e o OS/2 (DOS, posteriormente o Windows) foram claramente influenciados pelo UNIX, o estudo deste sistema operacional se torna ainda mais interessante. Entretanto, antes de entrar nos aspectos técnicos, vale a pena dizer algumas palavras a respeito de seus respectivos históricos. No meio da década de 1960, o MIT, a Bell Labs e a General Electric decidiram desenvolver em conjunto um sistema avançado de tempo compartilhado, o MULTICS. Para encurtar a história, o MULTICS estava 20 anos a frente do seu tempo em diversos aspectos, e o projeto não foi tão bem quanto os projetistas tinham esperado. Para começar, o hardware era muito pequeno, mas também muito lento, e o compilador para a Iinguagem na qual o MULTICS estava escrito (PL/I) realmente nunca funcionou. Eventualmente, a Bell Labs caiu fora, e a GE saiu junto do mercado de computadores. Uma das pessoas da Bell Labs que trabalhou no MULTICS, Ken Thompson, de repente se viu sem fazer nada. Entretanto, ele notou um PDP-7 velho que ninguém estava utilizando e decidiu escrever sozinho uma versão reduzida e monousuária, do MULTICS para o PDP-7. Apesar do pequeno tamanho do PDP-7, o sistema (apelidado de UNIX) prometeu muito, e assim Thompson, mais tarde junto com seu colega Dennis Ritchie, o transportou para um hardware melhor, reescrevendo-o várias vezes no processo de transferência. Em certo momento, eles tinham uma versão deles rodando num PDP-11/45. Por sorte, o PDP-11/45 era a máquina preferida dos departamentos de computação da maioria das universidades; e muitos usuários achavam os sistemas operacionais da DEC terríveis. Quando a Bell Labs concordou em licenciar o UNIX para universidades por 300 dólares (incluindo todo o código fonte), centenas delas agarraram a chance e o UNIX de repente tornou-se um objeto de Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 1 de 5 Curso de Ciências da Computação culto. Passaram a ocorrer encontros em todo o mundo, onde oradores famosos discutiam como eles haviam corrigido um erro obscuro do núcleo, mostrando o próprio código do núcleo em projetores (na época eram retroprojetores... ). A palavra se espalhou e, em poucos anos, o UNIX tinha sido transportado para dúzias de computadores, grandes e pequenos. No principio da década de 80, ele estava disponível em mais máquinas que qualquer outro sistema operacional da história passada. Sua popularidade aumentava constantemente, e apesar de menos utilizado ele certamente continua a ser o sistema mais utilizado para grandes programas (ex. SAP). No lado ITEL da história, o MS-DOS liderava o mercado dos PCs, mas continha limitações claras para a família Intel 80386. Aí, de repente, eles redescobriram o MULTICS. 20 anos mais tarde os computadores pessoais movidos a 80286 eram capazes de fazer o que um grande mainframe dos anos 60 não conseguia. O projeto do OS/2 voltado aos 80386 era completamente novo, mas em muitos pontos chave era claramente reconhecida a influência do MULTICS, e seu descendente UNIX. A Fig. 2.12 mostra alguns dos pontos críticos onde o OS/2 era superior ao MS-DOS. Em quase todos eles, a influencia do MULTICS era claramente visível. Fig. 2.12 Comparação entre MS-DOS e OS/2. Os projetistas do OS/2 provavelmente gostariam muito de simplesmente tratar o MS-DOS como um sonho ruim e começar tudo de novo, mas isso não era permitido. Haviam dito que o OS/2 precisaria suportar a execução de antigos programas em binário do MS-DOS. Notem que até hoje rodamos emuladores de MS-DOS em nossos computadores. 2.6.1. Exemplos de Memória Virtual O UNIX e o OS/2 adotaram abordagens diametralmente opostas no que tange a gerencia de memória. O UNIX tenta esconder inteiramente a questão, provendo um modelo de memória muito simples, de modo que o sistema poderia ser portado para um grande número de máquinas muito diferentes. O UNIX tem-se tornado altamente popular para computação “pesada”, precisamente porque ele foi portado para muitas máquinas, desde computadores pessoais a supercomputadores. A ampla disponibilidade do UNIX significa que um programa de aplicação pode ser escrito uma vez e então recompilado para uma dúzia de máquinas diferentes sem ser modificado. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 2 de 5 Curso de Ciências da Computação Este porte somente tem sido possível porque o UNIX faz pouquíssimas suposições a respeito do hardware e pouquíssimas exigências dele. A consequência desta forma de fazer as coisas é que o UNIX nem sempre faz um uso ótimo do hardware. O Windows não tem este problema. Ele espreme até a última gota de poder dos PCs. Entretanto, programas escritos para o Windows são pesados, e muito difíceis de se transportar para outros computadores e sistemas operacionais, especialmente se fizerem uso intenso das características avançadas. Em contraste, muitos programas UNIX têm sobrevivido a dúzias de mudanças radicais de hardware e arquitetura, com nada além de uma recopilação, e muitos outros programas tem sido transportados para outros sistemas operacionais com somente um pouco esforço. 2.6.2. Exemplos de E/S Virtual O âmago de qualquer sistema operacional e prover serviços para os programas de usuários, sendo a maioria serviços de E/S tais como leitura ou escrita em vários dispositivos de E/S. Tanto o UNIX quanto o Windows oferecem uma ampla variedade de serviços de E/S aos programas de usuários. Alguns deles, como leitura e escrita em arquivos, são similares, mas outros, não. Além destas semelhanças gerais, a forma como os serviços são invocados é radicalmente diferente nos dois sistemas. Muito da popularidade do sistema UNIX pode ser diretamente devida a sua simplicidade, que, por sua vez, é o resultado direto da organização do sistema de arquivos. Um arquivo comum é uma sequencia linear de bytes de 8 bits começando em 0 e indo até muito além de 1000 megabytes. O próprio sistema operacional não impõe estrutura de registros aos arquivos, embora muitos programas de usuários considerem arquivos de texto ASCII como sequências de linhas, cada linha terminada por um caractere de fim de linha (line feed). Associado a cada arquivo em uso (isto é, todo arquivo aberto) existe um apontador que aponta para o próximo byte a ser lido ou escrito. As chamadas READ e WRITE leem e escrevem dados começando na posição do arquivo indicada pelo apontador. Ambas as chamadas avançam o apontador após a operação de uma quantidade igual ao número de bytes transferidos. A chamada LSEEK move o apontador para um número de byte arbitrário, que pode ser absoluto, relativo a posição corrente ou relativo ao final do arquivo. Qualquer byte no arquivo pode ser acessado randomicamente, movendo primeiro o apontador e então chamando READ ou WRITE. A Fig. 2.13 é um trecho de um programa Pascal que ilustra como as principais chamadas de E/S de arquivos funcionam. Fig. 2.13 Comparação entre MS-DOS e OS/2. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 3 de 5 Curso de Ciências da Computação Antes de entrar no loop, o programa abre um arquivo existente, dados, e cria um novo arquivo, novoarq. O segundo parâmetro para as duas chamadas especificam que os arquivos são para leitura ou escrita, respectivamente. Ambas as chamadas retornam um pequeno inteiro positivo chamado de descritor de arquivo, que é utilizado para identificar o arquivo em chamadas subsequentes. Se OPEN ou CREAT falharem, um descritor de arquivo negativo será retornado, dizendo que a chamada falhou. A chamada READ possui três parâmetros: um descritor de arquivo, um buffer e um contador de byte. A chamada tenta ler o número desejado de bytes do arquivo indicado para o buffer. O número de bytes realmente lidos é retornado em contador, que será menor que bytes se o arquivo for muito curto. A chamada WRITE coloca os bytes recentemente lidos no arquivo de saída. O loop continua até que o arquivo de entrada tenha sido completamente lido, hora em que o loop termina e ambos os arquivos são fechados. Além dos arquivos comuns, o sistema UNIX possui também arquivos especiais, que são usados para acessar dispositivos de E/S. Cada dispositivo de E/S tipicamente possui um ou mais arquivos especiais associados a ele. Lendo ou escrevendo no arquivo especial associado, um programa pode ler ou escrever no dispositivo de E/S. Fitas magnéticas, fitas de papel, terminais e muitos outros dispositivos são tratados desta maneira. As principais chamadas de arquivo e diretório no sistema UNIX são listadas na Fig. 2.14. Fig. 2.14 Algumas das chamadas de sistema do UNIX para arquivos e diretórios. ACCESS determina se é permitida uma leitura, escrita ou execução potencial em um arquivo. CHDIR muda para um novo diretório de trabalho, cujo nome pode ser especificado tanto absolutamente como relativo ao corrente. CHMOO permite que o proprietário de um arquivo troque os bits de proteção RWX. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 4 de 5 Curso de Ciências da Computação STAT coloca informações sobre um arquivo em um buffer, para que o programa possa inspeciona-las. LINK cria uma nova entrada de diretório, com a entrada apontando para um arquivo existente. Por exemplo, a entrada /usr/jim/jotto pode ter sido criada pela chamada LINK(“/usr/ast/bin/jogo3”, “/usr/jim/jotto”) UNLINK remove um arquivo. Se o arquivo tiver apenas um link, o arquivo é deletado. A chamada UNLINK(“/usr/ast/bin/jog03”) torna jogo3 acessível somente através do path /usr/jim/jotto daf para a frente. LINK e UNLINK podem ser utilizados desta maneira para "mover" arquivos de um diretório para outro. 2.6.3. Exemplos de Gerência de Processos Tanto o UNIX quanto o Windows permitem que uma tarefa seja dividida em múltiplos processos que podem ser executados em (pseudo) paralelismo e se comunicarem, no estilo do exemplo produtor-consumidor. Em qualquer instante, um processo UNIX pode criar um subprocesso, que é uma replica exata de si mesmo, executando a chamada de sistema FORK. O processo original é chamado de pai e o processo novo e chamado de filho. Exatamente após o FORK, os dois processos são idênticos, e também compartilham os mesmos descritores de arquivos. Daí para frente, cada um segue o seu próprio caminho e faz o que ele quer, independente do outro. Em muitos casos, o processo filho manipula os descritores de alguma forma, e então executa a chamada de sistema EXEC, que substitui seu programa e seus dados pelo programa e dados encontrados em um arquivo executável especificado como parâmetro da chamada EXEC. Por exemplo, quando um usuário tecla um comando xyz em um terminal, o interpretador de comandos, chamado shell, executa FORK para criar um processo filho. O processo filho então chama EXEC para executar o programa xyz. Os dois processos executam em paralelo (com ou sem EXEC), a menos que o pai deseje esperar que o filho termine antes de continuar. Se o pai deseja esperar, ele executa a chamada de sistema WAIT, que faz com que ele seja suspenso até que o filho termine executando EXIT. Após o término do filho, o pai continua. Processos podem executar FORK quantas vezes quiserem, gerando uma árvore de processos. Na Fig. 2.15, por exemplo, o processo A executou FORK duas vezes, criando dois filhos, B e C. Então B executou FORK também duas vezes, e C, uma vez, resultando em uma árvore final de seis processos. Fig. 2.14 Uma árvore de processos no UNIX. Disciplina: Projeto Lógico de Computadores (5º/6º Sem - 2013). Livro: Andrew S. Tanenbaum Página 5 de 5