Processo

Processo é algo que o SO cria quando põe um programa em execução. Talvez que uma analogia ajude a perceber o conceito de processo.

Quando a D. Maria pensa fazer um bolo de laranja, vai ao seu livro de receitas e tira a receita do bolo de laranja. É como se fosse ao HDD buscar o ficheiro Bolo de Laranja, que corresponde ao programa (ou receita) de como fazer um bolo de laranja. È uma simples receita, ou um programa.

Mas, quando a D. Maria começa a executar a receita, começa a usar os recursos de que dispõe na sua cozinha (tigelas, pírex, batedeiras, forno, lava louças, etc.) e o programa começa a transformar-se naquilo que é o seu objetivo, o bolo de laranja.

Pois, da receita (programa) até ao bolo, estamos precisamente no processo de confeção do bolo de laranja.

E, durante esse processo de confeção, o tipo de língua em que a receita foi escrita não importa (Português, Inglês, Mandarim, ou outras) bem como o tipo, as características, a marca ou o modelo do equipamento em que se executa. Só importam os ingredientes, as suas quantidades, a forma como se misturam e o tempo e temperatura de cozedura.

Portanto o processo é alheio à língua em que a receita foi escrita e ao equipamento em que é executada.

Resulta então a definição de processo:

O processo é aquilo que executa o objetivo de um programa. É a abstração da execução de um programa, alheia às características da máquina onde executa e à linguagem em que foi programado.

A caracterização de um processo é feita por diversos elementos, dos quais salientamos:

  • O PID (Process ID), que identifica cada processo por um número diferente.
  • Um grau de prioridade.
  • Um espaço de endereçamento.
  • Um estado, a cada momento.
  • Um utilizador.

A prioridade é definida para cada processo de acordo com a sua importância.

Mas como é que se define a importância de um processo? È pelo nome pomposo, pela posição social, pelo dinheiro, ou então como é?

Calma. Apesar de o computador ter sido criado pelo homem, as formas de comportamento e postura que caracterizam o seu inventor ainda não o afetaram. Podem estar tranquilos.

A importância de um processo tem a ver com o facto de ser desencadeado como forma de resposta a um estímulo externo, com a maior ou menor necessidade de rapidez na sua execução ou com o facto de o utilizador associado ao mesmo ter privilégios especiais.

A prioridade de um processo é inversa à sua solicitação de UCP, isto é, um programa de cálculo científico que precisa da UCP em permanência enquanto executa, tem menor grau de prioridade do que um processador de texto, que só precisa da UCP de cada vez que é premida uma tecla.

Com base nestes pressupostos, o SO atribui ao processo um grau de prioridade que vai corrigindo ao longo do tempo, de acordo com o seu comportamento.

O espaço de endereçamento é um local na memória onde o ficheiro executável (as instruções) e os dados serão colocados, espaço exclusivo do processo. Este espaço tem características próprias na forma como o seu conteúdo é designado e arrumado, mas já falaremos sobre este tema.

Um processo tem a cada momento da sua execução um estado, definido pelo conteúdo do seu espaço de endereçamento, pelo conteúdo dos registadores, do ponteiro de instruções, do ponteiro de pilha (já vamos ver o que é), do registador de estado da UCP quando executa esse processo e ainda pelos objetos do sistema com que está a interagir nesse momento (ficheiros, periféricos, etc.)

A cada processo está associado um Utilizador, a quem o SO concede os privilégios ao mesmo atribuídos no sistema de ficheiros ao ficheiro executável, de acordo com os quais pode ser influenciada a prioridade do processo e os contextos em que pode executar.

Espaço de Endereçamento

Composição do espaço de endereçamento de um processo
Figura 1

Sendo os programas ficheiros, quando é necessário executar um programa é o SO que trata disso, colocando em memória esse programa, para que a UCP possa executá-lo no seu ciclo de busca e execução.

Como já vimos, a UCP só executa o que se encontra em memória, portanto, para que o processo se inicie há que definir o seu espaço de endereçamento e lá colocar o código binário executável e as diferentes estruturas de dados.

O espaço de endereçamento de um processo tem vários espaços com características próprias, conforme se representa na Figura 1 e que são:

  • Pilha (Stack)
  • Monte (Heap)
  • Dados
  • Código

Os dados são a zona do espaço de endereçamento onde são colocados os dados influentes no programa e pelo mesmo definidos, como constantes e variáveis globais, por exemplo.

O código, também designado por texto, é a zona onde é colocado o código binário correspondente ao ficheiro executável do programa.

A Pilha

A pilha (stack) é o local do espaço de endereçamento onde são empilhados (como o nome indica) dados que o processo vai buscar precisamente pela ordem inversa em que os coloca. Os dados são colocados usando a política LIFO, ou seja, Last In First Out. O primeiro dado a ser requerido pelo processo é sempre o último que entrou na pilha.

A origem da pilha é o seu endereço mais elevado e o seu topo o seu endereço mais baixo. A pilha carrega de cima para baixo e descarrega de baixo para cima (entenda-se no sentido decrescente e crescente de endereços).

Os dados colocados na pilha não têm endereço específico para cada um. A pilha tem um único ponteiro, o Ponteiro de Pilha (stack pointer), um registador da UCP que indica sempre à UCP o endereço do último byte da pilha referenciado. Quando a pilha está vazia o ponteiro indica o endereço da origem da pilha.

É possível ao programador utilizar a pilha, através das instruções push (empurra para a pilha) e pop (tira da pilha), que se referem sempre ao topo da pilha.

  • Se uma instrução push é utilizada os dados pretendidos são escritos nos bytes abaixo da posição referenciada pelo ponteiro e o valor do endereço do ponteiro é subtraído da quantidade de bytes escritos pelos dados, ficando de novo a indicar a última posição referenciada da pilha.
  • Se uma instrução pop é utilizada, o número de bytes correspondentes aos dados pretendidos é lido a partir do endereço indicado pelo ponteiro de forma ascendente e o valor do endereço do ponteiro é acrescido da quantidade de bytes lidos, voltando a indicar a última posição da pilha referenciada.

Os dados que sobrepõem os endereços de retorno devem ser relativos a valores locais, pois estes são eliminados aquando do retorno da sub-rotina. Quaisquer variáveis que sejam escritas na pilha têm que ser sempre acedidas de forma inversa àquela em que foram escritas. Não há forma de referenciar por endereço a posição de um dado na pilha. A escrita e leitura de qualquer dado na pilha será sempre feita por referência ao seu ponteiro.

É fundamental garantir que os dados escritos na pilha no âmbito de uma sub-rotina são de lá retirados antes que o endereço de retorno dessa sub-rotina seja acedido. Se assim não for, quando o endereço de retorno da sub-rotina for lido, no seu local estará um qualquer outro valor que será assumido como o tal endereço de retorno, provocando um erro no programa e abortando a sua execução.

Figura-13-2
Figura 2 – Gráfico Exemplificativo da estrutura da pilha

A Figura 2 exemplifica a forma descrita de funcionamento da pilha. Por uma questão de facilidade admitimos que os dados a escrever teriam sempre a dimensão de uma palavra de 32 bits (4 bytes). Daí as células aparecerem sempre representadas em conjuntos de 4 bytes e os endereços saltarem de 4 em 4.

Nas células a laranja estão os endereços de retorno dos diversos níveis de sub-rotinas. Por cima desses endereços o programa colocou dados locais. Quando aparece novo endereço de sub-rotina antes do primeiro ser retirado da pilha é porque nova sub-rotina foi chamada de dentro da sub-rotina então ativa, que passou a inativa. Na figura referida temos 3 níveis de sub-rotinas, sendo a 3ª que está ativa, estando as duas primeiras inativas. Cada uma foi chamada de dentro da anterior.

Por exemplo, quando o programa chama a sub-rotina 1, o seu endereço de retorno, uma palavra de 32 bits (4 bytes) é escrito na pilha e o valor do endereço indicado pelo ponteiro é subtraído de 4 (o nº de bytes escritos) ficando a apontar para o endereço 32.544 – 4 = 32.540, o endereço do último byte referenciado, também o último byte do endereço de retorno da sub-rotina 1.

Quando o dado A é escrito, no âmbito da sub-rotina 1, 12 bytes são escritos na pilha e o endereço contido no ponteiro é subtraído de 12, ficando então a apontar para o endereço 32.528, o último byte referenciado.

Quando o dado D é escrito na pilha no âmbito da sub-rotina 2, é através de uma instrução push. No próximo pop à pilha é esse dado que será lido, ou antes, os 4 bytes que compõem o mesmo. Nessa situação o ponteiro é ajustado e passa a apontar para o final do dado C, o endereço 32.516.

Quando o ponteiro aponta para o byte com endereço 32.528, um pop à pilha lerá o dado A, se tudo estiver controlado e a correr bem, sendo portanto pedidos 12 bytes. O ponteiro será acrescido desse valor e passará a apontar para o endereço de retorno da sub-rotina 1, a posição 32.540.

Quando o programa retorna da sub-rotina 1, a pilha fica vazia e o ponteiro fica a apontar para a origem da pilha, o endereço 32.544.

Como é fácil entender, a pilha é um espaço dinâmico, que vai crescendo conforme se adensa a complexidade e o aprofundamento em sub-rotinas do programa e diminuindo quando o inverso acontece.

Vamos ver um pequeno exemplo de como a pilha pode ser utilizada num programa e a sua forma de funcionamento pode ser aproveitada para facilitar a sua execução. A conversão de um número decimal em binário, representada na Figura 3.

Figura-13-3
Figura 3 – Utilização da pilha na conversão de decimal em binário

Como sabemos, a conversão de um decimal em binário faz-se dividindo sucessivamente o decimal por dois. O resto das diferentes operações fará parte da composição do binário a encontrar. Quando o resultado for inferior a 2, o próprio resultado também fará parte dessa composição estando encontrados todos os dígitos do binário.

Mas a representação do binário é feita pela colocação por ordem inversa dos dígitos que foram encontrados. Há então que inverter a ordem dos diversos valores encontrados nas sucessivas divisões.

Não será muito mais fácil e rápido utilizarmos a pilha?

Claro que é. Basta que se faça o push dos resultados sucessivamente encontrados. Eles serão guardados na pilha de forma descendente, byte a byte (neste caso cada dado ocupa um byte) da origem para o topo. Quando fizermos o pop aos resultados que colocámos na pilha, vamos obtê-los da forma inversa por que foram escritos, pois o pop é feito de forma ascendente do topo para a origem da pilha.

Por cada pop que fizermos estamos a ler o último valor escrito na pilha. Portanto se fizermos primeiramente o push dos valores de todas as operações, ao fazermos o pop sucessivo desses valores, vamos fazê-lo do último resultado obtido para o primeiro, a ordem correta dos dígitos para a representação do binário. Já não é preciso invertê-los.

O Monte

O monte (heap) é o local do espaço de endereçamento onde os dados são colocados de forma aleatória ou amontoada. À alocação de qualquer bloco de dados no monte tem que corresponder sempre um ponteiro para o endereço de início do bloco. A alocação é feita automaticamente pelo compilador podendo no entanto em certas linguagens de alto nível, como C por exemplo, essa alocação de espaço ser feita pelo programador, que deverá sempre ter o cuidado de a libertar quando deixar de ser necessária.

O monte é uma estrutura de dados dinâmica, tendo uma dimensão variável conforme as necessidades do programa. O monte cresce em sentido oposto à pilha e ambos para dentro do espaço de endereçamento do processo, que deve ser suficiente para conter as necessidades dinâmicas de ambos. O monte é onde os dados necessários à UCP em tempo de execução são colocados.

Enquanto a linguagem C permite a alocação de espaços de memória para as suas estruturas de dados pelo programador, através de instruções específicas (malloc p.e.), outras linguagens, como o JAVA p.e., reservam na totalidade para si o manuseamento da memória, encarregando-se elas próprias de criar e libertar os espaços necessários em tempo de execução. Esta é uma questão sensível nas linguagens de programação.

Utilizadores

O SO em execução em qualquer sistema tem sempre um Utilizador associado. Os possíveis utilizadores de um Sistema são previamente definidos no SO que gere esse sistema. Certamente que o que estamos a dizer já foi verificado por qualquer um ao ligar um computador.

Pois, precisamente ao ligar o computador, o que o SO faz é a autenticação do utilizador.

Para isso o utilizador fornece-lhe um conjunto de carateres que correspondem ao nome do utilizador ou username. O SO responde-lhe com um desafio pedindo-lhe que lhe envie um outro conjunto de carateres que só ele e esse utilizador conhecem, a password. Após o procedimento de autenticação, esse utilizador ficou associado a esse sistema pelo SO.

Quando o utilizador tenta aceder a um ficheiro qualquer, um executável por exemplo, para iniciar um Processo, o SO vai proceder à autorização desse utilizador.

É no sistema de ficheiros que se definem os privilégios dos diferentes possíveis utilizadores desse sistema, bem como grupos em que se podem incluir e com quem podem partilhar informação.

Com base no tipo de permissões que são atribuídos a cada utilizador e a cada grupo, se esse utilizador estiver autorizado a executar esse ficheiro então ele fica associado ao processo resultante com os privilégios que para ele e para o seu grupo foram definidos.

Chamamos a atenção para o entendimento da diferença entre Autenticação e Autorização, dois aspetos de enorme importância em todas as questões de segurança, de que certamente mais viremos a referir.

Estados de um Processo

Um processo tem 3 possíveis estados, em função dos quais o SO toma as suas decisões:

  • Em execução, é o estado de um processo que está a utilizar a UCP.
  • Bloqueado, é o estado de um processo ao qual foi retirada a UCP por se encontrar parado a aguardar informação solicitada a componentes externas. Portanto, mesmo com direito à UCP não poderia ter qualquer evolução.
  • Executável, é o estado de um processo que está em condições de utilizar a UCP quando esta lhe for concedida.

Multiprocessamento

A nossa amiga D. Maria, achou que tinha a sua cozinha muito desocupada e, para rentabilizar o dinheiro que tinha gasto no equipamento da mesma, resolveu que ia começar a executar receitas de outras pessoas por encomenda, nos períodos em que não estivesse a fazer as suas.

Rapidamente a D. Maria percebeu que, enquanto os processos de confeção estavam no fogão ou no forno ela não estava a fazer nada (talvez croché, mas não receitas) e que podia aproveitar esse tempo para ir adiantando outras em espaços e com equipamento não ocupados. De tal forma, o próprio fogão e o forno começaram a ser muito mais utilizados.

A D. Maria estava muito satisfeita, porque percebeu que com o mesmo equipamento conseguia confecionar mais receitas, portanto produzindo mais, processando mais receitas no mesmo espaço de tempo. O croché é que se ia atrasando. Mas crise é crise e croché não enche barriga.

A D. Maria estava a multicozinhar (multiprocessar) várias receitas na sua cozinha, ou seja, estava a executar em simultâneo várias receitas na mesma cozinha.

A D. Maria era o SO da sua cozinha. A sua cozinha é a UCP e o equipamento os periféricos. Quando um processo estava em comunicação longa com um periférico (o forno por exemplo) a D. Maria retirava esse processo (a execução da receita) da cozinha, guardava-o em espera registando o estado em que se encontrava quando o retirou e colocava outra receita para processamento na cozinha com outros periféricos mais rápidos.

Quando o forno fazia “Plimm”, estava a chamar-lhe a atenção para o facto de que o processo que estava a executar nesse periférico já estava pronto e que precisava da atenção dela. Então a D. Maria suspendia a receita que estava a executar e continuava com a primeira, recomeçando-a exatamente no estado em que a tinha deixado e que tinha registado na sua memória.

Num computador, pelas mesmas razões (performance e rentabilização do hardware), mas a escalas completamente diferentes, passa-se o mesmo. Num computador há sempre vários processos em execução em simultâneo.

Ao facto de poderem estar múltiplos processos em execução em simultâneo chamamos multiprocessamento. A gestão desse multiprocessamento é uma das tarefas mais importantes e interessantes de um SO.

Mas se a UCP só executa um processo de cada vez, como é isso possível?

E é verdade. A UCP só executa, em cada instante, um determinado programa, ou antes, processo. Só que, o SO faz uma gestão eficiente da UCP e vai-lhe dando diferentes processos para executar, ou seja, vai alternando os programas que a UCP tem em execução.

Certamente já tiveram mais do que um programa a correr em simultâneo num computador. Por exemplo, um processador de texto, um programa de imagem, um programa de correio eletrónico, um programa de acesso à Internet, um programa de vídeo. E todos estão em execução ao mesmo tempo. Só falámos naqueles que somos nós a colocar em execução, porque nos bastidores, sem nos apercebermos, estão dezenas de programas em execução ao serviço do sistema, os chamados processos de sistema.

Mas na realidade, todos esses processos não estão em execução simultânea, isto é, em cada momento só um deles está em execução pela UCP. É o facto de uma UCP poder executar cerca de três mil milhões de instruções por segundo que permite ao SO num só segundo conseguir rodar tantos processos quantos necessitar pela UCP, sem que nós nos apercebamos de tal, ficando mesmo com a sensação de que todos estão a executar ao mesmo tempo.

Quando estamos a ver um vídeo em alta definição ou a jogar um dos mais modernos jogos em 3D simulado, isto continua a ser verdade, pois nos bastidores, o SO não se esqueceu que o computador precisa da sua atenção e da permanente execução de programas que garantam o seu correto funcionamento e a sua segurança. Até podemos aproveitar para ver o filme enquanto pomos o antivírus a fazer uma análise completa ao computador. E o filme corre, como se nada se passasse para além dele no computador (esta afirmação tem obviamente realidades diversas, conforme as características do sistema utilizado).

Tal como já foi referido e vamos admitir como adquirido, é o SO que tira ou atribui acesso à UCP a um processo. É ele que manda. Vamos agora entender com base em que pressupostos o SO exerce o seu poder ditatorial, analisando algumas situações que podem dar origem à comutação de processos na UCP.

Sempre que um processo entra em espera por dados que a UCP requisita ao exterior do Chip (memória, disco ou periféricos), o SO pode retirar o direito à UCP a esse processo e atribuí-lo a outro, que entretanto esteja em fila de espera.

Tal é fácil de entender quando pensarmos que um pedido ao exterior pode demorar desde 50 nanossegundos (MP), passando por 5 milissegundos (HDD) até tempo indeterminado no caso de um teclado, por exemplo.

Já repararam por acaso no tempo que demoram entre duas teclas? Parece ínfimo não é?

Ponham-se no lugar da UCP. Tendo em conta que a UCP pode executar cerca de 3 mil milhões de instruções por segundo e que premir 3 teclas por segundo é um feito de especialistas, no período entre a introdução do valor de duas teclas a UCP consegue executar mil milhões de instruções. Portanto, na perspetiva da UCP é uma eternidade. Diria a UCP: “O que eu fazia enquanto aquele tipo está parado se me dessem trabalho”.

Sempre que um processo exceder um determinado período de tempo a que se chama Quantum e que é definido pelo SO como o tempo máximo consecutivo que uma processo pode usar a UCP, o direito de acesso à UCP é-lhe retirado e atribuído a outro processo que se encontre em fila de espera.

Tal procedimento é fácil de entender pois, de contrário, seria possível um processo que estivesse a executar cálculos científicos complexos com base em dados em cache, ocupar a UCP por tempo indefinido paralisando todos os outros e consequentemente o próprio computador.

Sempre que um processo prioritário solicitar a UCP, o SO pode retirar ao processo em execução o direito a acesso à mesma e concedê-lo a esse processo. Imaginem que a UCP está a executar um programa de cálculo científico e é solicitado um acesso ao disco. O SO retira a UCP ao primeiro processo, inicia o processo de acesso ao disco e imediatamente volta a entregar a UCP ao primeiro, enquanto aguarda que a MMU lhe devolva os dados solicitados. Da mesma forma, quando é premida uma tecla, o SO retira a UCP ao processo em curso, lê o valor da tecla premida e volta a entregar a UCP ao primeiro processo.

Organização dos Sistemas Operativos

O SO está organizado em três espaços fundamentais:

  • O Núcleo, ou Kernel
  • A biblioteca de chamadas sistema.
  • Os Processos de Sistema.

E pode executar em dois modos:

  • O modo Utilizador e
  • O modo Núcleo.

O Núcleo é a zona de segurança máxima de um computador, à qual só o sistema tem acesso.

No modo utilizador, o SO só tem acesso ao espaço de endereçamento definido para o Processo que esse utilizador está a executar.

No modo Núcleo, o SO tem acesso ao seu próprio espaço de endereçamento e ao espaço de endereçamento de todos os processos, sem quaisquer restrições.

Entende-se assim porque é que o Núcleo é uma zona de exceção, pois quem conseguisse, por iniciativa própria, executar rotinas do Núcleo, teria acesso à gestão de todo o computador e poderia fazer no mesmo tudo o que quisesse.

A forma de executar as rotinas do Núcleo do SO é única e consiste nas Chamadas Sistema. E só há uma maneira de aceder às rotinas do núcleo, que é através de interrupções ou exceções, situações estas que são geridas pela própria UCP, devidamente identificadas e enviadas ao SO.

Quando é assinalada uma interrupção à UCP, a UCP muda o pino (bit) de modo de execução de Utilizador para Núcleo e envia a identificação da Interrupção ao SO, que executa a rotina correspondente a essa interrupção. Uma vez concluída e no seu retorno, o bit de modo é novamente reposto no modo Utilizador.

É a este procedimento que se dá o nome de Chamada Sistema.

As rotinas de tratamento de exceções ou interrupções não são acedíveis de outra forma, isto é, não é possível serem invocadas por nenhum utilizador, que as desconhece, bem como aos seus endereços. Só ao sistema é permitido o acesso às mesmas e da forma descrita.

Sendo assim, o que são os Processos do Sistema?

As chamadas sistema têm custos de performance, pelo que sempre que podem ser evitadas o sistema cria processos de que é dono (o seu utilizador). Isto acontece em relação a processos necessários ao funcionamento do SO, que normalmente arrancam com o Boot do sistema, ficando a partir daí sempre em execução e que não têm implicações de segurança para o SO, pelo facto de executarem externamente ao núcleo.

Estão neste caso, entre muitos outros, os indexadores do sistema de ficheiros, o sistema de autenticação, serviços de escuta de redes, etc. Se tiverem Windows no vosso computador, abram a janela do Gestor de Tarefas (Task Manager) clicando com o botão direito do rato em cima da Barra de Tarefas e escolhendo essa opção. Depois abram o tab processos e selecionem mostrar processos de todos os utilizadores.

Terão oportunidade de verificar várias coisas:

  • a quantidade de processos que estão em execução no vosso computador,
  • os processos cujo dono é o Sistema ou System e que correspondem àqueles de que agora falámos,
  • a descrição dos processos, se tiverem essa curiosidade, embora nalguns casos não entendam nada,
  • pelo processo inativo do sistema, a percentagem de utilização que estão a dar ao vosso processador.

Com este novos conceitos podemos já falar sobre as interrupções e exceções.

Como é que o SO sabe que um periférico quer comunicar com um processo ou que um processo já concluiu uma comunicação com um periférico?

Interrupções e Exceções

Tal como no caso do forno da D. Maria há um “Plimm” sonoro que a avisa de que o processo daquele periférico já estava concluído, também na UCP é acionado um “Plimm” correspondente a um sinal de interrupção (um bit), que uma vez ativado chama a atenção da UCP para esse facto.

Para isso a UCP dispõe de pinos cujo estado é definido por um bit, cada. Digamos que o estado das Interrupções é definido por um ou mais registadores, em que cada báscula, correspondente a um bit, representa o estado desse pino ou IRQ (Interrupt Request).

A alteração de estado desse bit (ativo quando 1) significa que há um pedido de Interrupção por parte do periférico ou da exceção associada a esse IRQ. Como se percebe, apesar de o SO comandar todas as operações em computador, a UCP continua a ser quem dá efetivamente as indicações para que o SO atue e em que circunstâncias.

Cada pedido de interrupção tem uma identificação específica, composta por um Byte que a identifica e que consta de uma tabela e provoca uma chamada sistema, a tal que já vimos o que significa. Compete ao SO identificar o referido IRQ e proceder em conformidade, invocando a rotina correspondente.

As mudanças de Processo na UCP também são executadas pelo mesmo método e são consequência de um determinado IRQ. A própria mudança por limitação de Quantum, também o é.

Sabem que a UCP também tem tiques?

Pois é, como foi feita pelos humanos, também lhe incluíram um tique. Em intervalos regulares, a UCP pisca os olhos e o SO está atento a isso.

O tique, que vamos chamar pelo seu nome correto, clock tick, é um intervalo correspondente ao número de ciclos de clock necessários para preencher um valor que difere entre sistemas mas que é da ordem da dezena à centena de milissegundos.

Quando o SO define o Quantum, fá-lo em número de clock ticks e quando esse valor é atingido em relação a um processo em execução, é provocada uma interrupção.

Todas as interrupções que provoquem uma comutação de processo em execução na UCP, invocam no SO uma rotina que tem o nome de Despacho, cuja função é proceder à análise da interrupção, verificar se a comutação imediata se justifica e, em caso afirmativo, proceder à referida comutação de processos na UCP.

Em caso de comutação de processos, todo o contexto de execução do processo que se encontra na UCP é guardado em memória:

  • Registadores ativos (que podem ser da ordem das dezenas, contrariamente ao que vimos na análise da UCP, em que só considerávamos um registador)
  • Ponteiro de Instruções
  • Ponteiro de Pilha
  • Registo de estado

Mas em que zona da memória?

Por uma questão de segurança, estes valores não são guardados na pilha do espaço de endereçamento do processo, mas numa pilha desse Processo criada no Núcleo do SO, onde estão resguardados de qualquer acesso indevido.

Quando o processo retorna à UCP para execução, estes valores são retirados dessa pilha e são colocados nos devidos locais da UCP, alterando assim o seu contexto de execução para o correspondente ao Processo que retorna e que continuará a executar precisamente no estado em que se encontrava.

Para a rotina de Despacho poder tomar uma decisão sobre o Processo a colocar em execução na UCP, o SO tem uma outra rotina que dá pelo nome de Escalonamento, cuja função é manter uma lista ordenada dos processos cujo estado é Executável. Essa lista é ordenada por ordem de prioridade de execução, é uma fila de espera e está a ser permanentemente atualizada pela rotina Escalonamento.

O Quantum foi criado com o intuito de limitar a concessão de UCP a um processo a um período máximo de tempo, evitando assim que um qualquer processo de utilização intensiva da UCP se apropriasse dela por tempo indeterminado, caso não houvesse uma interrupção entretanto.

No entanto, o contrário não foi também descurado, havendo o cuidado de dar mais tempo de UCP aos processos que a utilizam intensivamente. Dessa forma, o Quantum dos Processos pode ser diferente. Caso assim seja, será maior para os processos com menos prioridade (com uso mais intensivo da UCP) do que para os de maior prioridade (com uso menos intensivo da UCP).

Para além deste procedimento, a rotina de Despacho tem também a possibilidade de, na sua análise antes de proceder à comutação de Processos, decidir sobre a possibilidade de não o fazer de imediato e conceder mais tempo de UCP ao Processo em execução, de acordo com a percentagem do Quantum desse Processo executada.

Como podemos verificar, há uma permanente interação entre o SO e o hardware, neste caso a UCP, que continua a ser o comandante das operações mas submetida aos critérios do SO. Isso implica que o SO identifique e conheça perfeitamente a UCP do sistema que está a gerir.

A gestão de interrupções e exceções e a comutação de Processo é uma das funções mais importantes e mais complexas do SO, pelo que daria para muita escrita. Pensamos que já referimos o essencial para transmitir o conhecimento das formas essenciais de execução dessa funcionalidade do SO.

Não queremos ir mais adiante, pois além de não ser esse o objetivo deste trabalho, arriscaríamos gerar enorme confusão nesta fase.