Title: Fundamentos de Sistemas Operacionais

Authors: Fábio Procópio (Author)

Capítudo 1 - Introdução a Sistemas Operacionais

Sem título Text

Objetivo da unidade

Olá, cursista! Ao fim desse capítulo, você será capas de compreender os principais aspectos históricos e teróricos dos sistemas operacionais, seus diferentes tipos, sua arquitetura e os elementos que compõe sua estrutura. Você está pront@? Se sim, vamos nessa!

Introdução e Histórico

Certamente você já ouviu falar em "sistema operacional", não é verdade? Aliás, vale a pena destacar que, neste momento, ao ler este texto, você está usando um sistema operacional que pode ser Windows, o Linux, o macOS, o Android, o iOS, o Unix ou qualquer um dos vários que estão disponíveis no mercado.

Um sistema operacional (SO) é um conjunto de instruções que são executadas por um processador (central processing unit, CPU), da mesma forma que ocorre em aplicações que utilizamos frequentemente, como um navegador web, uma planilha eletrônica, um editor de texto ou mesmo um programama que você escreveu em linguagem Python. Nesse contexto, o papel do SO é supervisionar o funcionamento de um computador, administrando a utilização e o comportamento dos recursos disponíveis, como o(s) processador(es), a memória e os dispositivos de entrada/saída.

Os sistemas operacionais foram surgindo a partir da evolução dos sistemas de computação ao longo de vários anos. Portanto, uma maneira de organizar a evolução história da computação é considerando as décadas em que novos computadores e técnicas de computação surgiram. Dessa forma, na linha do tempo abaixo, você pode observar uma breve história dessa evolução.

Lembre-se

Uma compreensão mais aprofundada sobre a evolução histórica dos SOs pode ser encontrada em clássicos da literatura como Machado e Maia (2007), Silberschatz et al. (2008), Tanembaum (2009) e Silberschatz et al. (2013).

Sem título TextEditor

Trajetória dos computadores e SOs no/pelo século XX

Evolução dos sistemas operacionais

1940: Os primeiros computadores

Surgem os primeiros computadores eletromecânicos, constituídos por milhares de válvulas. Os computadores ocupam grandes áreas.

1950: Os computadores passam a ser utilizados em aplicações comerciais

Os computadores passam a ser utilizados em aplicações comerciais. Surgem as primeiras linguagens de programação de alto nível, como Fortran, Algol e Cobol. Os sistemas operacionais passam a incorporar seus próprios conjuntos de rotinas para operações de entrada e saída. Isso possibilita que os programadores não necessitem mais desenvolver rotinas para cada dispositivo.

1960: Surge a multiprogramação

Surgem técnicas como multiprogramação, multiprocessamento, time-sharing e memória virtual.

1970: Equipamentos baratos

Os equipamentos utilizados para computação são barateados e diminuem de tamanho.

1980: Sistemas multiusuários

Os sistemas multiusuários (que serão estudados posteriormente) se destacam, em especial, os que são compatíveis com o Unix. Surgem as estações de trabalho monousuário, mas que executam diversas tarefas concorrentes. Surgem os SOs de rede Novell Netware e Microsoft LAN Manager.

O NCE (Núcleo de Computação Eletrônica) da UFRJ (Universidade Federal do Rio de Janeiro) desenvolve o sistema operacional Plurix para ser utilizado no computador projetado pelo núcleo, que é chamado de PEGASUS.

1990: Interfaces gráficas

Os sistemas operacionais baseados em interfaces gráficas se consolidam Os fabricantes de SOs percebem a necessidade de implementar suporte ao protocolo TCP/IP. A arquitetura cliente/servidor passa a ser fortemente utilizada na internet. Isso promove o surgimento de vários tipos de serviço, entre eles servidores web, de arquivo e de banco de dados.

2000: Surgem diversos SOs

Surgem diversos SOs. A lista é extensa, mas podemos citar: Windows 2000, Windows ME, Knoppix, Windows XP, Mac OS X, Gentoo Linux, Fedora, Kurumin, Ubuntu, Mac OS X Tiger, Linux Mint, OpenSUSE, Windows Vista, iOS, OpenSolaris, Android, WebOS, Windows 7, Mac OS X Snow Leopard, Windows Phone, Chrome OS,  Mac OS X Lion, Tizen, Windows 8, Ubuntu Touch, Firefox OS, Xbox OS, Orbis OS, Windows 10, Windows 11, entre outros.

Sem título TextEditor

Os tipos de SOs estão bastante relacionados à evolução do hardware, bem como às aplicações que podem ser executadas. A figura 1 é utilizada para representar como os tipos de SOs estão organizados.

Figura 1 – Tipos de SOs de acordo com a evolução do hardware.

[Image: Tipos de SOs de acordo com a evolução do hardware]

Sem título TextEditor

Fonte: Elaboração do autor.

Nos próximos tópicos, serão abordados os conceitos e as características dos sistemas monoprogramáveis, sistemas multiprogramáveis, sistemas com múltiplos processadores, a estrutura do sistema operacional, rotinas do sistemas operacional e system calls, além das arquiteturas do núcleo.

Sem título Emphasis Card

Uma compreensão mais aprofundada sobre a evolução histórica dos SOs pode ser encontrada em clássicos da literatura, como Machado e Maia (2007), Silberschatz et al. (2008), Tanembaum (2009) e Silberschatz et al. (2013).

Sem título Text

Sistemas monoprogramáveis

Os primeiros SOs, conhecidos como monoprogramáveis (ou monotarefa) foram projetados para executar uma única aplicação por vez. Quando a aplicação APP1 está sendo executada, por exemplo, o processador, a memória e os periféricos são alocados exclusivamente para ela. Então, para que outras aplicações possam ser executadas, necessariamente, precisam aguardar pelo término da execução da aplicação APP1.

Nesse tipo de SO, supondo uma aplicação em que são informados dados de um usuário, o processador permanece ocioso aguardando o recebimento dos dados preenchidos. Somente após a conclusão do preenchimento do formulário, o processador será novamente utilizado. Considerando ainda que o tamanho da aplicação é menor que o espaço total de memória principal (read access memory, RAM), haverá uma subutilização da memória.  Além disso, dispositivos de armazenamento como disco rígido (hard disk, HD) e solid state drive (SSD) ou outros periféricos como impressoras estarão indisponíveis para outras aplicações, como se pode ver na figura 2.

Figura 2 – SOs monoprogramáveis.

[Image: SOs monoprogramáveis]

Sem título Text

Fonte: Adaptado de Machado e Maia (2007)

Sistemas multiprogramáveis

Ao contrário dos sistemas monoprogramáveis, em sistemas operacionais do tipo multiprogramáveis (ou multitarefas) várias aplicações podem ser executadas simultaneamente, garantindo, assim, o compartilhamento de diversos recursos como processador, memória e dispositivos de entrada/saída, como se vê na figura 3. O próprio sistema deve se encarregar de orquestrar como ocorrerão os acessos simultâneos a esses recursos.

Figura 3 – SOs multiprogramáveis (adaptado de Machado e Maia, 2007)

[Image: SOs multiprogramáveis]

Sem título Text

Fonte: Adaptado de Machado e Maia (2007).

Como você já deve ter imaginado, em um sistema multitarefa o tempo para executar a lista de aplicações é menor do que em um sistema monotarefa. O motivo é que no primeiro sistema várias aplicações podem ser executadas ao mesmo tempo.

Considerando a quantidade de usuários que interagem com um sistema multiprogramável, ele pode ser classificado em dois tipos: monousuário e multiusuário. Os sistemas multiprogramáveis monousuário são encontrados frequentemente em computadores pessoais nos quais um único usuário pode operar com diversas aplicações ao mesmo tempo (por exemplo, construir uma planilha eletrônica e escrever um programa em Python). Já os sistemas multiprogramáveis, do tipo multiusuário, podem ser encontrados em servidores que são acessados por várias aplicações simultaneamente. Como exemplo, podemos pensar em um servidor web que hospeda um portal e é acessado por vários usuários concomitantemente.

Sistemas com múltiplos processadores

Estes sistemas se caracterizam por possuírem dois (ou mais) processadores que trabalham de forma sincronizada. Um ponto positivo nesse tipo de sistema é que várias aplicações podem ser executadas simultaneamente ou subdivididas entre mais de um processador.

Observando a comunicação entre os processadores e como a memória e os dispositivos de entrada/saída são compartilhados, os sistemas com múltiplos processadores podem ser divididos em fortemente acoplados ou fracamente acoplados.

Figura 4 – Sistemas fortemente acoplados.

[Image: Sistemas fortemente acoplados]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia(2007).

Nos sistemas fortemente acoplados, como visto na figura 4, há apenas um SO que gerencia uma única memória física, compartilhada entre os vários processadores do sistema de computação, bem como os dispositivos de entrada/saída.

Figura 5 - Sistemas fracamente acoplados.

[Image: Figura 5 – Sistemas fracamente acoplados(adaptado de Machado e Maia, 2007)]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia(2007)

Por outro lado, os sistemas fracamente acoplados, representados na figura 5, caracterizam-se por possuir dois ou mais sistemas de computação conectados por linhas de comunicação. Dessa forma, cada sistema computacional utiliza seu próprio SO, que gerencia a memória principal e os dispositivos de entrada/saída individualmente.

Em sistemas formente acoplados, o SO gerencia várias CPUs, que acessam uma memória principal compartilhada. Já nos sistemas fracamente acoplados, os sistemas de computação são independentes e gerenciados por seus respectivos SO's. Quanto à comunicação entre eles, ela se dá por meio de linhas de comunicação. Para fixar melhor o assunto, confira a videoaula abaixo.

Sem título TextEditor

O sistema operacional realiza o “meio de campo” entre os usuários e os recursos disponíveis no computador. Seu principal objetivo é tornar o trabalho do usuário mais produtivo e com menos chances de erro.

Dica

Sugestão de filme: Jobs, disponível na Netflix e no Youtube. O filme retrata a vida do cofundador da Apple, Steve Jobs, e abrange a sua ascensão desde o seu período como universitário até a fundação da Apple. O filme também revela eventos que levaram à demissão de Jobs da empresa, bem como o seu afastamento de pessoas bastante próximas, como o amigo Steve Wozniak. No enredo, também é apresentada a evolução dos computadores construídos pela empresa.

Sem título Text

Estrutura do Sistema Operacional

O núcleo do sistema (ou kernel) é um componente central que desempenha um papel importantíssimo na administração e na coordenação dos recursos de hardware. O kernel proporciona uma interface indispensável entre as operações a nível de hardware e as solicitações que são enviadas pelas aplicações de usuários.

A figura 6 representa a estrutura de um SO e as respectivas interfaces existentes entre suas camadas. Cada uma dessas camadas tem como papel desempenhar operações específicas no sistema.

Figura 6 – Estrutura do SO.

[Image: Estrutura do SO]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia(2007)

Em geral, os SOs utilizam uma política de segurança que é presente nos processadores e conhecida como modo de acesso. Há dois tipos de modo de acesso. No primeiro deles, o modo usuário, as aplicações executam uma quantidade limitada de instruções, que são conhecidas como instruções não privilegiadas. No segundo modo de acesso o modo kernel, as aplicações podem ter acesso a todas as instruções do processador. Elas são chamadas de instruções privilegiadas. No entanto, as instruções privilegiadas devem ser utilizadas com bastante cautela.

Sem título Text

Rotinas do sistema operacional e System Calls

As rotinas do SO formam o kernel e oferecem diversos serviços aos usuários e às suas aplicações. As funções do núcleo do sistema são implementadas por meio das instruções privilegiadas mas, para isso, é necessário que o processador esteja no modo de acesso do tipo kernel.

A execução das rotinas do sistema é controlada por um mecanismo chamado system calls, o qual é ativado toda vez que uma aplicação invoca uma rotina do SO.  As system calls e as rotinas do sistema podem ser pensadas como o caminho para se ter acesso ao núcleo do SO e, consequentemente, aos serviços que ele pode oferecer. Assim, quando um programa necessita de um serviço que é realizado por uma das rotinas do sistema, ela invoca uma system call enviando os argumentos que são necessários para que ela funcione. Ao fim da execução, uma resposta é devolvida para o programa indicando o estado de sua solicitação, isto é, “sucesso” ou “falha”.

Lembre-se

Sempre que uma aplicação deseja acessar algum serviço oferecido pelo SO, faz-se uma chamada à rotina específica responsável por fornecer aquele serviço por meio de uma system call.

Sem título Text

Arquiteturas do núcleo

Os vários elementos que constituem um sistema podem ser organizados de diversas formas e, por isso, existem várias arquiteturas para definir o núcleo de um SO: arquitetura monolítica, arquitetura em camadas, arquitetura de máquina virtual e arquitetura microkernel.

Arquitetura monolítica: Os primeiros SOs foram construídos com base nesse modelo por causa da sua simplicidade e desempenho. Essa arquitetura é formada por vários módulos, que são compilados de forma individual e, posteriormente, interligados para que se forme um único programa executável, como se vê na figura 7.

Figura 7 – Arquitetura monolítica

[Image: Arquitetura monolítica]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia(2007)

Arquitetura em camadas: divide o sistema em níveis que se sobrepões e, assim, suas funcionalidades são oferecidas apenas para as camadas superiores. Na figura 8, que representa essa arquitetura, observe que a camada 4 (a mais inferior da figura) oferece serviço para as camadas 3, 2 e 1, enquanto a camada 2 oferece serviços apenas para a camada 1.

Sem título TextEditor

Figura 8 – Arquitetura em camadas

[Image: Arquitetura em camadas]

Sem título TextEditor

Fonte: Elaboração do autor

Arquitetura de máquina virtual: cria um nível intermediário entre o hardware e o SO. São criadas várias máquinas virtuais (virtual machine, VM) independentes e cada uma delas oferece uma cópia virtual do hardware.

Sem título TextEditor

Figura 9 – Máquina virtual .

[Image: Máquina virtual]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia(2007).

Arquitetura microkernel: possibilita reduzir o tamanho e a complexidade do SO. Para isso, os serviços do sistema são ofertados por meio de processos que têm o papel de oferecer um conjunto de funções específicas. Essa arquitetura é uma tedendência: tornar o núcleo do SO menor e mais simples.

Figura 10 – Arquitetura microkernel.

[Image: Arquitetura microkernel]

Sem título TextEditor

Fonte: Adaptado de Machado e Maia (2007)

O projeto de um sistema operacional dependerá bastante da arquitetura do hardware que será utilizada, além da característica do sistema que será construído: batch, tempo compartilhado, monousuário, multiusuário, entre outros.

Dica

Uma das vantagens em utilizar a arquitetura em camadas é isolar as funções do SO para facilitar a sua manutenção. Todavia, para acessar cada uma das camadas da arquitetura, é necessário mudar o modo de acesso, o que diminui o desempenho do sistema.

Exercício de fixação

Q: Qual é a principal diferença entre sistemas operacionais monotarefas e multitarefas?
- Sistemas monotarefas são capazes de executar apenas uma tarefa por vez, enquanto sistemas multitarefas podem executar várias tarefas simultaneamente. (correct)
- Em sistemas monotarefas, o usuário tem mais controle sobre as operações do sistema, enquanto que em sistemas multitarefas o controle é mais restrito.
- A diferença reside apenas na nomenclatura: ambos os termos se referem ao mesmo tipo de sistema operacional.
- Sistemas multitarefas são mais lentos do que sistemas monotarefas devido à necessidade de alternar entre várias tarefas.

Q: Explique a diferença entre sistemas fracamente acoplados e fortemente acoplados em um contexto de sistemas distribuídos.
- Sistemas fracamente acoplados são aqueles em que os componentes podem operar de forma independente, enquanto sistemas fortemente acoplados exigem uma interdependência estreita entre os componentes. (correct)
- Em sistemas fracamente acoplados, a comunicação entre os componentes é rápida e eficiente, enquanto que em sistemas fortemente acoplados a comunicação é lenta e ineficaz.
- Sistemas fracamente acoplados geralmente envolvem uma colaboração mais intensa entre os componentes, enquanto sistemas fortemente acoplados permitem maior autonomia para cada componente.
- Sistemas fortemente acoplados são mais suscetíveis a falhas, enquanto sistemas fracamente acoplados oferecem maior robustez e tolerância a falhas.

Q: Sobre a arquitetura em camadas, selecione a opção correta.
- Refere-se a um modelo que organiza o SO em difererntes níveis funcionais, cada um construído sobre o anterior. (correct)
- É um conceito obsoleto e não mais utilizado em SOs modernos.
- Organiza o SO em apenas duas camadas principais: kernel e aplicativos.
- É exclusiva de SOs para dispositivos móveis e não é relevante para sistemas desktop.

Feedback (0 to 33%): Pode melhorar
Feedback (34 to 66%): Bom
Feedback (67 to 100%): Ótimo

Sem título Text

Conclusão

Abordamos aspectos essenciais relacionados à introdução sobre sistemas operacionais, desde seu papel fundamental na gestão de recursos até a evolução por meio de sistemas monotarefas, multitarefas, multiprocessadores e configurações do tipo monousuário e multiusuário.

Exploramos ainda os sistemas fracamente e fortemente acoplados, compreendendo a influência dessas dinâmicas na colaboração e no desempenho do sistema de computação.
Falamos também sobre as system calls e como as aplicações interagem com o núcleo do SO para acessar os seus serviços e os recursos disponíveis de hardware. Apresentamos as diferentes arquiteturas de SOs, destacando a monolítica, em camadas, máquina virtual e microkernel.

A arquitetura monolítica concentra as funcionalidades do SO em um único núcleo. Isso proporciona eficiência e maior desempenho ao sistema, porém compromete, consideravelmente, a modularidade e a sua manutenção. Por outro lado, o modelo de arquitetura em camadas divide o SO em módulos distintos, facilitando a compreensão e a modificação de partes específicas e, assim, tornando-o mais customizável e expansível.

Falamos também sobre a arquitetura baseada em máquina virtual que cria uma camada de abstração entre o hardware e os SOs envolvidos. Além disso, apresentamos a arquitetura de microkernel, cujos serviços são ofertados por meio de processos com o objetivo de oferecer um conjunto de funções específicas.

Compreendendo essas arquiteturas, você é capaz de visualizar como os SOs são projetados para atender às diversas demandas de aplicativos de usuários. É importante lembrar que cada abordagem possui suas vantagens e desvantagens e, por isso, ao especificar um SO, o projetista deve considerar cuidadosamente os requisitos que devem ser atendidos.

Por fim, a compreensão desses conceitos é crucial para a continuidade da disciplina. Os sistemas operacionais são peças-chave na orquestração eficiente dos recursos do sistema de computação.

Glossário

Este glossário oferece uma visão geral dos conceitos fundamentais abordados nos tópicos mencionados. É uma ferramenta útil para quem busca uma rápida referência ou revisão desses conceitos.

CPU: é a sigla para Central Processing Unit (Unidade Central de Processamento)

Kernel: é o núcleo do sistema operacional. Tem como responsabilidade intermediar as solicitações dos usuários e as operações a nível de hardware.

Sistema Operacional (SO): é um conjunto de instruções executadas por um processador.

Sistemas Fortemente Acoplados: possuem vários processadores em que um único SO gerencia uma memória que é compartilhada entre várias CPUs.

Sistemas Fracamente Acoplados: possuem vários processadores em que cada sistema de computação possui o seu próprio SO.

Sistemas Operacionais Monoprogramáveis: executam uma única tarefa por vez.

Sistemas Operacionais Multiprogramáveis: executam várias tarefas simultaneamente.

Sistemas Operacionais Multiprogramáveis Monousuário: permitem que um único usuário possa operar diversas tarefas simultaneamente.

Sistemas Operacionais Multiprogramáveis Multiusuário: permitem que vários usuários possam operar diversas tarefas simultaneamente.

System Calls: é um mecanismo responsável por executar as rotinas do SO.

Referências

MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de sistemas operacionais. Rio de Janeiro: Ed. LTC, 2007.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Sistemas operacionais com Java. 7. ed. Rio de Janeiro: Ed. Campus, 2008.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Fundamentos de Sistemas operacionais: princípios básicos. Rio de Janeiro: Ed. LTC, 2013.

TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 3. ed. São Paulo: Ed. Pearson Prentice Hall, 2009.

Capítudo 2 - Processos

Sem título Text

Objetivo da Unidade

E aí, cursista? Beleza?!

Nesta unidade, apresentaremos o conceito de processos no contexto dos sistemas operacionais. A ideia é discutir como eles fundamentam a execução de aplicações, bem como seus estados e as transições entre eles. Além disso, destacaremos a complexidade adicionada pelos subprocessos e a eficiência proporcionada pelos threads.

Discutiremos ainda o conceito de região crítica que delineia as áreas sensíveis nas quais os processos concorrentes podem conflitar. Para mitigar esses conflitos, são necessárias soluções de hardware e de software. Apresentaremos um problema clássico da literatura no contexto de processos concorrentes: o jantar dos filósofos. Você ainda vai estudar uma situação indesejada na qual dois (ou mais) processos concorrentes podem se deparar: o deadlock.

Ufa! Parece longo, mas a gente vai conseguir.

Vamos nessa!

Introdução

A multiprogramação consiste na capacidade de um processador executar, simultaneamente, mais de uma aplicação. Essas aplicações compartilham recursos disponíveis, porém cada uma delas possui sua própria área de memória responsável por armazenar dados e instruções.

Os SOs multiprogramáveis são utilizados quando se deseja que um mesmo computador execute mais de uma aplicação ao mesmo tempo. No momento em que lê este material, se desejar, embora isto não seja uma recomendação, você também pode acessar sua plataforma de streaming preferida e ouvir uma nova playlist ou ainda ler seus e-mails recebidos hoje. Isso é possível porque o SO que você está usando é multiprogramável. Aliás, qual SO você usa para estudar este material?

No contexto dos SOs, um processo consiste em um conjunto de informações utilizadas para o gerenciamento da execução concorrente de aplicações. Dessa forma, o conceito de processo é a base para o desenvolvimento dos sistemas multiprogramáveis.

Um processo também pode ser definido como um ambiente no qual uma aplicação é executada. Assim, a fim de manter as informações necessárias para execução de uma aplicação, um processo é dividido em três partes: contexto de hardware, contexto de software e espaço de endereçamento.

O contexto de hardware é essencial em sistemas multiprogramáveis porque garante a alternância entre os processos que estão utilizando o processador. Por outro lado, o contexto de software define os limites e as características dos recursos que podem ser utilizados pelo processo. As informações sobre o processo são armazenadas neste contexto e classificadas em três grupos:

- Identificação: Cada processo possui um número único que define a sua identificação (process identification, PID). O PID serve para que o SO e outros processos identifiquem, exclusivamente, um determinado processo. Além disso, o processo também possui uma identificação única do usuário que o criou (user identification, UID).
- Cotas: Cada processo possui um limite dos recursos que pode utilizar. Como exemplo, podem ser citados a quantidade máxima a) de arquivos abertos; b) de operações de entrada/saída; e c) de memória RAM que pode ser alocada.
- Privilégios: Cada processo possui privilégios que ditam as ações que podem ser realizadas em relação a ele mesmo (alteração de suas características como prioridade de execução, limite de memória alocada etc), a outros processos (mudança das características de outros processos) e ao sistema operacional (desativação do sistema, modificação de regras de segurança etc).

Por fim, a outra parte que constitui o processo é chamada de espaço de endereçamento, que consiste em uma região de memória, alocada pelo processo, na qual são armazenados dados e instruções. Portanto, cada processo possui um espaço de endereçamento individualizado e protegido de acessos que possam ser requisitados por outros processos.

Já no que diz respeito à comunicação do processo com o usuário, um processo pode ser foreground (permite a interação direta entre o usuário e o processo enquanto está sendo executado) ou background (isto é, não existe uma interação entre o usuário e o processo enquanto está sendo executado).

Estados do processo

Quando se trata de um sistema baseado em multiprogramação, o processador deve ser compartilhado entre os vários processos que estão ativos. Portanto, os processos estão em um dos três estados abaixo:

- Em execução (running): quando está sendo executado pelo processador.
- Pronto (ready): quando está aguardando, apenas, sua execução.
- Espera (wait): quando está aguardando por algum evento ou por algum recurso para ser executado.

Um processo pode ser classificado ainda de acordo com o tempo que utiliza o processador: a) CPU-bound, quando passa a maior parte do tempo no estado “pronto” ou “em execução”; e b) I/O-bound, quando passa a maior parte do tempo no estado “espera”, pois executa um número grande de operações de entrada/saída.

Dica

Para otimizar processos CPU-bound é interessante explorar a paralelização. Divida tarefas extensas em sub-tarefas menores que possam ser executadas simultaneamente por threads ou sub-processos, assim aproveitando ao máximo os núcleos da CPU.

Sem título Text

Mudanças de estado de processos

Há eventos que são os responsáveis pela mudança dos estados de um processo. Quando um evento é gerado pelo próprio processo, diz-se que o evento é voluntário. No entanto, quando um evento é gerado pelo SO, ele é chamado de involuntário.

Nos tópicos abaixo e na figura 1, são apresentadas as quatro mudanças que podem ocorrer nos estados de um processo:

- De “pronto” para “em execução”: A mudança se dá quando o processo é selecionado para ser executado.
- De “em execução” para “espera”: A mudança se dá quando ocorre um evento voluntário (como uma solicitação de impressão) ou involuntário (quando o SO, por algum motivo, suspende a execução do processo).
- De “espera” para “pronto”: A mudança ocorre quando uma solicitação feita pelo processo é atendida ou um recurso que ele aguardava é concedido.
- De “em execução” para “pronto”: A mudança acontece quando ocorrem eventos involuntários como, por exemplo, o seu tempo de execução ser finalizado. Nesse caso, o processo passa a aguardar por uma nova oportunidade de ser executado.

Figura 1 – Mudanças de estado de processos

[Image: Mudanças de estado de processos]

Sem título Text

Fonte: Elaboração do autor.

Subprocessos

Como já visto, uma aplicação pode ser executada de forma concorrente por meio da execução de vários processos simultaneamente. Essa é a maneira mais simples de se implementar concorrência, porém, para cada processo criado, é necessária a construção de um contexto de hardware, um contexto de software e um espaço de endereçamento.

Uma outra estratégia de implementação de concorrência é a utilização de subprocessos (processo-filho) que, como o nome sugere, são processos relacionados a um processo principal (processo-pai), conforme figura 2.

Figura 2 – Estrutura de um processo e seus subprocessos

[Image: Estrutura de um processo e seus subprocessos]

Sem título Text

Fonte: Elaboração do autor.

Nessa estratégia, cada subprocesso também possui a sua própria estrutura, que é formada por um contexto de hardware, um contexto de software e um espaço de endereçamento.

Threads

Aplicações concorrentes também podem ser implementadas por meio de threads cujo objetivo é reduzir o tempo necessário para criar, eliminar e trocar contextos de um processo.

De uma forma bastante simplificada, um thread pode ser definido como uma sub-rotina executada de forma assíncrona, isto é, concorrentemente com o programa que a chamou. Assim como processos, threads compartilham o mesmo processador e passam pelas mesmas mudanças de estado.

É importante ressaltar que um thread possui seu próprio contexto de hardware, porém compartilha com os demais threads do processo o mesmo contexto de software e o espaço de endereçamento, como se vê na figura 3.

Figura 3 – Representação de um processo com vários threads

[Image: Representação de um processo com vários threads]

Sem título TextEditor

Fonte: Elaboração do autor

É possível implementar aplicações concorrentes utilizando sub-processos ou threads. Os sub-processos representam processos independentes que compartilham recursos de maneira limitada, enquanto threads são unidades de execução dentro de um processo que compartilham o mesmo espaço de endereçamento.

Dica

Uma estratégia eficaz ao trabalhar com threads é aproveitar o paralelismo para melhorar o desempenho, dividindo tarefas em unidades menores que podem ser executadas simultaneamente.

Sem título TextEditor

No contexto dos SOs, um processo passa por diferentes estados. No estado "em execução", ele está sendo executado ativamente pelo processador. Já no estado "em espera", o processo aguarda por eventos ou recursos externos. Por fim, no estado "pronto", o processo está na fila para ser escalonado e retomar a sua execução. Para fixar melhor o assunto, assista o vídeo a seguir.

Sem título Text

Comunicação entre processos

Em um ambiente multiprogramável, é comum que exista comunicação entre os processos que estão ativos. Como resultado dessa interação, surge a necessidade de que os recursos do sistema (por exemplo, arquivos, bancos de dados, dispositivos de entrada/saída e memória principal) possam ser compartilhados.

No entanto, o compartilhamento desses recursos pode causar alguns problemas capazes de comprometer a execução coerente do sistema. A figura 4 representa um esquema do qual os processos P1 e P2 fazem parte. O esquema é iniciado no instante 0 e encerrado no instante 4. P1 e P2 compartilham as variáveis X, Y e S. O objetivo do esquema é fazer com que S armazene X + Y. Claramente, na figura, vemos que X + Y = 90.

Inconsistência causada pelo compartilhamento de recursos (elaborado pelo autor)

Figura 4 – Inconsistência causada pelo compartilhamento de recursos

Instante | P1 | P2 | X | Y | S
0 |  |  | 40 | 50 | 0
1 | S = S + X |  | 40 | 50 | 40
2 |  | X = X - 10 | 30 | 50 | 40
3 |  | Y = Y + 10 | 30 | 60 | 40
4 | S = S + Y |  | 30 | 60 | 100

Sem título Text

Fonte: Elaboração do autor.

No instante inicial, observa-se que X = 40, Y = 50 e S = 0. No instante 1, S é acrescida do valor de X, isto é, S = 0 + 40 = 40. No instante 2, X é subtraída de 10, assim X = 40 – 10 = 30. No instante 3, Y é acrescida de 10, isto é, Y = 60 = 50 + 10.

Mas, no instante 4, ocorre o momento crítico da execução dos processos P1 e P2. Observe que S é acrescida do valor de Y, assim, S = 100 = 40 + 60. No entanto, se X = 30 e Y = 60, então a variável S deveria armazenar o valor 90 (isto é, 30 + 60) e não o valor 100. Você percebe os problemas que podem ocorrer ao compartilhar recursos?

Região crítica

O problema de inconsistência apresentado anteriormente ocorreu porque o processo P2 passou a utilizar as variáveis compartilhadas antes que o processo P1 terminasse de usá-las.

Uma maneira simples de equacionar o problema é impedir que dois ou mais processos compartilhem, simultaneamente, um mesmo recurso. Portanto, a ideia é que, enquanto um processo P estiver acessando o recurso R, os outros processos que queiram acessá-lo devam aguardar até que P libere a utilização de R. Esse mecanismo de controle é chamado “exclusão mútua”.

Cada processo possui uma região crítica, isto é, um trecho de código no qual o processo pode alterar variáveis, realizar atualizações em tabelas de um banco de dados, modificar o conteúdo de um arquivo, além de várias outras operações.

Assim, o desafio é a definição de um protocolo capaz de garantir que, em um determinado instante, uma região crítica só seja acessada por um único processo.
Soluções de hardware para o problema da região crítica

Algumas soluções de hardware podem ser utilizadas para tentar resolver o problema da região crítica. Algumas delas são a) desabilitação de interrupções e b) instruções test-and-set.

a) Desabilitação de interrupções

É um mecanismo bastante simples: antes de entrar em sua região crítica, o processo deve desabilitar todas as interrupções e, imediatamente antes de sair, elas devem ser reabilitadas. A mudança de contexto só ocorre por meio de interrupções. Assim, o processo que desabilita as interrupções terá acesso exclusivo.

b) Instrução test-and-set

Esse tipo de instrução está presente em vários processadores. Ela consiste em ler uma variável, armazenar o seu conteúdo em outra variável e atribuir um novo valor a essa mesma variável. Uma característica importante de uma instrução test-and-set é que ela é atômica, ou seja, é executada sem interrupção alguma. Portanto, esse mecanismo garante a exclusão mútua porque dois processos não poderão manipular uma variável que esteja compartilhada ao mesmo tempo.

Soluções de software para o problema da região crítica

Ao longo dos anos, várias soluções baseadas em software foram apresentadas para resolução do problema de acesso à região crítica de dois processos como, por exemplo, o algoritmo de Dekker (DIJKSTRA, 1962).

Outro algoritmo clássico para resolver esse problema é chamado algoritmo da padaria (LAMPORT, 1974). O nome do algoritmo faz uma analogia ao sistema de organização de pedidos que são realizados em padarias, no qual são atribuídos números que representam a ordem em que os clientes serão atendidos. Quando um cliente entra em uma padaria, recebe um número de identificação exclusivo. Na verdade, essa forma de organização de atendimento é realizada em vários outros sistemas que não exclusivamente o de padaria. Por exemplo, quando vamos a um restaurante no formato self service, recebemos uma comanda (que é um número único) utilizada para nos identificar enquanto estamos dentro do estabelecimento.

Retornando ao que realmente nos é importante, um contador global exibe o número de clientes que estão sendo atendidos naquele momento, enquanto os demais aguardam pacientemente. Assim que o funcionário da padaria completa o atendimento do cliente atual, ele chama o próximo número na sequência, indicando qual cliente será atendido em seguida.

De maneira similar, no algoritmo de Lamport, os processos são tratados como se fossem clientes. Em vez de pedidos, esses processos aguardam sua vez para acessar suas regiões críticas e recebem números de identificação para estabelecer a ordem de prioridade. O processo com o número mais baixo é o primeiro a ser permitido na região crítica. Caso dois processos tenham o mesmo número, o que possuir um ID de processo mais baixo obtém acesso à região crítica.

Dica

Starvation (espera indefinida ou inanição) é uma situação na qual um determinado processo nunca consegue executar, totalmente, a sua região crítica. Isso ocorre em função de alguns critérios que o processador utiliza para escalonar os processos  que estão na fila de execução. Esses critérios serão estudados mais adiante.

Sem título Text

Jantar dos filósofos

A sincronização entre processos é algo comum na programação de sistemas complexos. Na literatura, há vários problemas relacionados à sincronização com o objetivo de fornecer uma compreensão de como implementar soluções para esses problemas.

Dentre os vários problemas conhecidos, um dos mais clássicos é o jantar dos filósofos que foi proposto por Dijkstra. Nesse problema, de forma muito abstrata, os filósofos se alternam somente entre duas atividades: meditar e comer. Dessa forma, eles não têm qualquer comunicação direta entre si e também não conseguem observar o estado dos outros.

Como visto na figura 5, o cenário do jantar consiste em uma mesa redonda, uma grande tigela de arroz no centro, cinco cadeiras (uma para cada filósofo), cinco pratos e cinco garfos.

Figura 5 – O jantar dos filósofos

[Image: O jantar dos filósofos]

Sem título TextEditor

Fonte: SILBERSCHATZ et al, 2013.

Quando está com fome e quer se alimentar, o filósofo p_i deve pegar um garfo à sua direita e outro à sua esquerda, mas um de cada vez. Devido ao compartilhamento dos garfos (eca!), dois filósofos vizinhos não podem se alimentar simultaneamente. Enquanto se alimenta, um filósofo utiliza os dois garfos sem largá-los. Quando finaliza, ele repõe os dois garfos sobre a mesa e retorna à sua atividade de meditação.

Algumas possíveis soluções para o problema do jantar dos filósofos são: garantir que, no máximo, quatro filósofos estejam sentados à mesa, simultaneamente; garantir que um filósofo só pegue um garfo se o outro estiver disponível; usar uma solução assimétrica, isto é, garantir que um filósofo ímpar pegue primeiro o garfo da sua esquerda e, então, o da direita, enquanto um filósofo par pegue seu garfo da direita e depois o da esquerda.

Dica

Embora o jantar dos filósofos seja um dos problemas mais clássicos da literatura de programação concorrente, existem outros bastante conhecidos como o buffer limitado, leitores-gravadores, barbeiro sonolento e o jantar dos selvagens.

Sem título Text

Deadlocks

Quando um processo aguarda por um recurso que nunca lhe estará disponível ou por um evento que jamais acontecerá, diz-se que ocorreu um deadlock. Muitas vezes, um deadlock é o resultado do compartilhamento de recursos em que a exclusão mútua é necessária.

Uma situação de deadlock (ou impasse) é representada graficamente na figura 6 considerando os processos P1 e P2, além dos recursos R1 e R2. Observe que P1 obtém o acesso exclusivo a R1 e P2 o acesso exclusivo a R2. Ao longo da execução, o processo P1 solicita acesso ao recurso R2, que está sendo usado pelo processo P2. Como o acesso é exclusivo, P1 fica aguardando até que R2 seja liberado por P2. No entanto, para continuar sua execução, P2 solicita acesso ao recurso R1 que, por sua vez, está em uso por P1. Como cada processo está esperando que o outro libere o recurso alocado, ocorre um deadlock.

Para detectar um deadlock, os SOs precisam manter uma estrutura de dados para identificar os recursos do sistema, o processo que está alocando aquele recurso e os processos que aguardam pela liberação do recurso. Em geral, os algoritmos que implementam esse mecanismo verificam se há uma espera circular.

Figura 6 – Situação de deadlock entre os processos P1 e P2

[Image: Situação de deadlock entre os processos P1 e P2]

Sem título TextEditor

Fonte: Elaboração do autor.

O sistema deve utilizar critérios de escalonamento justos para garantir que todos os processos tenham a oportunidade de ser executados, evitando assim uma espera indefinida (ou bastante demorada) e proporcionando uma distribuição equitativa de recursos.

Exercícios de fixação

Q: Um processo I/O-bound é aquele que:
- Depende fortemente de operações de entrada/saída. (correct)
- Executa, principalmente, operações aritméticas no processador.
- Prioriza o uso de múltiplos núcleos da CPU.
- Evita o uso excessivo de operações de leitura/escrita.

Q: Quando um processo é criado, algumas informações comumente registradas são: 1) número de identificação do processo, 2) identificação do usuário criador do processo e 3) prioridade do processo em relação a outros processos.

Sobre esta afirmação, podemos concluir que ela é:
- Verdadeira. (correct)
- Falsa.

Q: (DECEA, Analista de Sistemas, 2006) No contexto de sistemas operacionais, uma região (ou seção) crítica é a:
- Parte do programa que contém dados compartilhados. (correct)
- Área da memória que contém dados compartilhados.
- Área do programa que é executada em 80% do tempo.
- Área do SO que contém o código loader.

Feedback (0 to 33%): Pode melhorar
Feedback (34 to 66%): Bom
Feedback (67 to 100%): Ótimo

Sem título Text

Conclusão

Nesta unidade, exploramos os elementos que estão relacionados ao conceito de processos. Comentamos sobre o conceito de processos e subprocessos, bem como a diferenciação entre CPU-bound e I/O-bound.

Destacamos que os processos passam por diferentes estados, tais como “em execução”, pronto e espera. Além disso, falamos sobre as transições existentes entre esses três estados. Abordamos ainda a dinâmica dos processos chamados foreground e os  processos background.

Estudamos também que a região crítica é um trecho do código que exige estratégias, como a exclusão mútua, para garantir a integridade dos dados. Para resolver esse problema, algumas soluções de hardware e de software podem ser utilizadas para garantir a sincronização dos acessos concorrentes.

Falamos também sobre os deadlocks, que são as situações em que processos ficam bloqueados devido aos impasses gerados pela espera. A prevenção e a detecção de deadlocks são pontos importantes que devem ser considerados para manter a estabilidade dos sistemas.

Glossário

Este glossário oferece uma visão geral dos conceitos fundamentais abordados nos tópicos mencionados. É uma ferramenta útil para quem busca uma rápida referência ou revisão desses conceitos.

Deadlock: é uma situação em que um processo aguarda por um recurso que nunca será liberado ou por um evento que nunca vai acontecer.

Multiprogramação: é a capacidade de uma CPU processar, simultaneamente, mais de uma tarefa.

Processo: é o ambiente no qual uma tarefa é executada.

Processo background: não interage com o usuário enquanto está sendo executado.

Processo CPU-bound: passa a maior parte do tempo no estado “pronto” ou “em execução”.

Processo foreground: interage com o usuário enquanto está sendo executado.

Processo I/O-bound: passa a maior parte do tempo no estado “em espera” porque executa várias operações de entrada/saída.

Região crítica: trecho de código no qual o processo pode executar várias operações em recursos que estão compartilhados.

Subprocesso: é um processo que está relacionado a um processo principal.

Thread: é uma sub-rotina executada, concorrentemente, com o programa que a chamou.

Referências

COFFMAN, E. G; ELPHICK, M; SHOSHANI, A. System Deadlocks. ACM Computing Surveys, v. 3, p. 67-78, 1971.

DIJKSTRA, E. W. Over de sequentialiteit van procesbeschrijvingen (On the nature of sequential processes). EW Dijkstra Archive (EWD-35). Center for American History, University of Texas at Austin (Translation by Martien van der Burgt and Heather Lawrence), 1972. Disponível em: https://www.cs.utexas.edu/users/EWD/ewd00xx/EWD35.PDF. Acessado em: 17 dez. 2023.

LAMPORT, L. A new solution of Dijkstra’s concurrent programming problem. Association for Computing Machinery, New York, v. 17, 8, p. 453-455, 1974.

PER HANSEN, Brinch. A comparison of two synchronizing concepts. Acta Informatica, v. 1, p. 190-199, 1972.

PETERSON, Gary L.. Myths about the mutual exclusion problem. Information Processing Letters, Amsterdã, v. 12, n. 3, p. 115-116, 1981.

MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de sistemas operacionais. Rio de Janeiro: Ed. LTC, 2004.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Sistemas operacionais com Java. 7. ed. Rio de Janeiro: Ed. Campus, 2008.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Fundamentos de Sistemas operacionais: princípios básicos. Rio de Janeiro: Ed. LTC, 2013.

TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 3. ed. São Paulo: Ed. Pearson Prentice Hall, 2009.

Capítudo 3 - Escalonamento de Processos e Gerência de Memória

Sem título Text

Objetivo da Unidade

Olá, cursista, beleza?!

Estudaremos um mecanismo essencial para que você compreenda como os SOs “orquestram” os processos de modo que a CPU execute-os de forma justa. Nosso estudo também abordará o conceito de escalonamento de processos e as políticas de preempção e de não preempção.

Existem vários algoritmos que são utilizados para o escalonamento de processos como FIFO, SJF, cooperativo, circular, por prioridades, circular por prioridades, por múltiplas filas e por múltiplas filas por realimentação.

Por fim, ainda nesta unidade, estudaremos outro tópico importante de SO,que é a gerência de memória. Quando entrarmos nesse conteúdo, apresentaremos quatro abordagens que definem como as aplicações serão armazenadas em memória. São elas: alocação contígua simples, alocação particionada estática, alocação particionada dinâmica e a técnica de swapping.

É isso! Vamos nessa?

Escalonamento de Processos

Nos primeiros sistemas, nos quais era comum a existência de uma única CPU, só era possível a execução de um único processo por vez. Portanto, qualquer outro processo que precisasse ser executado, deveria aguardar a conclusão daquele que estava sendo processado no momento.

Todavia, como já vimos anteriormente, os sistemas multitarefas permitem que vários processos sejam executados simultaneamente a fim de garantir que o uso da CPU será sempre otimizado. Quando um processo precisa esperar por algo, o SO desaloca a CPU desse processo e realoca-a para outro. Isso ocorre repetidamente e, por isso, o escalonamento é um elemento fundamental para coordenar a complexidade das operações executadas em um sistema multitarefas.

No contexto dos SOs, dizemos que escalonamento (ou scheduling) é um método que define a ordem de execução dos processos concorrentes. Assim, o escalonador (ou scheduler) de processos é responsável por tomar essa decisão, utilizando diferentes algoritmos para otimizar o desempenho do sistema.

Lembre-se

Em um ambiente multitarefa, a comunicação entre processos em execução é frequente. Portanto, ressalta-se a necessidade de estratégias de escalonamento eficazes para otimizar as execuções e garantir uma utilização eficiente da CPU.

Sem título TextEditor

As políticas de escalonamento podem ser classificadas de acordo com a possibilidade de o SO ser interrompido (ou não) enquanto executa um processo para substituí-lo por outro. Dessa forma, um escalonamento pode ser classificado como não-preemptivo ou preemptivo.

No escalonamento não-preemptivo, quando um processo está em execução, nenhum evento externo pode ocasionar a perda de uso da CPU. Por outro lado, no escalonamento preemptivo, o SO pode interromper a execução de um processo e passá-lo para o estado de pronto e trocá-lo por outro.

A seguir, estudaremos os principais algoritmos de escalonamento de processos e cada um deles possui características específicas de implementação.

Dica

Atualmente, a maioria dos SOs implementam políticas preemptivas a fim de garantir os critérios de escalonamento apresentados anteriormente.

Sem título Text

Escalonamento First-In-First-Out (FIFO)

No escalonamento “primeiro a entrar, primeiro a sair” (FIFO), como o nome sugere, o primeiro processo que chegar ao estado “pronto” será selecionado para ser executado, como se vê na Figura 1.

O algoritmo de escalonamento é simples e implementa uma fila na qual processos que mudam para o estado “pronto” são posicionados ao seu final. Quando chegam no seu início, esses processos são escalonados para execução.

Figura 1 – Escalonamento FIFO

[Image: Escalonamento FIFO]

Sem título TextEditor

Fonte: Machado e Maia (2004)

Esse algoritmo também é conhecido como First-Come-First-Served (“primeiro a chegar, primeiro a sair”, FCFS). Uma de suas desvantagens é que o tempo médio de espera pode ser longo.

Escalonamento Shortest-Job-First (SJF)

O algoritmo de escalonamento “tarefa mais curta primeiro” seleciona o processo que tiver o menor tempo de CPU que ainda será executado. Assim, o processo que estiver no estado “pronto” e precisar do menor tempo de CPU para concluir sua tarefa será selecionado. O algoritmo também é conhecido como Shortest-Process-Next (“menor processo é o próximo”, SPN)

Escalonamento Cooperativo

Em um sistema que implementa o escalonamento cooperativo, um processo é executado até que ele mesmo decida liberar a CPU. Por esse motivo, uma desvantagem é que, se um processo não cooperar de forma adequada, ele pode monopolizar a CPU e, assim, prejudicar o desempenho do sistema como um todo.

Escalonamento Round Robin

O escalonamento round robin (circular) é do tipo preemptivo e foi projetado para ser executado em sistemas de tempo compartilhado. Esse algoritmo tem algumas semelhanças com o FIFO, porém, quando um processo passa para o estado “em execução”, é inicializada a contagem de tempo do uso contínuo da CPU, chamado fatia de tempo (time-slice) ou quantum. O algoritmo de escalonamento é apresentado de forma abstrata por Machado e Maia (2004) na Figura 2.

Figura 2 – Escalonamento Circular

[Image: Escalonamento Circular (Round Robin)]

Sem título TextEditor

Fonte: Machado e Maia (2004)

Escalonamento por Prioridades

Esse algoritmo também é do tipo preemptivo e é realizado considerando um valor associado a cada processo, chamado prioridade de execução. O processo que estiver com um maior valor de prioridade no estado “pronto” é sempre escolhido para execução. Já os processos com prioridade iguais são escalonados de acordo com o algoritmo FIFO.

Figura 3 – Escalonamento por Prioridades.

[Image: Escalonamento por Prioridades]

Sem título TextEditor

Fonte: Machado e Maia (2004)

Escalonamento Circular com Prioridades

Como o nome sugere, este algoritmo combina elementos do escalonamento circular (round robin) com o escalonamento por prioridades. A abordagem tem como objetivo fornecer um equilíbrio entre uma alocação justa de tempo de uso da CPU e a capacidade de dar preferência a processos com maior prioridade.

Sem título Emphasis Card

É uma boa prática que administradores de sistemas atribuam aos processos I/O-bound valores de prioridades maiores que os CPU-bound.  Essa política permitirá que o SO compense o tempo de uso do processador de forma mais igualitária.

Sem título TextEditor

Escalonamento por Múltiplas Filas

Nesse modelo de escalonamento, os processos no estado “pronto” são colocados em diferentes filas. Cada uma delas possui um mecanismo próprio e, assim, alguns processos são escalonados pelo algoritmo FIFO e outros pelo algoritmo de escalonamento circular.

Escalonamento por Múltiplas Filas com Realimentação

Esse algoritmo é semelhante ao escalonamento por múltiplas filas, mas a sua principal vantagem é permitir que, de forma dinâmica, o SO identifique o comportamento dos processos. Assim, caso um determinado processo mude de comportamento no decorrer do tempo, ele poderá ser realocado em uma nova fila.

Lembre-se

A escolha correta do algoritmo de escalonamento contribui para a eficiência global do sistema, melhorando a taxa de utilização da CPU, reduzindo o tempo de resposta e garantindo uma distribuição equitativa dos recursos.

Sem título Text

Gerência de Memória

Bom, agora vamos mudar um pouco de assunto e falar sobre a memória principal. Em um sistema de computação, geralmente a memória principal (ou RAM) é considerada um recurso caro e escasso.

Na configuração de um computador, você já percebeu que a capacidade de armazenamento dos dispositivos de memória secundária é sempre maior que a capacidade de armazenamento da memória principal? E sobre o preço, já percebeu que o dos dispositivos de memória secundária é sempre mais barato que o da memória principal?

A Figura 4 é o resultado de uma busca que eu acabei de fazer por “SSD preço” e “memória RAM preço”. Observe que o SSD (um dispositivo de memória secundária) com capacidade de armazenamento de 256 GB custa R$84,99, ao passo que um pente de memória RAM com capacidade de 16 GB custa R$ 428,76. Avalie que, proporcionalmente, a quantidade de memória principal é mais escassa e muito mais cara que a memória secundária. Uma conta rápida mostra que cada  GB de memória RAM custa R$ 26,79, enquanto para a memória secundária, o GB custa apenas R$ 0,33.

Figura 4 – Comparativo de preço e de capacidade de armazenamento entre memórias principal e secundária.

[Image: Comparativo de preço e de capacidade de armazenamento entre memórias principal e secundária7]

Sem título Text

Fonte: Elebaoração do autor.

Então, por causa da escassez e do alto custo, é prudente que o sistema operacional implemente mecanismos que possam gerenciar a maximização do número de usuários correntes, bem como de aplicações que utilizam a memória principal.

O papel da gerência de memória é manter o maior número de processos correntes na memória principal e maximizar o compartilhamento da CPU e dos outros recursos do sistema.

Alocação Contígua Simples

Esse tipo de alocação foi desenvolvido para os primeiros SOs. Nesse tipo de alocação, a memória principal é dividida em duas partes: uma para o SO e outra para as aplicações de usuários, como se vê na Figura 5.

Figura 5 – Alocação contígua simples.

[Image: Alocação contígua simples]

Sem título Text

Fonte: Adaptada de Machado e Maia (2004)

Alocação Particionada Estática

Nesse tipo de alocação, a memória é dividida em fatias de tamanho fixo, chamadas de partições. Na inicialização do sistema, o tamanho de cada partição é definido em função do tamanho da aplicação que será executada. Para entender melhor como estão organizadas essas partições, observe a Figura 6.

Figura 6 – Alocação particionada estática

[Image: Alocação particionada estática]

Sem título TextEditor

Fonte: Machado e Maia (2004)

No modelo inicial desse tipo de partição, o SO já define em quais partições as aplicações serão executadas. Se, por exemplo, A e B estiverem sendo executadas e a Partição 3 estiver livre, C e E não poderão ser executadas porque foi definido que C seria executada na Partição 1 e E na partição 2, conforme figura 7. Esse tipo de gerência de memória é chamado alocação particionada estática absoluta.

Na alocação particionada estática relocável, quando a aplicação é carregada, o SO calcula os endereços a partir da posição inicial onde a aplicação foi alocada. No caso do exemplo apresentado na Figura 7, um sistema que utiliza esse tipo de alocação particionada estática relocável, caso A e B terminassem, a aplicação E poderia ser executada em qualquer uma das duas partições. Veja a figura 8.

Figura 7 – Alocação particionada estática absoluta

[Image: Alocação particionada estática absoluta]

Sem título TextEditor

Fonte: Machado e Maia (2004)

Na alocação particionada estática realocável, quando a aplicação é carregada o SO calcula os endereços a partir da posição inicial onde a aplicação foi alocada. No caso do expemplo apresentado na figura 7, um sistema que utiliza esse tipo de alocação particionada estática realocável, caso A e caso B terminassem, a aplicação E poderia ser executada em qualquer uma das duas partições. Veja a figura 8.

Sem título TextEditor

Figura 8 – Alocação particionada estática relocável

[Image: Alocação particionada estática relocável]

Sem título TextEditor

Fonte: Machado e Maia (2004)

Sem título Text

Alocação Particionada Dinâmica

Nesse tipo de alocação, o conceito de partições fixas foi desconsiderado. Portanto, nesse esquema, cada aplicação utiliza o espaço necessário para sua execução e, assim, torna essa área a sua partição, conforme a Figura 9.

Figura 9 – Alocação particionada dinâmica.

Sem título TextEditor

Fonte: Machado e Maia (2004)

Sem título Text

Swapping

Swapping é uma técnica utilizada para lidar com a limitação física da memória RAM disponível no sistema de computação. Quando a quantidade de espaço necessário para executar os processos excede a capacidade da memória RAM, o SO utiliza a técnica para transferir, temporariamente, o conteúdo da memória RAM para a memória secundária (por exemplo, HD ou SSD).

O SO escolhe um processo residente na RAM e o transfere para a memória secundária (swap out). Posteriormente, o sistema recarrega o processo da memória secundária para a memória principal (swap in). A execução continua normalmente, como se nada tivesse ocorrido. Acompanhe o fluxo da técnica na Figura 10.

Figura 10 – Técnica swapping

Sem título Image Slider

Técnica swapping

Sem título Image Slide

Sem título TextEditor

Fonte: Machado e Maia (2004)

Para fixar melhor o assunto, assista o vídeo a seguir.

Exercícios de fixação

Q: (IGEPREV, Técnico em Gestão de Informática, 2023) O escalonamento de processos é uma função crucial de um SO, que determina qual processo terá acesso à CPU em um determinado momento. Nesse contexto, qual é a diferença entre preempção e não preempção em escalonamento de processos?
- Preempção é quando o sistema operacional força um processo para liberar a CPU para executar outro processo, enquanto não preempção é quando um processo pode executar continuamente até terminar. (correct)
- Preempção é quando um processo voluntariamente renuncia à CPU, enquanto não preempção é quando a CPU é liberada somente quando o processo termina.
- Preempção é quando um processo é executado em múltiplas CPUs simultaneamente, enquanto não preempção é quando um processo é executado em apenas uma CPU.
- Preempção é quando o sistema operacional executa o escalonamento de processos com base na prioridade, enquanto não preempção é quando o escalonamento é feito de forma aleatória.

Q: (TRT/PB, Técnico Judiciário, 2022) A estratégia de gerenciamento adotada em sistemas operacionais modernos que consiste em trazer para memória principal cada processo em sua totalidade, executá-lo por um tempo e então colocá-lo de volta no disco é denominada:
- Swapping. (correct)
- Buffering.
- Alocação estática relocável.
- Alocação dinâmica.

Feedback (0 to 50%): Pode melhorar
Feedback (51 to 100%): Ótimo

Sem título Text

Conclusão

Nesta unidade, exploramos o conceito de escalonamento de processos em SOs multiprogramáveis. Iniciamos na diferenciação entre processos preemptivos e não preemptivos e abordamos os seus diversos algoritmos como FIFO, SJF, cooperativo, circular, por prioridades, circular com prioridades, por múltiplas filas e por múltiplas filas com realimentação.

Estudamos também como o SO gerencia a memória principal. Para isso, discutimos quatro estratégias: alocação contígua simples, alocação particionada estática, alocação particionada dinâmica e swapping. Cada uma delas tem influência direta no desempenho do SO. A alocação contígua oferece simplicidade, mas pode enfrentar limitações na utilização de espaço. A alocação particionada estática fornece uma distribuição fixa de partições, enquanto a dinâmica adapta-se às necessidades em tempo de execução. Por fim, a técnica de swapping permite a gestão flexível da memória, mas pode introduzir retardo nas respostas por causa das operações de acesso à memória secundária.

Glossário

Este glossário oferece uma visão geral dos conceitos fundamentais abordados nos tópicos mencionados. É uma ferramenta útil para quem busca uma rápida referência ou revisão desses conceitos.

Escalonamento: também chamado de scheduling, é o método que define a ordem de execução dos processos.

Escalonador: também chamado de scheduler, é o responsável pelo escalonamento dos processos.

FIFO: algoritmo de escalonamento First-In-First-Out (“primeiro a entrar, primeiro a sair”).

Quantum: contagem de tempo do uso contínuo da CPU.

Round Robin: algoritmo de escalonamento circular.

SJF: algoritmo de escalonamento Shortest-Job-First (“tarefa mais curta primeiro”).

SPN: significa Shortest-Process-Next (“menor processo é o próximo”). É um outro nome dado ao algoritmo SJF.

Swapping: técnica utilizada para lidar com a limitação física da memória RAM disponível no sistema de computação.

Time-slice: o mesmo que quantum.

Referências

MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de sistemas operacionais. Ed. LTC, 2004.

MAZIERO, Carlos Alberto. Sistemas operacionais: conceitos e mecanismos. Curitiba: DINF – UTFPR, 2019. Disponível em: https://wiki.inf.ufpr.br/maziero/doku.php?id=socm:start. Acessado em 24 out. 2023.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Fundamentos de Sistemas Operacionais: princípios básicos. Ed. LTC, 2013.

TANEMBAUM, Andrew S. Sistemas Operacionais Modernos. 3. ed. São Paulo: Pearson Prentice Hall, 2009.

Capítudo 4 - Sistema de Arquivos e Gerência de Dispositivos

Sem título Text

Objetivo da Unidade

Olá, cursista, beleza?

Nesta unidade, estudaremos dois elementos fundamentais no contexto de SOs: o sistema de arquivos e a gerência de dispositivos.

No conteúdo que trata sobre o sistema de arquivos, apresentaremos aspectos fundamentais, como a natureza e a estrutura de arquivos e a hierarquia dos diretórios. Estudaremos também as configurações dos diretórios, como os modelos de nível único, de dois níveis e de árvore, que são responsáveis pela organização e pela recuperação de informações. Nós também falaremos sobre as estratégias de alocação de espaço em disco, abrangendo métodos como alocação contígua, encadeada e indexada.

Sobre o conteúdo destinado a estudar a gerência de dispositivos, examinaremos componentes-chave, como o subsistema de E/S, responsável pela comunicação entre o SO e os periféricos. Além disso, abordaremos o papel dos device drivers no processo para tradução de comandos entre o SO e os dispositivos físicos, o funcionamento do controlador de entrada/saída e a interação com diversos dispositivos de entrada/saída.

É isso! Vamos nessa?

Sistema de arquivos

As aplicações frequentemente armazenam e recuperam informações. Para gerenciar e organizar essas informações, os SOs utilizam os arquivos. Nesse cenário, o componente responsável por efetivar esse papel é chamado de sistema de arquivos.No vídeo a seguir, nós vamos falar sobre esse elemento indispensável do sistema de computação.

Sem título TextEditor

Da mesma forma que o SO precisa criar estratégias para gerenciar a memória principal, ele também necessita de uma gerência sobre a maneira como os arquivos são alocados na memória secundária. Dessa forma, é importante você lembrar das três principais técnicas de alocação: contígua, encadeada e indexada.

Dica

Embora a implementação da estrutura de diretórios de nível único seja bastante simples, no cotidiano a estrutura de diretórios em árvore é mais comum. Por exemplo, no meu notebook, os arquivos que estou usando para elaborar este material estão armazenados no seguinte caminho (path):
D:\Meu Drive\Importante\TSI\Disciplinas\FundamentosSO

Sem título Text

Proteção de acesso

Nós sabemos que os dispositivos de armazenamento são compartilhados entre diversos usuários e aplicações e, como resultado, os arquivos são suscetíveis a serem acessados a qualquer momento. Além disso, com mais frequência, estamos compartilhando nossos arquivos na nuvem. Por esse motivo, é importante que os SOs implementem mecanismos para garantir a segurança de nossos arquivos e diretórios.

Geralmente, os tipos de acesso são determinados de acordo com as operações que podem ser realizadas sobre os arquivos. São eles: somente leitura (read) – está relacionado às operações de visualização do seu conteúdo, ou mesmo de cópia do arquivo para criação de um outro; escrita (write) – está relacionado à alteração do conteúdo do arquivo; num arquivo texto, por exemplo, pode-se modificar o texto ou incluir novos caracteres; exclusão (delete) – está relacionado à operação de remoção do arquivo; e execução (execute) – está relacionado a arquivos executáveis (com extensão .EXE) ou arquivos de comando em lote (com extensão. BAT).

A maneira mais simples de controlar o acesso a um arquivo é por meio da utilização de uma senha. O procedimento é bastante simples: o usuário informa uma senha e, caso esteja correta, o sistema libera o acesso ao arquivo.

Outra forma de controlar o acesso a arquivos é por meio da criação de um grupo de usuários. O princípio consiste em associar cada usuário do sistema a um grupo e, assim, os usuários que pertencem ao mesmo grupo têm acesso aos mesmos arquivos. Nesse tipo de proteção, há três níveis de acesso: owner (proprietário) – só pode ser acessado pelo usuário que o criou; group (grupo) – só pode ser acessado pelos usuários que fazem parte do grupo do criador do arquivo; e all (todos) – qualquer usuário do sistema pode acessar.

Por fim, é possível também implementar o controle de acesso por meio de uma lista, chamada lista de controle de acesso (access control list, ACL), na qual são especificados os usuários e os tipos de acesso que eles podem ter. Veja o exemplo abaixo:

Sem título Table

Nome do arquivo | Usuários | Permissões
Aula4_SO.docx | procopio.professor | leitura + escrita + exclusão
Aula4_SO.docx | joao.aluno | leitura
Aula4_SO.bat | procopio.professor | execução + exclusão
Aula4_SO.bat | pedro.aluno | execução + exclusão

Sem título Text

Implementação de cache

Quando comparado à memória principal, o acesso à memória secundária é muito lento. O motivo é que as operações de entrada/saída são mais lentas que as operações realizadas na memória principal.

Então, para minimizar esse problema, muitos sistemas implementam uma técnica conhecida como buffer cache. Como ela funciona? Vamos lá:

1. O SO reserva uma área na memória onde ficam armazenados os caches de operações de entrada/saída.
2. Quando uma operação de escrita ou leitura é requisitada, o SO verifica se a informação desejada está no buffer cache.
3. Se sim: não é necessário o acesso à memória secundária. Se não: a operação de entrada/saída é executada e o buffer cache é atualizado.

Sem título TextEditor

No controle de acesso por grupo, os usuários pertencentes ao mesmo grupo têm acesso aos mesmos arquivos. Por outro lado, na implementação da lista de controle de acesso, são especificados os usuários e os tipos de acesso que eles podem ter.

Dica

Na unidade passada, falamos que a memória principal é mais escassa quando comparada à memória secundária e, como resultado, a primeira é mais cara que a segunda. Podemos destacar também que a memória cache ainda é mais escassa que a memória principal.

Sem título Text

Gerência de dispositivos

O SO desempenha um papel importante ao gerenciar os dispositivos de entrada/saída (E/S) em um sistema de computação. No que diz respeito aos dispositivos de entrada, ele gerencia a comunicação entre o hardware e as aplicações, garantindo a interpretação adequada dos dados que são recebidos. Sobre os dispositivos de saída, o SO supervisiona a alocação de recursos, sincroniza operações e fornece uma camada de abstração para que as aplicações interajam de maneira uniforme, sem se preocupar com detalhes específicos do hardware. A figura 1 apresenta as camadas que compõem a gerência dos dispositivos de E/S.

Figura 1 – Arquitetura de camadas da gerência de dispositivos

[Image: Arquitetura de camadas da gerência de dispositivos]

Sem título Text

Fonte: Machado e Maia (2004)

Subsistema de entrada/saída

O SO tem como missão tornar transparente, tanto para usuários quanto para aplicações, a execução das operações de entrada/saída (E/S). Para que as aplicações consigam manipular os periféricos de uma maneira simples, o subsistema de E/S deve ocultar a complexidade das operações para cada tipo de dispositivo da camada de sistema de arquivo ou do sistema de gerenciamento de banco de dados.

O subsistema de E/S é formado por um conjunto de rotinas, chamadas de rotinas de E/S, que possibilitam a comunicação com qualquer dispositivo conectado ao sistema de computação. A grande vantagem em se utilizar essas rotinas é que o usuário não se preocupa com os detalhes do dispositivo que está sendo acessado, como em que posição do dispositivo de armazenamento o arquivo será gravado.

Device driver

Você já deve ter ouvido algum colega seu falar, ou mesmo lido em algum fórum, as expressões “baixar o driver da impressora”, “instalar o driver da webcam”, entre outras. Não é verdade?

O device driver (ou simplesmente driver) é um software que atua como uma interface entre um dispositivo de hardware e o SO. O papel do driver é permitir que o SO se comunique com o hardware específico do dispositivo, possibilitando, assim, que as aplicações e o SO utilizem e controlem o dispositivo de maneira correta.

Como se vê na figura 2, os drivers recebem comandos gerais de acesso aos dispositivos e traduzem-nos para comandos específicos que são executados pelos controladores. Geralmente, um SO possui drivers para diferentes tipos de dispositivos:  webcam, microfone, placa de rede wireless e outros.

Devido à grande dependência entre os drivers e o núcleo do SO, os fabricantes desenvolvem diferentes drivers para um mesmo dispositivo. Quando você deseja instalar o driver de uma impressora que você acabou de comprar, por exemplo, é comum acessar a página do fabricante na Internet e encontrar algo como “Driver para Windows 11”, “Driver para Linux” ou “Driver para macOS”.

Figura 2 – Device driver.

[Image: Device driver]

Sem título Text

Fonte: Machado e Maia (2004)

Controlador de entrada/saída

Os controladores de E/S são componentes de hardware responsáveis por manipular diretamente os dispositivos de E/S. O driver se comunica com os dispositivos utilizando as funcionalidades implementadas nos controladores. Geralmente, o controlador é uma placa conectada a um slot do computador, ou mesmo implementado na placa da CPU.

Figura 3 – CPU, memória e controladores.

[Image: CPU, memória e controladores]

Sem título Text

Fonte: Machado e Maia (2004)

Dispositivos de entrada/saída

Esse tipo de dispositivo tem como papel viabilizar a comunicação entre o sistema computacional e os elementos que estão externos a ele. Os dispositivos podem ser de entrada ou de saída.

Os dispositivos de entrada possibilitam que o sistema computacional receba dados provindos de um leitor de reconhecimento facial, de um teclado, de um leitor de impressão digital, de um mouse ou de outros. Já os dispositivos de saída fazem a operação contrária, isto é, exibem dados para o meio externo. Como exemplo, podemos citar uma impressora. Um dispositivo pode ainda realizar as duas atividades, como acontece com um display touch screen.

Sistemas distribuídos

Para finalizarmos essa unidade, vamos conversar sobre uma outra arquitetura conhecida como sistemas distribuídos (SDs). Em um sistema distribuído, vários componentes de hardware ou de software, de diferentes máquinas, interagem entre si. Ao contrário dos sistemas centralizados, nos quais um único computador ou servidor controla todas as operações, os sistemas distribuídos permitem a distribuição de tarefas, de dados e de processamento entre os vários nós em uma rede.

Essa abordagem oferece benefícios como escalabilidade, confiabilidade e desempenho. Os SDs podem ser encontrados em vários contextos, por exemplo, redes de computadores ou plataformas de computação em nuvem.

No contexto de gerenciamento de dispositivos, os SDs otimizam a comunicação e a coordenação entre dispositivos espalhados em uma rede. Ao implementar os conceitos de gerenciamento de dispositivos em um ambiente distribuído, devem ser observados alguns pontos importantes, como a sincronização eficiente de informações, a garantia de consistência de dados e a gestão adaptativa dos dispositivos conectados.

Exercício de fixação

Q: (Câmara Municipal de Sorocaba/SP, Técnico em Informática, 2022) Das alternativas abaixo, qual cita apenas dispositivos de entrada?
- Microfone, teclado e mouse. (correct)
- Mouse, teclado e monitor.
- Impressora, monitor e plotter.
- Caixa de som, mouse e headphone.

Q: (Fundação Estadual de Inovação em Saúde/ES, Analista de Recursos Humanos, 2022) Impressora, teclado e monitor são, respectivamente, dispositivos de
- saída, entrada e saída. (correct)
- entrada, entrada e entrada.
- saída, saída e saída.
- entrada, entrada e saída.

Q: (PETROBRAS, Técnico em Exploração de Petróleo Jr., 2012) Um sistema operacional pode utilizar várias técnicas para fazer a gerência de alocação de espaço em disco. A técnica de alocação que organiza um arquivo como um conjunto de blocos ligados logicamente no disco, independente de sua localização física, é a alocação:
- encadeada. (correct)
- contígua.
- indexada.
- segmentada.

Q: Qual das seguintes afirmativas caracteriza corretamente um sistema distribuído?
- Facilita a colaboração entre componentes em diferentes máquinas. (correct)
- Utiliza exclusivamente algoritmos de processamento descentralizado.
- Limita-se a ambientes isolados sem interconexão.
- Minimiza a redundância de dados para otimizar o desempenho do sistema.

Feedback (0 to 33%): Pode melhorar
Feedback (34 to 66%): Bom
Feedback (67 to 100%): Ótimo

Sem título Text

Conclusão

O estudo sobre o sistema de arquivos e a gerência de dispositivos revela a complexidade e a interdependência desses elementos.

Entender como os arquivos são alocados nos dispositivos de armazenamento secundário e também como estão organizadas as hierarquias de diretórios é importante para saber como recuperar dados de uma maneira mais eficaz. As configurações de diretórios, tais como modelos de nível único, de dois níveis ou de árvore, revelam-se como estratégias importantes para otimizar a gestão da informação.

Nas seções relacionadas ao gerenciamento de dispositivos, estudamos o subsistema de E/S, o device driver, o controlador de E/S e os dispositivos de E/S. Vimos que o subsistema de E/S media a comunicação entre o SO e os periféricos, enquanto os device drivers garantem que os comandos sejam interpretados a fim de viabilizar a interação entre hardware e software.

Glossário

Este glossário oferece uma visão geral dos conceitos fundamentais abordados nos tópicos mencionados. É uma ferramenta útil para quem busca uma rápida referência ou revisão desses conceitos.

Cache: espaço de memória bastante limitado, projetado para oferecer acesso rápido às informações.

Diretório: estrutura de organização utilizada para armazenar e organizar arquivos.

Driver: software que atua como uma interface entre um dispositivo de hardware e o SO.

E/S: sigla para entrada/saída, sinônimo de I/O.

Hierarquia de diretórios: organização de um sistema de arquivos em níveis de diretórios.

I/O: sigla para input/output, sinônimo de E/S.

Referências

MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de sistemas operacionais. Rio de Janeiro: LTC, 2004.

SILBERSCHATZ, Abraham; GALVIN, Peter Baer; GAGNE, Greg. Sistemas operacionais com Java. 7.  ed. Rio de Janeiro: Campus, 2008.

Ficha catalográfica

Sem título Ficha Catalográfica

PRESIDENTE DA REPÚBLICA
Luiz Inácio Lula da Silva
MINISTRO DA EDUCAÇÃO
Camilo Sobreira de Santana
SECRETÁRIO DE EDUCAÇÃO PROFISSIONAL E TECNOLÓGICA
Getúlio Marques FerreiraFormate o texto do cabeçalho

REITOR
José Arnóbio de Araújo Filho

PRÓ-REITOR DE PESQUISA E INOVAÇÃO
Avelino Aldo de Lima Neto

CAMPUS AVANÇADO NATAL - ZONA LESTE
DIRETOR-GERAL
José Roberto Oliveira dos Santos

DIRETOR DE EDUCAÇÃO A DISTÂNCIA E TECNOLOGIA EDUCACIONAL
Wagner de Oliveira

COMITÊ EDITORIAL DA DIRETORIA DE EDUCAÇÃO A DISTÂNCIA E TECNOLOGIAS
EDUCACIONAIS - CAMPUS AVANÇADO NATAL - ZONA LESTE/IFRN

PRESIDENTE
Wagner de Oliveira

SUPLENTES
João Moreno Vilas Boas de Souza Silva
Allen Gardel Dantas de Luna
Josenildo Rufino da Costa
Leonardo dos Santos Feitoza

MEMBROS
José Roberto Oliveira dos Santos
Albérico Teixeira Canário de Souza
Glacio Gley Menezes de Souza
Wagner Ramos Campos

PUBLICAÇÃO | EQUIPE

AUTORIA
Fábio Augusto Procópio de Paiva

CAPA
Iasmin Soares do Nascimento

PROGRAMAÇÃO
Cibele Regina Barros Diniz
Gersuer Henrique Sousa de Oliveira
Matheus Mathias Rocha Lúcio de Moraes
Ramon de Sousa Vieira

REVISÃO
Maria Valeska Rocha da Silva

PRODUÇÃO
Williany Bezerra de Souza

DIAGRAMAÇÃO
Amanda da Costa Marques

IMAGENS
Amanda da Costa Marques
Kyvia Victoria de Brito Torres
Yasmin Vitoria Moreira Freire
Iasmin Soares do Nascimento

PROGRAMA DE FOMENTO
Universidade Aberta do Brasil (UAB)

Paiva, Fábio Augusto Procópio de.

              P149f Fundamentos de Sistemas operacionais. / Fábio Augusto Procópio de Paiva, -- 2024.

6 unid. ; Digital.

Livro (Comitê editorial da diretoria de educação a distância e tecnologias educacionais). Campus Zona Leste - Instituto Federal de Educação, Ciência e Tecnologia do Rio Grande do Norte, Natal (RN), 2024.

ISBN:978-65-84831-40-7

           1.Educação 2. Educação a Distância 3. Tecnologia da Informação 4. Educação Profissionalizante I. Título.

CDU: 004:451

Catalogação na publicação pelo Bibliotecário-Documentarista
Ezequiel da Costa Soares Neto CRB15/613
Biblioteca Sebastião Názaro do Nascimento (BSNN) / Campus Zona Leste - IFRN