Organizacao de Escalonadores de Processo

Fazer download em pdf ou txt
Fazer download em pdf ou txt
Você está na página 1de 126

UNIVERSIDADE ESTADUAL PAULISTA “JÚLIO DE MESQUITA FILHO” 

FACULDADE DE CIÊNCIAS ‐ CAMPUS DE BAURU 

BACHARELADO EM SISTEMAS DE INFORMAÇÃO 

SISTEMAS OPERACIONAIS I 

CARLOS EDUARDO CIRILO 

DANILO BALZAQUE SILVEIRA NETTO JÚNIOR 

JORGE HENRIQUE DE BARROS ASSUMPÇÃO 

Organização de Escalonadores de Processo 

Bauru 

2007 
CARLOS EDUARDO CIRILO 

DANILO BALZAQUE SILVEIRA NETTO JÚNIOR 

JORGE HENRIQUE DE BARROS ASSUMPÇÃO 

Organização de Escalonadores de Processo 

 
Monografia    apresentada  à  disciplina  Sistemas 
Operacionais I do curso de Bacharelado em Sistemas de 
 
Informação da Faculdade de Ciências – campus de Bauru 
–  da  Universidade  Estadual  Paulista  “Júlio  de  Mesquita 
 
Filho”.
 

Bauru 

2007 
 

“Se um homem tem um talento e não tem capacidade de usá‐lo, ele fracassou. Se ele 
tem um talento e usa somente a metade deste, ele fracassou parcialmente. Se ele tem 
um  talento  e  de  certa  forma  aprende  a  usá‐lo  em  sua  totalidade,  ele  triunfou 
gloriosamente e obteve uma satisfação e um triunfo que poucos homens conhecerão“. 

Thomas Wolfe 

 
RESUMO 

O  escalonamento  de  UCP  é  a  base  dos  sistemas  operacionais  multiprogramados.  Ao 


alternar  a  UCP  entre  os  processos,  o  sistema  operacional  pode  tornar  o  computador 
produtivo. Quando um sistema pode escolher os processos que executa, deve adotar 
uma estratégia ‐ denominada política de escalonamento de processador – para decidir 
quais  processos  executar  em  determinado  instante.  Uma  política  de  escalonamento 
deve tentar satisfazer alguns critérios de desempenho, como maximizar o número de 
processos que terminam por unidade de tempo (rendimento), minimizar o tempo que 
cada  processo  espera  antes  de  executar  (latência),  evitar  adiamento  indefinido  de 
processos,  assegurar  que  cada  processo  conclua  antes  de  seu  prazo estabelecido, ou 
maximizar  a  utilização  do  processador.  Alguns  desses  objetivos  são  complementares, 
outros  conflitam  entre  si.  O  escalonamento  é  uma  função  fundamental  do  sistema 
operacional. Quase todos os recursos do computador são escalonados antes do uso. A 
UCP, é claro, é um dos principais recursos do computador. Assim, o escalonamento é 
central ao projeto de sistemas operacionais.   
LISTA DE FIGURAS 

Figura 1.1.  Bloco de controle de processo   15 

Figura 1.2.  Transições de estado de processos                17 

Figura 1.3.   Estados de um processo e seus disparadores            18 

Figura 1.4.   SO estruturado por processos                19 

Figura 1.5.   Modelo de multiprogramação                20 

Figura 1.6.   Seqüência de troca de surtos de UCP e E/S              20 

Figura 1.7.   Surtos de uso da UCP                   21 

Figura 1.8.   Histograma das durações de surto de UCP              22 

Figura 1.9.   A fila de processos prontos e várias filas de dispositivos de E/S        26 

Figura 1.10.   Repres. do diagrama de filas do escalonamento de processos        27 

Figura 1.11.   Níveis de escalonamento                    28 

Figura 1.12.   Diagrama de filas com o escalonamento de nível intermediário        29 

Figura 2.1.   Escalonamento primeiro a entrar primeiro a sair             40 

Figura 2.2.   Previsão da duração do próximo surto de UCP                 45 

Figura 2.3.   Escalonamento em três níveis                49 

Figura 2.4.   Utilização da UCP como uma função do num. de proc. na memória  50 

Figura 2.5.   Escalonamento Round Robin                 52 

Figura 2.6.   Agendamento Round Robin                  52 

Figura 2.7.    Aumento  das trocas de contexto                57 

Figura 2.8.   Variação do tempo de retorno                57 

Figura 2.9.   Escalonamento por prioridades                   58 

Figura 2.10.  Algoritmo de escalonamento com quatro classes de prioridade       61 

Figura 2.11.   Escalonamento por múltiplas filas                64 

Figura 2.12.   Escalonamento por múltiplas filas de realimentação            67 

Figura 2.13. Escalonador de processo‐padrão do Unix              75 
Figura 2.14.   Escalonador por fração justa                 76 

Figura 2.15.   Latência de dispatch                    82 

Figura 2.16.   Processos e Threads                    85 

Figura 2.17.   Escalonamento no Solaris 2                  86 

Figura 2.18.   Escalonamento de thread Java por prioridade            87 

Figura 2.19.   Avaliação dos escalonadores de UCP por simulação            93 

Figura 3.1.   As camadas em um sistema Unix                95 

Figura 3.2.   Algumas chamadas ao sistema relacionadas com processos        96 

Figura 3.3.   O escalonador do Unix                   98 

Figura 3.4.   O Minix é estruturado em quatro camadas             101 

Figura 3.5.   O escalonador no Minix                 102 

Figura 3.6.   Definição das matrizes rdy_head e rdy_tail             104 

Figura 3.7.   Código de escalonamento no Minix               106 

Figura 3.8.   Diagrama de transição de estado de thread            119 

   
LISTA DE TABELAS 

Tabela 2.1  Duração de surtos da UCP, em milissegundos              41 

Tabela 2.2   Duração de surtos da UCP, em milissegundos              43 

Tabela 2.3   Dur. de surtos da UCP em ms e instantes de chegada de proc.          47 

Tabela 2.4   Duração de surtos da UCP, em milissegundos              55 

Tabela 2.5   Duração de surtos da UCP, em milissegundos e prioridades          59 

Tabela 2.6   Duração de surtos da UCP, em milissegundos               89 

   
 

LISTA DE SIGLAS 

BCP  Bloco de Controle de Processo 

E/S  Entrada/Saída 

FCFS  First In First Serv (Primeiro a Entrar Primeiro a Ser Servido) 

FIFO  First In First Out (Primeiro a Entrar Primeiro a Sair) 

FSS  Fair Share Scheduling (Escalonamento por Fração Justa) 

HRRN  Highest Response Ratio Next (Próxima Taxa de Retorno Mais Alta) 

I/O  Input/Output 

PEB  Process Enviroment Block (Bloco de Ambiente de Processo) 

RR  Round Robin (Alternância Circular) 

SJF  Shortest Job First (Job Mais Curto Primeiro) 

SPN  Shortest Process Next (Próximo Processo Mais Curto) 

SRT  Shortest Remaining Time (Menor Tempo de Execução Restante) 

SO  Sistema Operacional 

TEB  Thread Enviroment Block (Bloco de Ambiente de Thread) 

TLS  Thread Local Storage (Armazenamento Local do Thread) 

UCP  Unidade Central de Processamento 

   
SUMÁRIO 

 
INTRODUÇÃO .............................................................................................................................. 11 
1. O ESCALONAMENTO DE PROCESSOS ...................................................................................... 13 
1.1 Breve Histórico .................................................................................................................. 13 
1.2 O Processo: conceito, definições, estados e comportamento .......................................... 14 
1.3 Quando escalonar ............................................................................................................. 23 
1.4 Escalonamento preemptivo versus escalonamento não preemptivo .............................. 24 
1.5 Filas de escalonamento ..................................................................................................... 25 
1.6 Níveis de Escalonamento .................................................................................................. 27 
1.7 Prioridades ........................................................................................................................ 31 
1.8 Trocas de contexto ............................................................................................................ 32 
2. ALGORITMOS DE ESCALONAMENTO ....................................................................................... 33 
2.1 Categorias de algoritmos de escalonamento .................................................................... 33 
2.2 Objetivos do Escalonamento ............................................................................................. 34 
2.3 Critérios de Escalonamento .............................................................................................. 36 
2.4 Escalonamento em Sistemas em Lote ............................................................................... 39 
2.4.1 Escalonamento primeiro a entrar primeiro a sair (FIFO) ........................................... 39 
2.4.2 Escalonamento por job mais curto primeiro (SJF) ..................................................... 42 
2.4.3 Escalonamento por próxima taxa de resposta mais alta (HRRN)............................... 46 
2.4.4 Escalonamento por menor tempo de execução restante (SRT) ................................ 47 
2.4.5 Escalonamento em três níveis .................................................................................... 48 
2.5 Escalonamento em sistemas interativos ........................................................................... 51 
2.5.1 Escalonamento Round Robin ..................................................................................... 51 
2.5.2 Escalonamento por Prioridades ................................................................................. 58 
2.5.3 Escalonamento por Múltiplas Filas ............................................................................ 63 
2.5.4 Escalonamento por múltiplas filas com realimentação ............................................. 66 
2.5.5 Próximo processo mais curto (shortest process next ‐ SPN) ...................................... 71 
2.5.6 Escolamento Garantido .............................................................................................. 71 
2.5.7 Escalonamento por Loteria ........................................................................................ 72 
2.5.8 Escalonamento por Fração Justa (fair share scheduling ‐ FSS) .................................. 73 
2.6 Escalonamento em sistemas de tempo real ..................................................................... 77 
2.6.1 Escalonamento por prazo .......................................................................................... 77 
2.6.2 Escalonamento de Tempo Real .................................................................................. 78 
2.6.3 Algoritmos de escalonamento de tempo real estáticos ............................................ 83 
2.6.4 Algoritmos de escalonamento de tempo real dinâmicos .......................................... 84 
2.7 Escalonamento de threads ................................................................................................ 85 
2.8 Escalonamento de Multiprocessadores ............................................................................ 87 
2.9 Política versus Mecanismo ................................................................................................ 88 
2.10 Avaliação de Algoritmos .................................................................................................. 89 
2.10.1 Modelagem determinista ......................................................................................... 89 
2.10.2 Modelo de filas ......................................................................................................... 91 
2.10.3 Simulações ................................................................................................................ 92 
2.10.4 Implementação ........................................................................................................ 93 
3. ESTUDOS DE CASO .................................................................................................................. 95 
3.1 Escalonamento no UNIX .................................................................................................... 95 
3.2 Escalonamento no Minix ................................................................................................. 100 
3.2.1 Código e comentários .............................................................................................. 103 
3.3 Escalonamento no Windows XP ...................................................................................... 116 
3.3.1 Organização de processos e trheads ........................................................................ 116 
3.3.2 Escalonamento de threads ....................................................................................... 118 
3.3.3 Estados de threads ................................................................................................... 119 
3.3.4 Algoritmo de escalonamento de thread .................................................................. 120 
3.3.5 Determinação de prioridades de threads ................................................................ 121 
3.3.6 Escalonamento em multiprocessadores .................................................................. 123 
CONCLUSÕES ............................................................................................................................. 125 
REFERÊNCIAS ............................................................................................................................. 126 
 

   
INTRODUÇÃO 
Sem  software,  um  computador  é  basicamente  um  inútil  amontoado  de  metal.  Com 
software,  um  computador  pode  armazenar,  processar  e  recuperar  informações,  exibir 
documentos  multimídia,  pesquisar  na  internet  e  envolver‐se  em  muitas  outras  importantes 
atividades que justificam o seu valor (TANENBAUM; WOODHULL, 2000, p. 17). O software de 
computador  pode  ser  dividido,  grosso  modo,  em  dois  tipos  principais:  software  de  sistema, 
conjunto  de  programas  generalizados  que  gerenciam  os  recursos  do  computador,  como 
processador  central,  as  conexões  de  comunicação  e  os  dispositivos  periféricos;  e  software 
aplicativo,  programas  que  são  escritos  para  ou  pelos  usuários  para  designar  uma  tarefa 
específica ao computador que o usuário realmente deseja (LAUDON, J.; LAUDON, K., 2003, p. 
196‐197). O software de sistema mais fundamental é o sistema operacional (SO), que controla 
todos  os  recursos  do  computador  e  fornece  a  base  sobre  a  qual  os  programas  aplicativos 
podem ser escritos (TANENBAUM; WOODHULL, 2000, p. 17). 

Os primeiros sistemas de computação só permitiam que um programa fosse executado 
de cada vez. Esse programa tinha controle completo do sistema e acesso a todos os recursos 
do sistema (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 63). Os computadores modernos 
são  capazes  de  fazer  várias  coisas  ao  mesmo  tempo,  permitindo  que  múltiplos  programas 
sejam  carregados  na  memória  e  executados  de  forma  concorrente.  Enquanto  executa  um 
programa de usuário, um computador pode também ler os dados de um disco e mostrar um 
texto na tela ou enviá‐lo para uma impressora. É comum um computador de mesa (desktop) 
compilar  um  programa,  enviar  um  arquivo  a  um  impressora,  exibir  uma  página  Web, 
apresentar um videoclipe digital e receber mensagens de correio eletrônico concorrentemente 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 66; TANEMBAUM, 2003, p. 53).  

Uma série de capacidades do SO habilita o computador a administrar muitas tarefas e 
usuários diferentes ao mesmo tempo. A multiprogramação permite que múltiplos programas 
compartilhem  os  recursos  de  um  sistema  computacional  ao  mesmo  tempo  por  meio  do  uso 
simultâneo  de  uma  Unidade  Central  de  Processamento  (UCP)1.  Na  verdade,  apenas  um 
programa está usando a UCP em dado momento, mas as necessidades de entrada/saída (E/S) 
de outros programas podem ser atendidos ao mesmo tempo dando aos usuários a ilusão de 
paralelismo (LAUDON, J.; LAUDON, K., 2003, p. 197‐198). Algumas vezes, nesse contexto, fala‐
se  de  pseudoparalelismo  ou  paralelismo  lógico  para  diferenciá‐lo  do  verdadeiro  paralelismo 
de  hardware  dos  sistemas  multiprocessadores,  os  quais  possuem  duas  ou  mais  UCPs  que 
compartilham simultaneamente a mesma memória física (TANEMBAUM, 2003, p. 53). Com o 
                                                            
1
 Os termos UCP e processador serão utilizados indistintamente neste trabalho. 
uso de tempo compartilhado (timesharing) o SO permite que muitos usuários compartilhem 
os recursos de processamento concomitantemente de forma que a UCP gaste um período pré‐
determinado  de  tempo  com  um  programa  antes  de  passar  para  outro.  A  cada  um  dos 
diferentes usuários é alocada uma minúscula fatia de tempo de computador em um programa; 
durante esse tempo, cada um fica livre para executar quaisquer operações requisitadas. Ao fim 
desse período, outra minúscula fatia de tempo da UCP é alocada a outro usuário. Esse arranjo 
permite  que  muitos  usuários  permaneçam  conectados  à  UCP  simultaneamente,  cada  um 
recebendo apenas uma pequena quantidade de tempo de computação (LAUDON, J.; LAUDON, 
K., 2003, p. 197‐198). 

Essa situação, onde variados programas competem pelo uso da UCP ao mesmo tempo, 
ocorre  sempre  que  dois  ou  mais  processos  estão  simultaneamente  no  estado  pronto  para 
execução.  Se  apenas  uma  UCP  estiver  disponível,  deverá  ser  adotada  uma  estratégia  – 
denominada  política  de  escalonamento  de  processador  (ou  disciplina  de  escalonamento)  – 
para  decidir  quais  processos  executar  em  determinado  instante  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES,  D.  R.,  2005,  p.  209).  A  parte  do  SO  responsável  por  essa  escolha  é  chamada  de 
escalonador  de  processos  (ou  escalador  de  processos),  e  o  algoritmo  que  ele  utiliza  para 
realizar essa tarefa é o algoritmo de escalonamento (TANEMBAUM, 2003, p. 97). 

Uma política de escalonamento deve tentar satisfazer alguns critérios de desempenho 
conforme  os  objetivos  do  sistema  a  que  está  vinculada,  como  maximizar  o  número  de 
processos  que  terminam  por  unidade  de  tempo  (rendimento),  minimizar  o  tempo  que  cada 
processo  espera  antes  de  executar  (latência),  evitar  adiamento  indefinido  de  processos 
(deadlocks),  assegurar  que  cada  processo  conclua  antes  de  seu  prazo  estabelecido,  ou 
minimizar a utilização do processador.  Alguns desses objetivos, como maximizar a utilização e 
o  rendimento  do  processador  são  complementares;  outros  conflitam  entre  si  –  um  sistema 
que  garanta  que  os  processos  terminarão  antes  de  seus  prazos  pode  não  atingir  o  maior 
rendimento possível (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 209). 

O  escalonamento  de  UCP  é  a  base  dos  sistemas  operacionais  multiprogramados.  Ao 


alternar a UCP entre os processos, o sistema operacional pode tornar o computador produtivo. 
Quase todos os recursos do computador são escalonados antes do uso. A UCP, é claro, é um 
dos  principais  recursos  do  computador.  Assim,  o  escalonamento  é  central  ao  projeto  de 
sistemas operacionais. (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 95) 

A organização dos principais algoritmos de escalonamento, bem como suas políticas e 
implicações nos sistemas são o tema central de discussão do presente trabalho.   
CAPÍTULO 1 

O ESCALONAMENTO DE PROCESSOS2 

1.1 Breve Histórico 
Entre  as  décadas  de  1950  e  meados  da  década  de  1960,  quando  os  sistemas  de 
processamento  em  lote  passaram  a  ser  utilizados  nos  computadores  de  segunda  geração,  o 
algoritmo  de  escalonamento  era  bastante  simples.  As  entradas  de  dados  eram  feitas 
basicamente  por  meio  de  fitas  magnéticas  que  continham  os  dados  transcritos  de  cartões 
perfurados. A tarefa do algoritmo era apenas executar os próximos jobs3 na seqüência em que 
apareciam na fita (TANENBAUM; WOODHULL, 2000, p. 69; TANEMBAUM, 2003, p. 97). Com o 
surgimento dos sistemas de tempo compartilhado na terceira geração de computadores, entre 
1965 e 1980, e o advento da multiprogramação, o algoritmo de escalonamento tornou‐se mais 
complexo  à  medida  em  que  vários  usuários  passaram  a  requisitar  serviços  da  UCP  de  forma 
concorrente.  Em  muitos  casos,  em  máquinas  que  mesclavam  serviços  em  lote  e  de  tempo 
compartilhado,  o  escalonador  tinha  a  responsabilidade  de  decidir  se  um  job  em  lote  ou  um 
usuário  interativo  em  um  terminal  deveria  ser  atendido.  Assim,  observando  a  escassez  de 
tempo  de  UCP  e  o  diferencial  que  o  escalonador  impactava  no  desempenho  observado  e na 
satisfação  do  usuário,  grande  enfoque  foi  dado  no  desenvolvimento  de  algoritmos  de 
escalonamento inteligentes e eficientes (TANEMBAUM, 2003, p. 97). 

A  ascensão  dos  computadores  pessoais  (PC)  a  partir  da  década  de  1980  trouxe  uma 
nova  mentalidade  no  que  diz  respeito  ao  escalonamento  de  processos.  Em  um  PC,  na  maior 
parte do tempo existe apenas um processo ativo, o que faz com que o escalonador não precise 
trabalhar  muito  para  perceber  qual  processo  executar.  Além  disso,  com  os  avanços 
tecnológicos  no  decorrer  dos  anos,  os  PCs  tornaram‐se  tão  velozes  que  dificilmente  a  UCP 
chegará a ser um recurso escasso. Na verdade, a maioria dos programas para PCs são limitados 
não  pela  taxa  na  qual  a  UCP  é  capaz  de  processá‐los,  mas  sim  pela  velocidade  com  que  o 
usuário  pode  entrar  com  os  dados  que  a  aplicação  necessita.  Logo,  observou‐se  que  o 
escalonamento não era tão importante em PCs simples (TANEMBAUM, 2003, p. 97).  

                                                            
2
  Na  literatura,  os  termos  escalonamento  de  processos  e  escalonamento  de  processador  são  usados  como 
equivalentes. 

  Neste  trabalho,  os  termos  job  e  processo  serão  utilizados  quase  que  indistintamente.  Apesar  da  tendência  de 
utilizar o termo processo, boa parte da teoria e terminologia sobre sistemas operacionais foi desenvolvida em uma 
época na qual a principal atividade dos sistemas operacionais era o processamento de jobs. Seria errôneo evitar o 
uso de termos comumente aceitos que incluem a palavra job (como escalonamento de jobs) simplesmente porque 
processo suplantou job. 
Por  outro  lado,  em  servidores  e  estações  de  trabalho  de  alto  desempenho  em  rede, 
onde  é  comum  haver  múltiplos  processos  competindo  pela  UCP,  o  escalonamento  é  crucial 
para  o  desempenho  percebido  do  sistema  como  um  todo.  Além  de  escolher  o  processo 
adequado para executar, o escalonador também deve preocupar‐se com a utilização eficiente 
da  UCP,  visto  que  as  tarefas  envolvidas  na  alternância  de  processos,  como  o  salvamento  e 
recuperação  de  contexto,  são  dispendiosas  e  se  forem  realizadas  muitas  vezes 
deliberadamente  podem  demandar  uma  grande  quantidade  de  tempo  da  UCP,  afetando  o 
desempenho geral do sistema (TANEMBAUM, 2003, p. 98). 

1.2 O Processo: conceito, definições, estados e comportamento 
Um  obstáculo  à  discussão  de  sistemas  operacionais  é  que  existe  dificuldade  em 
denominar todas as atividades da UCP. Um sistema em lote (bach) executa jobs, enquanto que 
um sistema de tempo compartilhado executa programas de usuário ou tarefas. Mesmo em um 
sistema  monousuário,  como  o  Microsoft  Windows  ou  o  Macintosh  OS,  um  usuário  pode 
executar vários programas de uma vez: um processador de textos, um navegador Web e um 
pacote de e‐mail. Mesmo se o usuário só puder executar um programa de cada vez, o sistema 
operacional  poderá  precisar  dar  suporte  a  suas  próprias  atividades  internas  programadas, 
como gerência de memória. Em muitos aspectos, todas essas atividades são semelhantes, de 
modo que podem ser todas denominadas de processos (SILBERSCHATZ, A.; GALIN, P.; GAGNE, 
G., 2000, p. 63). 

O  termo  processo  no  contexto  de  sistemas  operacionais  foi  usado  pela  primeira  vez 
pelos projetistas do sistema Multics na década de 1960 (DALEY; DENNIS, 1967 apud DEITEL, H. 
M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  66)  4.  Desde  aquela  época  o  termo  processo,  de 
certo  modo  usado  intercambiavelmente  como  tarefa,  ganhou  muitas  definições  como:  um 
programa em execução; uma atividade assíncrona; o “espírito animado” de um procedimento; 
o  “locus  de  controle”  de  um  procedimento  em  execução;  aquilo  que  é  manifestado  pela 
existência  de  uma  estrutura  de  dados  denominada  “descritor  de  processo”  ou  “bloco  de 
controle  de  processo”  (BCP)  no  sistema  operacional;  aquela  entidade  às  quais  os 
processadores  são  designados;  e  a  unidade  “de  despacho”  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 66). 

Cada  processo  é  representado  no  sistema  operacional  por  um  bloco  de  controle  de 
processo (BCP), também chamado de bloco de controle de tarefa. A figura seguinte mostra um 
BCP. 
                                                            
4
  DALEY,  R.  C.;  DENNIS,  Jack  B.  “Virtual  memory,  processes,  and  sharing  in  Multics”,  Proceedings  of  the  ACM 
Symposium on Operating System Principles, jan. 1967. 
estado do 
ponteiro 
processo 
número do processo 
contador do programa 

Registradores 

limites de memória 
lista de arquivos abertos 



 
Figura 1.1. Bloco de controle de processo 
 
O BCP contém muitas informações associadas a um processo específico, incluindo: 

• Estado do processo; 
• Contador do programa; 
• Registradores de UCP; 
• Informações de escalonamento de UCP; 
• Informações de gerência de memória; 
• Informações de contabilização; 
• Informações de status de E/S. 
O BCP atua simplesmente como um repositório de informações que podem variar de 
processo a processo (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 65). 

Os softwares de computador – inclusive, algumas vezes, o próprio sistema operacional 
‐  são  organizados  em  vários  processos  seqüenciais.  Nesse  sentido,  o  processo  é  apenas  um 
programa  em  execução  acompanhado  dos  valores  atuais  do  contador  de  programa,  dos 
registradores  e  das  variáveis  (TANEMBAUM,  2003,  p.  55).  Cada  processo  tem  seu  próprio 
espaço  de  endereço,  que  normalmente  consiste  em  uma  região  de  texto,  uma  região  de 
dados e uma região de pilha. A região de texto armazena o código que o processador executa. 
A região de dados armazena as variáveis e memória alocada dinamicamente, que o processo 
usa  durante  a  execução.  A  região  de  pilha  armazena  instruções  e  variáveis  locais  para 
chamadas  ativas  ao  procedimento.  O  conteúdo  da  pilha  cresce  à  medida  que  um  processo 
emite  chamadas  aninhadas  ao  procedimento,  e  diminui  quando  o  procedimento  chamado 
retorna  (PETERSON;  QUARTERMAN;  SILBERSCHATZ,  1985  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 67)5. 

Silberschatz, A., Galin, P.; Gagne, G. (2000, p. 64) enfatizam que um programa por si só 
não é um processo; um programa é uma entidade  passiva, como o conteúdo de um arquivo 
armazenado  em  disco,  enquanto  um  processo  é  uma  entidade  ativa,  com  um  contador  de 
programa  especificando  a  próxima  instrução  a  ser  executada  e  um  conjunto  de  recursos 
associados.  Embora  dois  processos  possam  ser  associados  ao  mesmo  programa,  são 
considerados  duas  seqüências  separadas  de  execução.  Por  exemplo,  vários  usuários  podem 
estar executando cópias diferentes do programa de correio ou o mesmo usuário pode chamar 
muitas  cópias  do  programa  editor.  Cada  uma  dessas  atividades  é  um  processos  separado  e, 
embora as seções de texto sejam equivalentes, as seções de dados variam. Também é comum 
ter um processo que produza muitos processos durante sua execução. 

Em  suma,  a  idéia  principal  é  que  um  processo  constitui  uma  atividade.  Ele  possui 
programa, entrada, saída e um estado (TANENBAUM, 2003, p. 54). Durante seu tempo de vida 
um  processo  passa  por  uma  série  de  estados  de  processo  distintos.  Vários  eventos  podem 
fazer que um processo mude de estado. Diz‐se que um processo está executando (ou seja, no 
estado de execução) se estiver executando em um processador. Diz‐se que um processo está 
pronto  (ou  seja,  em  estado  “de  pronto”)  quando  poderia  executar  em  um  processador  se 
houvesse  algum  disponível.  Diz‐se  que  um  processo  está  bloqueado  (ou  seja,  no  estado 
bloqueado)  se  estiver  esperando  que  algum  evento  aconteça  (tal  como  um  evento  de 
conclusão  de  E/S,  por  exemplo)  antes  de  poder  prosseguir  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 67). 

Em um sistema monoprocessado (ou uniprocessado), ou seja, como uma única UCP, 
apenas um processo pode ser executado por vez, mas diversos outros podem estar prontos e 
outros  ainda  bloqueados.  O  SO  mantém  uma  lista  de  prontos,  de  processos  prontos,  e  uma 
lista de bloqueados, de processos bloqueados. A lista de prontos é organizada por ordem de 
prioridade, de modo que o processo seguinte a receber o processador será o primeiro da lista 
(o  processo  de  maior  prioridade).  A  lista  de  bloqueados  é  tipicamente  desordenada  –  os 
processos  não  se  tornam  desbloqueados  (ou  seja,  prontos)  na  ordem  de  prioridade;  são 
desbloqueados na ordem em que ocorrem os eventos pelos quais estão esperando. Em alguns 

                                                            
5
 PETERSON, J. L.; QUARTERMNA, J. S.; SILBERSCHATZ, A. “4.2BSD and 4.3BSD as examples of the UNIX system”, ACM 
Computing Surveys, v. 17, nº 4, dez. 1985, p. 388. 
casoss é comum p
priorizar os processos em
m espera (DEITEL, H. M.; D
DEITEL, P. J.;; CHOFFNES, D. R., 
2005, p. 68). 

u usuário  executa  um  programa,  processos  sãão  criados  e  inseridos naa  lista 


Quando  um 
de prrontos. Um p
processo vai  passando paara o topo da lista à med
dida que outtros concluem sua 
vez  de 
d usar  a  UCP. 
U Quando  um  proceesso  chega  ao  topo  daa  lista  e  há  um  processsador 
dispo
onível, aquele processo éé designado  a um processador e diz‐se que ele ffez uma tran
nsição 
de esstado, passan do pronto paara o estado de execução
ndo do estad o, conforme iilustrado na figura 
que sse segue. 

  Figura 1.2. TTransições de estado de pro
ocessos 

O  ato  dee  designar  um  processsador  ao  prrimeiro  proccesso  da  lissta  de  pron
ntos  é 
denominado  desspacho,  e  é  realizado  por 
p uma  enttidade  do  sistema  operracional  chaamada 
escalonador  (ou  despachantte). Diz‐se  qu
ue processoss que estão  nos estadoss de pronto  ou de 
orque disputtam ativamente tempo d
ução estão acordados po
execu de processad
dor. O SO gerrencia 
transsições  de  esttado  para  melhor 
m servir  aos  processsos  no  sistem
ma.  Para  evitar  que  quaalquer 
um d
dos processo
os monopolizze o sistema, acidental o
ou maliciosamente, o sisstema operacional 
estab
belece um re
elógio de intterrupção  em
m hardware
e (também  denominado 
d temporizad
dor de 
intervvalo) que peermite que o
o processo eexecute duraante um inteervalo de tem
mpo específiico ou 
quan
ntum. Se o prrocesso não devolver o p
processador voluntariam
mente antes q
que o intervaalo de 
po  expire,  o  temporizad
temp dor  de  interrvalo  gera  uma  interrup
pção,  fazend
do  que  o  sisstema 
operaacional obtenha o controle do proceessador. Entãão o SO mud
da o estado  do processo
o, que 
estavva  anteriorm
mente  em  exxecução,  paraa  pronto  e  despacha 
d o  primeiro  pro
ocesso  da  lissta  de 
pronttos,  mudand
do  o  seu  esttado  de  pro m  execução  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
onto  para  em
CHOFFNES,  D.  R.,  2005,  p.  68).  Muitos  algoritmos  vêm  sendo  desenvolvidos  na  tentativa  de 
equilibrar  essa  competição,  que  exige  eficiência  para  o  sistema  como  um  todo  e  igualdade 
para  processos  individuais  (TANENBAUM,  2003,  p.  58).  Se  um  processo  em  execução  iniciar 
uma  operação  de  E/S  antes  do  seu  quantum  expirar  e,  conseqüentemente,  tiver  de  esperar 
que  a  operação  de  E/S  seja  concluída  antes  de  poder  usar  o  processador  novamente,  o 
processo  em  execução  entregará  voluntariamente  o  processador.  Nesse  caso,  diz‐se  que  o 
processo bloqueou a si mesmo, deixando em suspenso a conclusão da operação de E/S. Diz‐se 
que processos no estado bloqueado estão adormecidos porque não podem executar mesmo 
que  um  processador  fique  disponível  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p. 
68). 

Dessa forma, observa‐se quatro estados de transição possíveis. Quando um processo é 
despachado, ele transita de pronto para em execução (despacho). Quando o quantum de um 
processo expira, ele transita de em execução para pronto (preempção). Quando um processo é 
bloqueado,  ele  transita  de  em  execução  para  bloqueado  (bloqueio).  Por  fim,  quando  um 
processo acorda devido à conclusão de algum evento pelo qual está esperando, ele transita de 
bloqueado  para  pronto  (despertar).  Nota‐se  que  o  único  estado  de  transição  iniciado  pelo 
próprio  processo  de  usuário  é  o  bloqueio  –  as  outras  três  transições  são  disparadas  pelo 
sistema  operacional  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  69)  como 
esquematizado  na  figura  abaixo. 
 

Figura 1.3. Estados de um processo e seus disparadores   

Assume‐se,  então,  que  o  sistema  operacional  designa  um  quantum  a  cada  processo. 
Alguns  sistemas  operacionais  mais  antigos,  que  executavam  com  processadores  que  não 
dispunham  de  relógios  de  interrupção,  empregavam  multitarefa  cooperativa,  o  que  significa 
que  cada  processo  deve  devolver  voluntariamente  o  processador  no  qual  está  executando 
antes  que  outro  processo  possa  executar.  Entretanto,  multitarefa  cooperativa  é  raramente 
usada  nos  sistemas  operacionais  modernos  porque  permite  que  processos  monopolizem  o 
processador,  acidental  ou  maliciosamente,  entrando  em  laço  infinito  ou  simplesmente 
recusando‐se a entregar o processador na hora certa, por exemplo (DEITEL, H. M.; DEITEL, P. J.; 
CHOFFNES, D. R., 2005, p. 69). 

Quanto  mais  complexo  for  um  sistema  operacional,  mais  benefícios  aos  usuários  são 
esperados.  Embora  sua  principal  preocupação  seja  a  execução  de  programas  de  usuário,  ele 
também  precisa  cuidar  das  várias  tarefas  de  sistema  que  são  mais  bem  executadas  fora  do 
núcleo  (kernel)  propriamente  dito.  Um  sistema,  portanto,  consiste  em  uma  coleção  de 
processos: processos de sistema operacional que executam código do sistema e processos de 
usuário  que  executam  código  de  usuário.  Todos  esses  processos  podem  executar  ao  mesmo 
tempo,  sendo  a  UCP  (ou  UCPs)  multiplexada(s)  entre  eles  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 63). 

Essa visão dá origem ao modelo mostrado na figura seguinte. Nele, o nível mais baixo 
do  sistema  operacional  é  o  escalonador,  com  diversos  processos  acima  dele.  Todo  o 
tratamento  de  interrupção  e  detalhes  sobre  a  iniciação  e  o  bloqueio  de  processos  estão 
“ocultos” no escalonador, que, na verdade não possui muito código. O restante do SO é bem 
estruturado na forma de processos (TANENBAUM, 2003, p. 58). 

 
Figura 1.4. A camada mais inferior de um sistema operacional estruturado por processos trata as interrupções e o 
 
escalonamento. A camada superior abriga os processos seqüenciais 

O SO deve assegurar que cada processo receba uma quantidade suficiente de tempo 
de  processador.  Em  qualquer  sistema,  o  número  de  processos  verdadeiramente  executados 
em concorrência é obrigatoriamente igual ao número de processadores mas, em geral, há um 
número  muito  maior  de  processos  do  que  de  processadores  em  um  sistema.  Portanto,  a 
qualquer dado instante, alguns processos podem ser executados e outros não, de forma que a 
UCP troca, a todo momento, de um processo para outro dando a impressão de que o conjunto 
de  processos  esteja  sendo  executado  (pseudo)paralelamente  (TANENBAUM,  2003,  p.  53; 
DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 67). Esse mecanismo de trocas rápidas é 
chamado de multiprogramação e é ilustrado na figura abaixo. 

 
 

Figu  
ura 1.5. (a) Mu
ultiprogramaçção de quatro programas. (b
b) Modelo connceitual de qu
uatro processo
os seqüenciaiss 
independeentes. (c) Som
mente um proggrama está ativo a cada moomento 
 

O  objetivvo  da  multip


programação
o  é  ter  proccessos  em  execução  o  ttempo  todo,,  para 
maxim
mizar  a  utilização  da  UC po  compartillhado  é  alteernar  a  UCP  entre 
CP.  O  objetiivo  do  temp
proceessos  de  forrma  tão  freeqüente  quee  os  usuário
os  possam  in
nteragir  com
m  cada  proggrama 
duran
nte sua execução. Para u
um sistema u
uniprocessad
do, nunca haverá mais dee um processso em 
execu
ução. Se hou
uver mais pro
ocessos, os d
demais terão
o de esperar até que a UCP esteja lib
berada 
e posssa ser reescalonada (SILBERSCHATZ,, A.; GALIN, P
P.; GAGNE, G
G., 2000, p. 6
66). 

 
Figgura 1.6. Seqü
üência de trocca de surtos de UCP e E/S 
 

Quase todos os proceessos alternaam surtos de
e computaçãão com requ
uisições de E//S (de 
disco
o)  como  ilusttrado  na  figu
ura  acima.  O 
O sucesso  do
o  escalonam
mento  da  UC
CP  depende  dessa 
proprriedade  do  processo  em
m  que  sua  execução 
e u ciclo  de  processame
consiste  em  um  ento  e 
espera  por  E/S.  Os  processo  alternam  entre  esses  dois  estados.  A  execução  de  um  processo 
inicia‐se com um surto de UCP. A isso se segue um surto de E/S que, por sua vez, é seguido por 
outro surto de UCP, depois por outro de E/S e assim por diante. Por fim, o último surto de UCP 
termina  com  um  pedido  do  sistema  para  encerrar  a  execução  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 95). 

 
Figura 1.7. Surtos de uso da UCP alternam‐se com períodos de espera por E/S. (a) Um processo orientado à 
UCP. (b) Um processo orientado à E/S 
 

Em  geral,  a  UCP  executa  indefinidamente  e  então  é  feita  uma  chamada  ao  sistema 
para  a  leitura  ou  escrita  de  um  arquivo.  Após  o  término  da  chamada  ao  sistema,  a  UCP 
computa novamente até que ela requisite ou tenha de escrever mais dados e assim prossegue 
sucessivamente.  Percebe‐se  que  algumas  atividades  de  E/S  contam  como  computação  pois 
fazem  uso  da  UCP,  como  quando  a  UCP  copia  bits  para  uma  RAM  de  vídeo  a  fim  de  fazer  a 
atualização  da  tela,  por  exemplo.  E/S,  nesse  sentido,  ocorrerá  apenas  quando  um  processo 
entra  no  estado  bloqueado  aguardando  que  um  dispositivo  externo  termine  sua  tarefa 
(TANENBAUM, 2003, p. 98). 

Observa‐se que alguns processos, como os da Figura 1.7(a), gastam a maior parte do 
tempo  computando  e  por  isso  são  denominados  de  processos  orientados  à  UCP  (ou  UCP‐
bound), enquanto outros, como o da Figura 1.7(b), esperam por E/S na maior parte das vezes e 
são chamados de orientados à E/S (ou I/O‐bound). Os processos orientados à UCP geralmente 
apresentam  longos  surtos  de  uso  da  UCP  e  esporádicas  esperas  por  E/S,  enquanto  que  os 
processos orientados à E/S têm pequenos surtos de uso da UCP e esperas freqüentes por E/S. 
Nota‐se que o fator principal é o tamanho do surto da UCP, não o tamanho do surto de E/S. Os 
processos orientados à E/S não realizam muita computação entre uma requisição e outra da 
UCP, não pelo fato de terem requisições por E/S demoradas. Na verdade, o tempo de leitura 
de  um  bloco  dee  disco,  por  exemplo,  é 
é sempre  o  mesmo  ind
dependentem
mente  do  quanto 
demo
ore processaar os dados q
que chegam p
posteriormente (TANENB
BAUM, 2003
3, p. 98).  

As  durações  desses  surtos  de  UCP  foram  medidas 


m ustivamente.  Embora  po
exau ossam 
variar muito de p
processo a processo e dee computado m a ter uma  curva 
or a computaador, tendem
de  freqüência 
f s
semelhante  àquela  ind
dicada  na  figura  abaixo.  A  curvva  geralmen
nte  é 
caraccterizada com
mo exponencial ou hiperexponenciaal. Existe um grande núm
mero de surttos de 
UCP  curtos  e  um
m  número  peequeno  de  surtos 
s de  UC U programaa  orientado  a  E/S 
CP  longos.  Um 
geralmente terá m
muitos surto
os de UCP curtos. Um pro
ograma orien
ntado a UCP poderá ter aalguns 
os  de  UCP  lo
surto ongos.  Essa  distribuição
o  pode  ser  importante 
i na  seleção  de  um  algo
oritmo 
adequado de escaalonamento de UCP. 

 
Figura 1.8. H
Histograma daas durações dee surto de UCP

 

Tanenbau
um  (2003,  p. 
p 98)  diz  que 
q eniente  obsservar  que,  à  medida  que 
é  conve q a 
ologia  evoluii  e  as  UCPs  tornam‐se  mais 
tecno m rápidass  e  muito  mais 
m velozes  que  os  disco
os,  os 
proceessos  tendem
m  a  ficar  mais 
m dos  à  E/S  e  conseqüentemente  o  eescalonamen
orientad nto  de 
proceessos orientaados à E/S deeverá ser um
m assunto traatado com grrande importtância num ffuturo 
próximo. Basicam
mente, a idéia é que se u
um processo  orientado à E/S quiser eexecutar, devve ser 
rapidamente dad
da a ele essa oportunidad
de, pois assim quisições de disco, 
m ele executtará suas req
manttendo o disco
o ocupado e a UCP livre p
para executaar outros pro
ocessos. 

 
1.3 Quando escalonar 
Existe  uma  variedade  de  situações  nas  quais  o  escalonamento  é  necessário. 
Primeiramente, quando se cria um novo processo, é preciso tomar uma decisão entre executar 
o processo pai ou o processo filho. Como ambos os processos estão no estado pronto, essa é 
uma decisão normal de escalonamento e pode levar à escolha de um ou de outro, ou seja, o 
escalonador  pode  escolher  legitimamente  executar  o  pai  ou  o  filho.  Em  segundo  lugar,  uma 
decisão de escalonamento deve ser tomada ao término de um processo. Como o processo não 
pode executar mais, algum outro processo deve ser selecionado entre os prontos. Se nenhum 
processo  estiver  pronto,  é  executado  um  processo  ocioso  gerado  pelo  sistema.  Em  terceiro 
lugar, quando um processo bloqueia para E/S, sobre um semáforo ou por alguma outra razão, 
outro processo precisa ser escolhido para executar. O motivo do bloqueio pode algumas vezes 
influenciar na escolha. Por exemplo, se A for  um  processo importante e estiver esperando B 
sair de sua região crítica (RC), deixar B executar em seguida permitirá que ele saia de sua RC e 
assim  que  A  continue.  Contudo,  surge  aí  um  problema,  pois  o  escalonador,  em  geral,  não 
possui  a  informação  necessária  para  considerar  essa  dependência.  Em  quarto  lugar,  quando 
ocorre  uma  interrupção  de  E/S,  pode‐se  tomar  uma  decisão  de  escalonamento.  Se  a 
interrupção vem de um dispositivo de E/S que acabou de fazer seu trabalho, o processo que 
estava  bloqueado,  esperando  pela  E/S,  pode  agora  ficar  pronto  para  execução.  Cabe  ao 
escalonador  decidir  se  executa  o  processo  que  acabou  de  ficar  pronto  ou  se  continua 
executando o processo atual (que estava executando no momento da interrupção) ou ainda se 
escolhe um terceiro processo para executar (TANENBAUM, 2003, p. 99). 

Se um hardware de relógio fornece interrupções periódicas de 50 Hz, 60 Hz ou alguma 
outra  freqüência,  uma  decisão  de  escalonamento  pode  ser  tomada  a  cada  interrupção  de 
relógio  ou  a  cada  k‐ésima  interrupção  de  relógio.  Os  algoritmos  ou  disciplinas  de 
escalonamento  podem  ser  classificados  em  duas  categorias  quanto  ao  modo  como  tratam 
essas interrupções (TANENBAUM, 2003, p. 99). Uma disciplina é não preemptiva se, uma vez 
que  o  sistema  tenha  designado  um  processador  a  um  processo,  não  puder  retirar  aquele 
processador  daquele  processo.  Uma  disciplina  é  preemptiva  se  o  sistema  puder  retirar  o 
processador  do  processo  que  estiver  executando.  Sob  uma  disciplina  de  escalonamento  não 
preemptiva,  cada  processo,  uma  vez  recebido  um  processador,  executa  até  concluir  ou  até 
devolver voluntariamente um processador (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, 
p. 211). Na verdade, nenhuma decisão de escalonamento é tomada durante as interrupções de 
relógio.  Após  o  processamento  da  interrupção  de  relógio  ter  findado,  o  processo  que  estava 
executando antes da interrupção prossegue até acabar (TANENBAUM, 2003, p. 99). Sob uma 
disciplina preemptiva de escalonamento, o processador pode executar uma parte do código de 
um  processo  durante  um  tempo  máximo  fixado  e  então  fazer  um  chaveamento  de  contexto 
(DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  211;  TANENBAUM,  2003,  p.  99).  Se 
ainda  estiver  executando  ao  final  desse  intervalo  de  tempo,  o  processo  será  suspenso  e  o 
escalonador escolherá outro processo para executar caso haja algum disponível (TANENBAUM, 
2003, p. 99). 

1.4 Escalonamento preemptivo versus escalonamento não preemptivo 
O escalonamento preemptivo é útil em sistemas nos quais processos de alta prioridade 
exigem  resposta  rápida.  Em  sistemas  de  tempo  real,  por  exemplo,  as  conseqüências  seriam 
catastróficas  caso  as  interrupções  não  fossem  respondidas  (ABBOT,  1984;  RAMAMRITHAM; 
STANOVIC, 1984; VOLZ; MUDGE, 1987; POTKONJAK; WOLF, 1999 apud DEITEL, H. M.; DEITEL, 
P. J.; CHOFFNES, D. R., 2005, p. 211)6,7,  8, 9. Em sistemas interativos de tempo compartilhado, o 
escalonamento  preemptivo  ajuda  a  garantir  tempos  de  resposta  aceitáveis  ao  usuário.  A 
preempção  não  deixa  de  ter  um  custo  pois  os  chaveamentos  de  contexto  incorrem  em 
sobrecarga.  Para  tornar  a  preempção  efetiva,  o  sistema  deve  manter  muitos  processos  na 
memória  principal,  de  modo  que  o  processo  seguinte  esteja  pronto  quando  um  processador 
tornar‐se  disponível.  Normalmente,  apenas  uma  parte  de  cada  processo  está  na  memória 
principal a qualquer instante e as partes menos ativas geralmente estão em discos (DEITEL, H. 
M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 211). 

Em  sistemas  não  preemptivos,  processos  curtos  podem  sofrer  longas  esperas  para 
serem atendidos enquanto são concluídos processos mais longos, mas os tempos de retorno 
são mais previsíveis, porque os processos de alta prioridade que chegam não podem desalojar 
os  processos  que  estão  à  espera.  Como  um  sistema  não  preemptivo  não  pode  retirar  um 
processo de um processador até que o processo conclua a execução, programas errantes que 
nunca são concluídos (porque entraram em laço infinito) podem nunca entregar o controle do 
sistema.  Além  disso,  em  um  sistema  não  preemptivo,  a  execução  de  processos  não 
importantes pode fazer que processos muito importantes permaneçam esperando (DEITEL, H. 
M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 211). 

                                                            
6
 ABBOT, C. “Intervention schedules for real‐time programming”, IEEE Transactions on Software Engineering, v. SE‐
10, nº 3, maio 1984, p. 268‐274. 
7
  RAMAMRITHAM,  K.  ;  STANOVIC,  J.  A.  “Dynamic  task  scheduling  in  hard  real‐time  distributed  systems”,  IEEE 
Software, v. 1, nº 3, jul. 1984, p. 65‐75. 
8
  VOLZ,  R.  A.;  MUDGE,  T.  N.  “Instruction  level  timing  mechanisms  for  accurate  real‐time  task  scheduling”,  IEEE 
Transactions on Computers, v. C‐36, nº 8, ago. 1987, p. 988‐993. 
9
 POTKONJAK, M.; WOLF, W. “A methodology and algorithms for the design of hard real‐time ultitasking ASICs”, ACM 
Transactions on Design Automation of Electronic Systems (TODAES), v. 4, nº 4, out. 1999.
Para  evitar  que  usuários  monopolizem  o  sistema  (acidental  ou  propositalmente),  um 
sistema preemptivo pode retirar o processador de um processo. Normalmente tal operação é 
implementada instalando‐se um relógio de interrupção ou um temporizador de intervalo que 
gere  um  interrupção  periodicamente,  permitindo  que  o  sistema  execute.  Tão  logo  um 
processador  seja  designado  a  um  processo,  esse  executa  até  liberar  voluntariamente  seu 
processador  ou  até  ocorrer  uma  interrupção  do  relógio  ou  alguma  interrupção.  Então  o 
sistema  pode  decidir  se  o  processo  em  execução  deve  continuar  ou  algum  outro  processo 
“seguinte” deve executar (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 211). 

O escalonamento preemptivo requer a existência de uma interrupção de relógio ao fim 
do intervalo de tempo para que o controle sobre a UCP seja devolvido ao escalonador. Se não 
houver relógio disponível, o escalonamento não preemptivo será a única opção (TANENBAUM, 
2003,  p.  99).  Assim,  o  relógio  de  interrupção  ajuda  a  garantir  tempos  de  resposta  razoáveis 
para usuários interativos, evita que o sistema fique suspenso em um laço infinito do usuário e 
permite  que  processos  respondam  a  eventos  que  dependam  de  tempo.  Processos  que 
precisam  executar  periodicamente  dependem  do  relógio  de  interrupção  (DEITEL,  H.  M.; 
DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 211). 

Segundo Deitel, H. M.; Deitel, P. J.; Choffnes, D. R. (2005, p. 212):  

“Ao  projetar  um  mecanismo  de  escalonamento  preemptivo,  deve‐se 


considerar cuidadosamente a arbitrariedade de sistemas de prioridade. Não 
tem  sentido  construir  um  mecanismo  sofisticado  para  implementar 
fielmente  um  esquema  de  preempção  por  prioridade  quando  as  próprias 
prioridades não são designadas significativamente.” 

1.5 Filas de escalonamento 
À  medida  que  os  processos  entram  no  sistema,  são  colocados  em  uma  fila  de  jobs. 
Essa  fila  consiste  em  todos  os  processos  do  sistema.  Os  processos  que  estão  residindo  na 
memória  principal  e  estão  prontos  e  esperando  para  executar  são  mantidos  na  fila  de 
processos prontos (ready queue). A fila dos processos prontos geralmente é armazenada como 
uma  lista  encadeada.  Um  cabeçalho  de  fila  de  processos  prontos  contém  ponteiros  ao 
primeiro e último BCPs na lista (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 66).  

Existem também outras filas no sistema. Quando a UCP é alocada a um processo, ele 
executa  durante  um  tempo  e  é  encerrado,  interrompido  ou  espera  pela  ocorrência  de 
determinado  evento,  como  a  conclusão  de  um  pedido  de  E/S,  por  exemplo.  No  caso  de  um 
pedido de E/S, esse pedido pode ser para uma unidade de fita dedicada ou para um dispositivo 
compartilhado,  como  um  disco.  Como  existem  muitos  processos  no  sistema,  o  disco  pode 
estar ocupado com o pedido de E/S de algum outro processo. O processo, portanto, pode ter 
de  esperar  pelo  disco.  A  lista  de  processos  esperando  por  determinado  dispositivo  de  E/S  é 
chamada fila de dispositivo. Como ilustrado na figura abaixo, cada dispositivo tem sua própria 
fila de dispositivo (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 66). 

Figura 1.9. A fila de processos prontos e várias filas de dispositivos de E/S 
 

Uma representação comum para uma discussão sobre escalonamento de processos é 
um  diagrama  de  filas,  como  o  da  Figura  1.9.  Cada  caixa  retangular  representa  uma  fila.  Dois 
tipos de fila estão presentes: a fila de processos prontos e um conjuntos de filas de dispositivo. 
Os  círculos  representam  os  recursos  que  servem  as  filas  e  as  setas  indicam  o  fluxo  de 
processos no sistema (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 67). 

 
 

 
Figura 1.10. Representação do diagrama de filas do escalonamento de processos 
Um processo novo é colocado inicialmente na fila de processos prontos. Ele espera na 
fila até ser selecionado para a execução ou ser submetido (dispatched). Depois que o processo 
recebe a UCP e está em execução, um dos vários eventos a seguir poderá ocorrer: 

• O  processo  pode  emitir  um  pedido  de  E/S  e  ser  colocado  em 
uma fila de E/S; 
• O  processo  pode  criar  um  novo  subprocesso  e  esperar  seu 
término; 
• O processo pode ser removido à força da UCP, como resultado 
de uma interrupção e ser colocado de volta na fila de processos prontos. 
Nos  dois  primeiros  casos,  o  processo  acaba  alternando  do  estado  de  espera  para  o 
estado de pronto e, em seguida, é colocado de volta na fila de processos prontos. Um processo 
continua o seu ciclo até terminar e, nesse ponto, é removido de todas as filas, como seu BCP e 
recursos sendo desalocados (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 67). 

1.6 Níveis de Escalonamento 
Um processo migra entre várias filas de escalonamento ao longo de toda sua vida. O 
sistema operacional deve selecionar, para fins de escalonamento, os processos dessas filas de 
alguma  forma.  O  processo  de  seleção  é  executado  pelo  escalonador  (scheduler)  adequado. 
Três níveis de escalonamento podem ser considerados conforme ilustra a Figura 1.11. 

O  escalonamento  de  alto  nível,  também  denominado  escalonamento  de  jobs  ou 
escalonamento  de  longo  prazo  determina  quais  jobs  o  sistema  permite  que  disputem 
ativamente os recursos do sistema. Denominado às vezes de escalonamento de admissão, ele 
determina quais jobs são admitidos no sistema. Uma vez admitidos, os jobs são inicializados e 
tornam‐se  processos  ou  grupos  de  processos.  A  política  de  escalonamento  de  alto  nível 
determina o grau de multiprogramação, isto é, o número total de processos em um sistema 
em dado instante (IBARAKI, T.; ABDEL‐WAHAB, H. M.; KAMEDA, T.; 1983 apud DEITEL, H. M.; 
DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 209)10. A entrada de muitos processos em um sistema 
pode  causar  a  saturação  de  recursos  do  sistema  ocasionando  um  mau  desempenho.  Nesse 
caso,  a  política  de  escalonamento  de  alto  nível  pode  decidir  proibir  temporariamente  que 
novos jobs entrem até que outros sejam concluídos (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. 
R., 2005, p. 209). 

  Figura 1.11. Níveis de escalonamento

Após a política de escalonamento de alto nível ter admitido um job (que pode conter 
um  ou  mais  processos)  no  sistema,  a  política  de  escalonamento  de  nível  intermediário, 
também  denominado  escalonamento  de  médio  prazo,  determina  quais  processos  terão 
permissão de concorrer por processadores. Essa política atende às flutuações de médio prazo 
                                                            
10
 IBARAKI, T.; ABDEL‐WAHAB, H. M.; KAMEDA, T. “Design of minimum‐cost deadlock‐free systems”, Journal of the 
ACM, v. 30, nº 4, out. 1983, p. 750. 
da  carga  do  sistema,  atuando  na  suspensão  e  retomada  de  processos  temporariamente  de 
forma  a  conseguir  uma  operação  tranqüila  do  sistema  e  ajudar  a  cumprir  certas  metas  de 
desempenho no âmbito geral do sistema. O escalonador de nível intermediário funciona como 
um buffer entre admissão de jobs no sistema e a designação de processadores a processos que 
representam  esses  jobs  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  209).  O 
escalonador de nível intermediário aparece apenas em alguns sistemas operacionais, como os 
de  tempo  compartilhado.  Seu  funcionamento  está  representado  na  Figura  1.12.  A  principal 
idéia por trás dessa política de escalonamento é que às vezes pode ser mais vantajoso remover 
processos  da  memória  (e  da  disputa  ativa  por  UCP)  e,  assim,  reduzir  o  grau  de 
multiprogramação. Em algum momento posterior, o processo pode ser introduzido novamente 
na  memória  e  sua  execução  pode  ser  retomada  do  ponto  onde  parou.  Esse  esquema  é 
chamado  swapping  (troca).  O  escalonador  de  nível  intermediário  realiza  as  operações  de 
swapping.  O  swapping  pode  ser  necessário  para  melhorar  a  combinação  de  processos  ou 
porque  uma  mudança  nos  requisitos  de  memória  comprometeu  a  memória  disponível, 
exigindo a liberação de memória (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 68). 

 
Figura 1.12. Diagrama de filas com o escalonamento de nível intermediário 

Por fim, a política de escalonamento de baixo nível de um sistema, também chamada 
de  escalonamento  de  curto  prazo  ou  escalonamento  de  UCP,  determina  quais  processos 
ativos  o  sistema  designará  a  um  processador  quando  o  próximo  ficar  disponível.  Em  muitos 
dos sistemas atuais, os únicos escalonadores são os de níveis baixo e intermediário (neste caso 
a  inicialização  do  job  é  realizada  pelo  escalonador  de  nível  intermediário).  Escalonadores  de 
alto nível normalmente são limitados a sistemas de grande porte (mainframes) que executam 
processamento  em  lote  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  209).  Por 
exemplo,  sistemas  de  tempo  compartilhado,  como  o  UNIX,  geralmente  não  têm  um 
escalonador de alto nível, mas simplesmente colocam todo novo processo na memória para o 
escalonador  de  baixo  nível.  A  estabilidade  desses  sistemas  depende  de  uma  limitação  física 
(como  o  número  de  terminais  disponíveis)  ou  da  natureza  de  auto‐ajuste  dos  usuários 
humanos.  Se  o  desempenho  cair  para  níveis  inaceitáveis,  alguns  usuários  simplesmente  vão 
desistir (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 68). 

A principal distinção entre os escalonadores de alto e baixo nível é a freqüência da sua 
execução.  O  escalonador  de  baixo  nível  deve  selecionar  um  novo  processo  para  a  UCP  com 
freqüência. Um processo pode executar por apenas alguns milissegundos antes de esperar por 
um pedido de E/S. Em geral, o escalonador de baixo nível executa pelo menos uma vez a cada 
100  milissegundos.  Devido  à  breve  duração  de  tempo  entre  as  execuções,  o  escalonador  de 
baixo nível deve ser rápido. Se levar 10 milissegundos para decidir executar um processo por 
100  milissegundos,  então  10/(100  +  10)  =  9%  da  UCP  está  sendo  usado  (desperdiçado) 
simplesmente  para  escalonar  o  trabalho  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G.,  2000,  p. 
68). 

O  escalonador  de  alto  nível,  por  outro  lado,  executa  com  muito  menos  freqüência. 
Pode  haver  um  intervalo  de  minutos  entre  a  criação  de  novos  processos  no  sistema.  Como 
visto,  o  escalonador  de  alto  nível  controla  o  grau  de  multiprogramação,  isto  é,  o  número  de 
processos na memória. Se o grau de multiprogramação for estável, a taxa média de criação de 
processos deve ser igual à taxa média de partida de processos que saem do sistema. Assim, o 
escalonador  de  alto  nível  pode  precisar  ser  chamado  apenas  quando  um  processo  sair  do 
sistema. Devido ao intervalo maior entre as execuções, o escalonador de alto nível pode levar 
mais tempo para decidir que processos devem ser selecionados para execução (SILBERSCHATZ, 
A.; GALIN, P.; GAGNE, G., 2000, p. 68). 

É importante que o escalonador de alto nível faça uma seleção cuidadosa. Em geral, a 
maioria  dos  processos  podem  ser  escritos  com  orientados  a  E/S  ou  orientados  a  UCP.  Um 
processo orientado a E/S passa mais tempo realizando as operações de E/S do que efetuando 
cálculos.  Um  processo  orientado  a  UCP,  em  contrapartida,  gera  pedidos  de  E/S  com  pouca 
freqüência,  usando  mais  o  seu  tempo  na  computação.  É  importante  que  o  escalonador  de 
longo prazo selecione uma boa combinação de processos incluindo processos orientados a E/S 
e orientados a UCP. Se todos os processos forem orientados a E/S, a fila de processos prontos 
quase  sempre  estará  vazia  e  o  escalonador  de  baixo  nível  terá  pouco  trabalho.  Se  todos  os 
processos forem orientados a UCP, a fila de espera de E/S ficará vazia a maior parte do tempo, 
os dispositivos ficarão sem uso e mais uma vez o sistema ficará desequilibrado. O sistema com 
o melhor desempenho terá uma combinação de processos orientados a E/S e orientados a UCP 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 68). 
Muitas vezes as políticas de escalonamento de baixo nível atribuem uma prioridade a 
cada processo, que reflete a importância desse processo – quanto mais importante for, maior 
será  a  probabilidade  de  que  a  política  de  escalonamento  o  selecione  para  ser  executado  em 
seguida.  O  escalonador  de  baixo  nível  (também  denominado  despachante)  também  designa 
(despacha)  um  processador  ao  processo  selecionado.  O  despachante  funciona  muitas  vezes 
por  segundo  e,  portanto,  deve  residir  na  memória  principal  o  tempo  todo  (DEITEL,  H.  M.; 
DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 209). 

Coffman  e  Kleinrock  (1968  apud  Deitel,  H.  M.;  Deitel,  P.  J.;  Choffnes,  2005,  p.  210) 
discutem  políticas  de  escalonamento  populares  e  indicam  como  usuários  conhecedores  de 
qual  política  o  sistema  realmente  usa  podem  conseguir  melhor  desempenho  tomando 
medidas  apropriadas11.  Ruschitzka  e  Fabry  (1977  apud  Deitel,  H.  M.;  Deitel,  P.  J.;  Choffnes, 
2005,  p.  210)  apresentam  uma  classificação  de  algoritmos  de  escalonamento  e  formalizam  a 
noção de prioridade12. 

1.7 Prioridades 
Escalonadores  muitas  vezes  usam  prioridades  para  determinar  como  escalonar  e 
despachar  processos.  Prioridades  podem  ser  designadas  estaticamente  ou  mudar 
dinamicamente.  Elas  quantificam  a  importância  relativa  dos  processos.  Prioridades  estáticas 
permanecem fixas, portanto, mecanismos baseados em prioridade estática são relativamente 
fáceis  de  implementar  e  incorrem  em  sobrecarga  relativamente  baixa.  Contudo,  esses 
mecanismos  não  são  responsivos  a  mudanças  no  ambiente,  mesmo  os  que  poderiam 
aumentar  o  rendimento  e  reduzir  a  latência.  Por  outro  lado,  mecanismos  de  prioridade 
dinâmica  são  responsivos  a  mudanças.  O  sistema  pode  querer,  por  exemplo,  elevar  a 
prioridade de um processo que esteja retendo um recurso importante que outro processo de 
prioridade mais alta precisa. Após o primeiro processo devolver o recurso, o sistema baixa a 
prioridade,  para  que  o  processo  de  prioridade  mais  alta  possa  executar.  Esquemas  de 
prioridade  dinâmica  são  mais  complexos  de  implementar  e  têm  sobrecargas  maiores  do  que 
esquemas  estáticos.  Na  melhor  das  hipóteses  a  sobrecarga  é  justificada  pelo  aumento  de 
responsividade do sistema (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 212). 

Em sistemas multiusuários, um sistema operacional deve fornecer serviços razoáveis a 
uma  grande  comunidade  de  usuários,  mas  também  deve  atender  a  situações  nas  quais  um 

                                                            
11
 COFFMAN Jr., E. G.; KLEINROCK, E. L. “Computer scheduling methods and their dountermeasures”, Proceedings of 
AFIPS, SJCC, v. 32, 1968, p. 11‐21. 
12
 RUSCHITZKA, M.; FABRY, R. S. “A unifying approach to scheduling”, Communications of the ACM, v. 20, nº 7, jul. 
1977, p. 469‐477. 
membro  da  comunidade  de  usuários  precisa  de  tratamento  especial.  Um  usuário  que  tenha 
um job importante pode estar disposto a pagar um preço mais alto, isto é, comprar prioridade 
para um serviço de nível mais alto. Essa cobrança extra é merecida, porque os recursos talvez 
precisem ser retirados de outros clientes pagantes. Se não houvesse cobrança extra, todos os 
usuários requisitariam o nível mais alto de serviço (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. 
R., 2005, p. 212). 

1.8 Trocas de contexto 
Alternar  a  UCP  para  outro  processo  requer  salvar  o  estado  do  processo  antigo  e 
carregar  o  estado  salvo  do  novo  processo.  Essa  tarefa  é  chamada  de  troca  de  contexto.  O 
contexto de um processo é representado no seu BCP; inclui o valor dos registradores de UCP, 
o estado do processo e as informações de gerência de memória. Quando ocorre uma troca de 
contexto, o kernel salva o contexto do processo antigo em seu BCP e carrega o contexto salvo 
do novo processo escolhido para execução. O tempo de troca de contexto é puro overhead, já 
que  o  sistema  não  efetua  trabalho  útil  durante  o  processo  de  troca.  Sua  velocidade  varia  de 
máquina a máquina dependendo da velocidade da memória, do número de registradores que 
devem  ser  copiados  e  da  existência  de  instruções  especiais  (como  uma  única  instrução  para 
carregar  ou  armazenar  todos  os  registradores).  Velocidades  típicas  estão  entre  1  a  1000 
microssegundos (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 69). 

Os tempos de troca de contexto são altamente dependentes do suporte de hardware. 
Por  exemplo,  alguns  processadores  (como  o  Sun  UltraSPARC)  fornecem  vários  conjuntos  de 
registradores. Uma troca de contexto simplesmente inclui mudar o ponteiro para o conjunto 
de  registradores  atual.  É  claro  que  se  houver  mais  processos  ativos  do  que  conjuntos  de 
registradores, o sistema vai copiar os dados do registrador de e para a memória como antes. 
Além  disso,  quanto  mais  complexo  o  sistema  operacional,  mais  trabalho  deve  ser  realizado 
durante uma troca de contexto.  Existem técnicas avançadas de gerência de memória podem 
exigir  que  dados  extras  sejam  trocados  com  cada  contexto.  Por  exemplo,  o  espaço  de 
endereçamento  do  processo  atual  deve  ser  preservado  à  medida  que  o  espaço  da  próxima 
tarefa  é  preparado  para  uso.  Como  o  espaço  de  endereçamento  é  preservado  e  quanto 
trabalho será necessário para preservá‐lo dependerão do método de gerência de memória do 
sistema operacional. A troca de contexto tornou‐se um gargalo de desempenho de tal ordem 
que  os  programadores  estão  utilizando  novas  estruturas  (threads)  para  evitá‐la  sempre  que 
possível (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 69). 

   
CAPÍTULO 2 

ALGORITMOS DE ESCALONAMENTO 
 

O escalonamento de UCP lida com o problema de decidir a quais processos na fila de 
processos  prontos  a  UCP  deverá  ser  alocada.  Existem  muitos  algoritmos  diferentes  de 
escalonamento de UCP (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 99). Os algoritmos 
de escalonamento que serão apresentados determinam, durante a execução, quais processos 
executam  em seguida.  Esses algoritmos decidem  quando e por quanto tempo cada processo 
executa; escolhem preemptibilidade, prioridades, tempo de execução, tempo até a conclusão, 
justiça e outras características do processo. Alguns sistemas requerem a utilização de um tipo 
particular  de  escalonador  (sistemas  de  tempo  real  normalmente  requerem  escalonadores 
preemptivos,  por  prioridade).  Outros  confiam  no  comportamento  do  processo  ao  tomar 
decisões de escalonamento (favorecem processos orientados a E/S) (DEITEL, H. M.; DEITEL, P. 
J.; CHOFFNES, D. R., 2005, p. 215). Alguns algoritmos são usados apenas em sistemas em lote, 
enquanto  outros  são  utilizados  em  sistemas  interativos,  e  outros  ainda  são  empregados  em 
sistemas de tempo real. Convém ressaltar que alguns algoritmos podem ser usados tanto em 
sistemas em lote quanto em sistemas interativos (TANENBAUM, 2003, p. 101). 

2.1 Categorias de algoritmos de escalonamento 
Para  ambientes  diferentes  são  necessários  diferentes  algoritmos  de  escalonamento. 
Essa  situação  ocorre  porque  diferentes  áreas  de  aplicação  (e  diferentes  tipos  de  sistemas 
operacionais)  têm  objetivos  diferentes.  Em  outras  palavras,  o  que  deve  ser  otimizado  pelo 
escalonador não é o mesmo para todos os sistemas (TANENBAUM, 2003, p. 99). 

De acordo com Tanenbaum (2003, p. 99) três ambientes merecem distinção: 

1. Lote. 
2. Interativo. 
3. Tempo real. 

Nos sistemas em lote não há, em seus terminais, usuários esperando impacientes por 
uma resposta rápida. Conseqüentemente, os algoritmos não preemptivos ou preemptivos com 
longo  intervalo  de  tempo  para  cada  processo  são  em  geral  aceitáveis.  Essa  tática  reduz  as 
alternância entre processos e assim melhora o desempenho (TANENBAUM, 2003, p. 99). 
Em  um  ambiente  com  usuários  interativos,  a  preempção  é  essencial  para  evitar  que 
um  processo  se  aposse  da  UCP  e  com  isso  negue  serviço  aos  outros.  Mesmo  que  nenhum 
processo execute intencionalmente para sempre, uma falha em um programa pode levar um 
processo a impedir indefinidamente que todos os outros executem. A preempção é necessária 
para impedir esse comportamento (TANENBAUM, 2003, p. 99). 

Em  sistemas  com  restrições  de  tempo  real,  a  preempção  é,  estranhamente, 
desnecessária  algumas  vezes,  pois  os  processos  sabem  que  não  podem  executar  por  longos 
períodos e em geral fazem seus trabalhos e bloqueiam rapidamente. A diferença com relação 
aos  sistemas  interativos  é  que  os  sistemas  de  tempo  real  executam  apenas  programas  que 
visam  ao  progresso  da  aplicação.  Já  os  sistemas  interativos  são  de  propósito  geral  e  podem 
executar  programas  arbitrários  não  cooperativos  ou  até  mal‐intencionados  (TANENBAUM, 
2003, p. 100). 

2.2 Objetivos do Escalonamento 
Um  projetista  de  sistemas  deve  considerar  uma  variedade  de  fatores  ao  desenvolver 
uma  disciplina  de  escalonamento  como  o  tipo  do  sistema  e  as  necessidades  do  usuário.  Por 
exemplo, a disciplina de escalonamento para um sistema de tempo real deve ser diferente da 
disciplina para o sistema interativo de um computador de mesa; usuários esperam resultados 
diferentes desses tipos de sistemas. Dependendo do sistema, o usuário e os projetistas podem 
esperar que o escalonador: 

• Maximize o rendimento. Uma disciplina de escalonamento deve tentar 
atender ao maior número de processos por unidade de tempo. 
• Maximize  o  número  de  processos  interativos  que  estão  recebendo 
tempos de resposta “aceitáveis”. 
• Maximize  a  utilização  de  recursos.  Os  mecanismos  de  escalonamento 
devem manter os recursos do sistema ocupados. 
• Evite  adiamento  indefinido.  Um  processo  não  deve  experimentar  um 
tempo  de  espera  sem  limite  antes  de  receber  um  serviço  ou  enquanto  o  estiver 
recebendo. 
• Imponha prioridades. Se o sistema designar prioridades a processos, o 
mecanismo de escalonamento deve favorecer os processos de prioridade mais alta. 
• Minimize  sobrecarga.  Curiosamente,  em  geral  esse  objetivo  não  é 
considerado  dos  mais  importantes.  Sobrecarga  freqüentemente  resulta  em 
desperdício  de  recursos,  mas  uma  certa  porção  dos  recursos  do  sistema  se  investida 
efetivamente como sobrecarga pode melhorar muito o desempenho geral do sistema. 
• Assegure  a  previsibilidade.  Minimizando  a  variância  estática  dos 
tempos  de  resposta  de  processos,  um  sistema  pode  garantir  que  os  processos 
recebam níveis de serviços previsíveis. 

Um  sistema  pode  cumprir  esses  objetivos  de  diversas  maneira.  Em  alguns  casos  o 
escalonador pode impedir o adiamento indefinido de processos por meio do envelhecimento 
(aging)  –  elevando  gradativamente  a  prioridade  de  um  processo  enquanto  ele  espera  ser 
atendido.  Eventualmente  sua  prioridade  se  torna  alta  o  suficiente  para  que  o  escalonador 
seleciona aquele processo para executar (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, 
p. 212‐213). 

O  escalonador  pode  aumentar  o  rendimento  favorecendo  processos  cujos  requisitos 


podem ser satisfeitos rapidamente ou cuja conclusão libera outros processos para execução. 
Uma estratégia como essa favorece processos que retêm recursos fundamentais. Por exemplo, 
um  processo  de  baixa  prioridade  pode  reter  um  recursos  requerido  por  um  processo  de 
prioridade  mais  alta.  Se  o  recursos  for  não  preemptivo,  o  escalonador  deverá  conceder  ao 
processo de prioridade baixa mais tempo de execução do que ordinariamente receberia, para 
que  ele  libere  o  recurso  fundamental  mais  cedo.  Essa  técnica  é  denominada  inversão  de 
prioridade,  pois  as  prioridades  relativas  dos  dois  processos  são  invertidas  para  que  o  de 
prioridade  alta  obtenha  recursos  que  requer  para  continuar  a  execução.  De  forma  similar,  o 
escalonador pode preferir favorecer um processo que requisite recursos subutilizados, porque 
o sistema provavelmente satisfará os requisitos desse processo em um período de tempo mais 
curto (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 213). 

Muitos desses objetivos conflitam uns com os outros, fazendo do escalonamento um 
problema  complexo.  Por  exemplo,  a  melhor  maneira  de  minimizar  tempos  de  resposta  é  ter 
recursos disponíveis suficientes sempre que forem necessários. O preço dessa estratégia é que 
a  utilização  geral  dos  recursos  será  ruim.  Em  sistemas  de  tempo  real,  respostas  rápidas, 
previsíveis,  são  cruciais  e  a  utilização  de  recursos  é  menos  importante.  Em  outros  tipos  de 
sistemas, a questão da economia comumente faz com que a utilização efetiva de recursos seja 
um imperativo (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 213). 

A  despeito  das  diferenças  entre  os  objetivos  dos  sistemas,  muitas  disciplinas  de 
escalonamento exibem propriedades semelhantes: 
• Justiça. Uma disciplina de escalonamento é justa se todos os processos 
semelhantes forem tratados da mesma maneira, e nenhum processo sofrer adiamento 
indefinido devido a questões de escalonamento. 
• Previsibilidade.  A  execução  de  um  determinado  processo  sob  cargas 
de sistema similares deve durar aproximadamente o mesmo período de tempo. 
• Escalabilidade.  O  desempenho  do  sistema  deve  se  degradar 
graciosamente  (não  deve  entrar  em  colapso  imediatamente)  sob  cargas  pesadas 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 213‐214). 

2.3 Critérios de Escalonamento 
Para  cumprir  os  objetivos  de  escalonamento  de  um  sistema,  o  escalonador  deve 
considerar o comportamento do processo. Um processo orientado a UCP tende a usar todo o 
tempo do processador que o sistema aloca a ele. Um processo orientado a E/S tende a usar o 
processador apenas brevemente antes de gerar uma requisição de E/S e em seguida devolvê‐
lo.  Processos  orientados  a  UCP  gastam  a  maior  parte  do  seu  tempo  usando  o  processador; 
processos  orientados  a  E/S  passam  a  maior  parte  do  seu  tempo  esperando  por  recursos 
externos (impressoras, unidades de disco, conexões de rede etc.) atendam a suas requisições, 
e somente em tempo nominal usando processadores (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, 
D. R. , 2005, p. 214). 

Uma  disciplina  de  escalonamento  também  poderia  considerar  se  um  processo  é  em 
lote ou interativo. Um processo em lote contém trabalho que o sistema executa sem interagir 
com o usuário. Um processo interativo requer freqüentemente entradas do usuário. O sistema 
deve  fornecer  bons  tempos  de  resposta  a  um  processo  interativo,  enquanto,  em  geral,  um 
processo  em  lote  pode  sofrer  atrasos  razoáveis.  Similarmente,  uma  disciplina  de 
escalonamento deve ser sensível à urgência de um processo. Um processo em lote que deve 
ser  executado  durante  a  noite  não  exige  respostas  imediatas.  Um  sistema  de  controle  de 
processo  de  tempo  real  que  monitora  uma  refinaria  de  petróleo  deve  ser  responsivo  para 
evitar uma possível explosão (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 214). 

Há algum tempo atrás, usuários interagiam com processos emitindo requisições triviais 
por meio do teclado. Nesse ambiente, um escalonador podia favorecer um processo interativo 
e  causar  pouco  efeito  sobre  outros  processos  porque  o  tempo  requerido  para  atender  a 
processos interativos (por exemplo, exibir textos) era nominal. À medida que os computadores 
ficaram  mais  potentes,  projetistas  de  sistemas  e  programadores  de  aplicações  começaram  a 
incluir  características  como  gráficos  e  GUIs  para  aperfeiçoar  a  interação  amigável  com  o 
usuário. Embora alguns sistemas ainda utilizem interfaces de texto, grande parte dos usuários 
de hoje interage via GUIs usando um mouse para executar ações como abrir, redimensionar , 
arrastar  e  fechar  janelas  de  aplicativos.  Usuários  esperam  que  sistemas  respondam 
rapidamente,  para  que  essas  ações  produzam  movimentação  suave.  Diferentemente  do  que 
acontece em interfaces de texto, essa tarefa pode ser intensiva em computação por exigir que 
o  sistema  redesenhe  a  tela  muitas  vezes  por  segundo.  Favorecer  esses  processos  interativos 
pode reduzir significativamente o nível de serviço oferecido a outros processos do sistema. No 
caso de um processo em lote, essa redução temporária do serviço pode ser aceitável, embora 
talvez não o seja para processos que executem em  tempo real  (como aplicações multimídia) 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 214‐215). 

Em um sistema que emprega prioridades, o escalonador deve favorecer processos de 
prioridades mais altas. Escalonadores podem basear suas decisões na freqüência com que um 
processo de prioridade mais alta causou a preempção de um outro de prioridade mais baixa. 
Sob certas disciplinas, processos que sofrem preempções freqüentes recebem um tratamento 
menos favorecidos. Isso porque o curto tempo de execução do processo antes da preempção 
não  justifica  a  sobrecarga  incorrida  em  um  chaveamento  de  contexto  toda  vez  que  um 
processo  é  despachado.  Pode‐se  argumentar  o  contrário,  ou  seja,  que  tal  processo  deve 
receber tratamento mais favorável para compensá‐lo porque foi “maltratado” anteriormente 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 215). 

Políticas  de  escalonamento  preemptivo  comumente  mantêm  informações  sobre 


quanto  tempo  real  de  execução  cada  processo  recebeu.  Alguns  projetistas  acham  que  um 
processo que recebeu pouco tempo de execução deve ser favorecido. Outros acham que um 
processo que recebeu muito tempo de execução poderia estar próximo do término e deveria 
ser favorecido para chegar logo ao fim, liberar seus recursos para o uso de outros processos e 
sair  do  sistema  o  mais  cedo  possível.  De  maneira  similar,  um  escalonador  pode  manter  uma 
estimativa de quanto tempo ainda falta antes de um processo terminar. É fácil provar que os 
tempos médios de espera podem ser minimizados executando‐se primeiramente os processos 
que  exigem  o  mínimo  de  tempo  de  execução  antes  de  concluir.  Infelizmente,  um  sistema 
raramente sabe exatamente quanto tempo mais cada processo precisa para concluir (DEITEL, 
H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 215). 

Dessa maneira, diferentes algoritmos de escalonamento têm diferentes propriedades 
e podem favorecer uma classe de processos mais que outra. Ao escolher que algoritmo usar 
em  determinada  situação,  deve‐se,  pois,  considerar  as  diferentes  propriedades  dos  vários 
algoritmos (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 98). 

Muitos critérios foram sugeridos para comparar algoritmos de escalonamento de UCP. 
As características usadas para comparação podem fazer diferença substancial na determinação 
do melhor algoritmo. Os critérios usados incluem: 

• Utilização  de  UCP:  A  UCP  deverá  ficar  o  mais  ocupada  possível.  A 


utilização de UCP pode variar de 0 a 100%. Em um sistema real, deverá variar de 40% 
(para um sistema não muito carregado) a 90% (para sistemas muito utilizados). 
• Throughput:  Se  a  UCP  estiver  ocupada  executando  processos,  o 
trabalho  estará  sendo  feito.  Uma  medida  de  trabalho  é  o  número  de  processos 
completados por unidade de tempo, denominado throughput. Para processos longos, 
essa  taxa  pode  ser  de  um  processo  por  hora;  para  transações  curtas,  o  throughput 
pode ser de 10 processos por segundo. 
• Tempo  de  retorno:  Do  ponto  de  vista  de  determinado  processo,  o 
critério  importante  é  quanto  tempo  leva  para  executar  esse  processo.  O  intervalo 
entre  a  submissão  de  um  processo  até  o  seu  tempo  de  conclusão  é  o  tempo  de 
retorno.  Esse  tempo  é  a  soma  dos  períodos  gastos  esperando  para  acessar  a 
memória, aguardando na fila de processos prontos, executando na UCP e realizando 
operações de entrada e saída. 
• Tempo  de espera:  O algoritmo de escalonamento de UCP não afeta a 
quantidade  de  tempo  durante  a  qual  determinado  processo  executa  ou  efetua  E/S; 
afeta apenas o tempo que um processo gasta esperando na fila de processos prontos. 
O  tempo  de  espera  é  a  soma  dos  períodos  gastos  esperando  na  fila  de  processos 
prontos. 
• Tempo  de  resposta:  Em  um  sistema  interativo,  o  tempo  de  retorno 
pode não ser o melhor critério. Em geral, um processo pode produzir algum resultado 
logo de início e pode continuar computando novos resultados enquanto os anteriores 
estiverem sendo repassados para o usuário. Assim, outra medida é o tempo entre a 
submissão  de  um  pedido  até  a  primeira  resposta  ser  produzida.  Essa  medida, 
chamada  de  tempo  de  resposta,  é  o  tempo  que  o  processo  leva  para  começar  a 
responder, mas não é o tempo que leva para gerar a resposta. O tempo de resposta 
geralmente  é  limitado  pela  velocidade  do  dispositivo  de  saída  (SILBERSCHATZ,  A.; 
GALIN, P.; GAGNE, G., 2000, p. 98). 
É  desejável  maximizar  a  utilização  de  UCP  e  o  throughput,  e  minimizar  o  tempo  de 
retorno,  o  tempo  de  espera  e  o  tempo  de  resposta.  Em  muitos  casos,  otimiza‐se  a  medida 
média.  No  entanto,  existem  casos  em  que  é  desejável  otimizar  os  valores  mínimos  ou 
máximos, em vez do valor médio. Por exemplo, para garantir que todos os usuários obtenham 
um  bom  serviço,  talvez  seja  necessário  minimizar  o  tempo  de  resposta  máximo 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 98). 

Pesquisadores  sugeriram  que,  para  sistemas  interativos  (como  os  de  tempo 
compartilhado),  é  mais  importante  minimizar  a  variância  no  tempo  de  resposta  do  que 
minimizar  o  tempo  de  resposta  médio.  Um  sistema  com  um  tempo  de  resposta  razoável  e 
previsível  pode  ser  considerado  mais  desejável  do  que  um  sistema  que  é  mais  rápido  em 
média, mas é altamente variável. No entanto, pouco trabalho foi realizado em algoritmos de 
escalonamento de UCP que minimizem a variância (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 
2000, p. 98‐99). 

2.4 Escalonamento em Sistemas em Lote 

2.4.1 Escalonamento primeiro a entrar primeiro a sair (FIFO) 
Segundo Deitel, H. M.; Deitel, P. J.; Choffnes (2005, p. 215), Tanenbaum (2003, p. 102) 
e  Silberschatz,  A.,  Galin,  P.;  Gagne,  G.  (2000,  p.  99),  o  algoritmo  de  escalonamento  mais 
simples é provavelmente o algoritmo não preemptivo primeiro a entrar primeiro a sair (First In 
First  Out  ‐  FIFO),  também  conhecido  como  primeiro  a  chegar  primeiro  a  ser  atendido  (First 
Come Firs ‐Served – FCFS). 

No FIFO, os processos são despachados conforme o momento em que chegaram à fila 
de  prontos  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  215).  Nesse  esquema,  o 
processo que solicita a UCP primeiro, a recebe primeiro (SILBERSCHATZ, A.; GALIN, P.; GAGNE, 
G., 2000, p. 99). Logo, com esse algoritmo, a UCP é atribuída aos processos na ordem em que 
eles a requisitam (Figura 2.1). Basicamente, há uma fila única de processos prontos. Quando o 
primeiro  job  entra  no  sistema  é  iniciado  imediatamente  e  autorizado  a  executar  por  quanto 
tempo queira. À medida que chegam os outros jobs, eles são encaminhados para o final da fila. 
Quando  o  processo  em  execução  é  bloqueado,  o  primeiro  processo  aguardando  na  fila  é  o 
próximo  a  executar.  Quando  um  processo  bloqueado  fica  pronto  –  assim  como  um  job  que 
acabou de chegar ‐, ele é dirigido para o fim da fila (TANENBAUM, 2003, p. 102).  

 
 
Figura 2.1. Escalonamento primeiro a entrar primeiro a sair  

O  FIFO  é  não  preemptivo  –  uma  vez  obtido  um  processador,  o  processo  executa  até 
libertá‐lo, terminando ou realizando um pedido de E/S (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, 
D. R., 2005, p. 215; SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 100). A grande vantagem 
desse algoritmo é que ele é fácil de entender e igualmente fácil de programar. Com ele, uma 
única  lista  encadeada  controla  todos  os  processos  prontos.  Logo,  adicionar  um  novo  job  ou 
processo  desbloqueado  requer  apenas  a  inserção  de  seu  BCP  no  final  da  fila  (TANENBAUM, 
2003, p. 102). 

O  algoritmo  de  escalonamento  FIFO  é  justo  no  sentido  de  que  escalona  processos 
segundo  o  momento  em  que  chegaram;  desse  modo,  todos  os  processos  são  tratados 
igualmente,  porém,  de  certa  maneira  é  injusto  porque  processos  longos  fazem  processos 
curtos  esperar,  e  processos  não  importantes  fazem  processos  importantes  esperar.  Assim,  o 
FIFO  não  é  útil  para  escalonar  processos  interativos,  pois  não  pode  garantir  tempos  de 
resposta  curtos  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  215),  tornando‐se 
particularmente problemático para sistemas de tempo compartilhado, onde é importante que 
cada usuário tenha uma parte de UCP em intervalos regulares. Seria desastroso permitir que 
um  processo  ficasse  com  a  UCP  por  um  período  prolongado  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 100).  

De acordo com Silberschatz, A., Galin, P.; Gagne, G (2000, p. 100), o tempo de espera 
médio  com  a  política  FIFO  muitas  vezes  é  bem  longo.  Considere  o  seguinte  conjunto  de 
processos  que  chegam  no  instante  0,  com  a  duração  de  surto  de  UCP  expressa  em 
milissegundos: 

 
Tabela 2.1 ‐ Duração de surtos da UCP, em milissegundos 

Processo  Duração de surto 
P1  24 
P2  3 
P3  3 
 

Se os processos chegarem na ordem P1, P2, e P3, e forem atendidos na ordem FIFO, o 
resultado seria o apresentado no seguinte diagrama de Gantt:   

P1  P2  P3 


0    24 27  30

O  tempo  de  espera  é  0  milissegundo  para  o  processo  P1,  24  milissegundos  para  o 
processo P2 e 27 milissegundos para o processo P3. Assim, o tempo de espera médio é de (0 + 
24 + 27)/3 = 17 milissegundos. Entretanto, se os processos chegarem na ordem P2, P3 e P1, os 
resultados serão semelhantes aos apresentados no diagrama de Gantt a seguir: 

P2  P3  P1 


0    3  6  30

O  tempo  médio  é  agora  (6  +  0  +3)/3  =  3  milissegundos.  Essa  redução  é  substancial. 


Assim,  o  tempo  de  espera  médio  em  uma  política  FIFO  geralmente  não  é  mínimo,  e  pode 
variar substancialmente se os tempos de surto de UCP do processo variarem muito. 

Além  disso,  considere  o  desempenho  do  escalonamento  FIFO  em  uma  situação 
dinâmica. Suponha que exista um processo orientado a UCP e muitos processos orientados a 
E/S.  À  medida  que  os  processos  fluem  pelo  sistema,  a  seguinte  situação  pode  ocorrer:  o 
processo  orientado  a  UCP  obterá  e  manterá  a  UCP.  Durante  esse  tempo,  todos  os  demais 
processos  terminarão  sua  operação  de  entrada/saída  e  passarão  para  a  fila  de  processos 
prontos,  esperando  pela  liberação  da  UCP.  Enquanto  os  processos  esperam  na  fila  de 
processos prontos, os dispositivos de E/S estão ociosos. Por fim, o processo orientado a UCP 
termina  seu  surto  de  computação  e  passa  para  um  dispositivo  de  E/S.  Todos  os  processos 
orientados a E/S, que têm surtos de UCP curtos, executam rapidamente e voltam para as filas 
de E/S. Nesse instante, a UCP fica ociosa. O processo orientado a UCP passará então para a fila 
de  processos  prontos  e  receberá  a  UCP.  Novamente,  todos  os  processos  de  E/S  acabam 
esperando  na  fila  de  processos  prontos  até  que  o  processo  orientado  a  UCP  termine  sua 
execução.  Existe um efeito comboio, enquanto  todos os outros processos aguardam que  um 
grande  processo  saia  da  UCP.  Esse  efeito  resulta  em  menor  utilização  de  UCP  e  dispositivos 
que o possível, caso processos mais curtos pudessem ser atendidos primeiro (SILBERSCHATZ, 
A.; GALIN, P.; GAGNE, G., 2000, p. 100). 

2.4.2 Escalonamento por job mais curto primeiro (SJF) 
O escalonamento por job mais curto primeiro (Shortest Job First – SJF) é uma disciplina 
de escalonamento não preemptiva na qual o escalonador seleciona o processo à espera com o 
menor tempo de execução estimado até a conclusão (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, 
D.  R.,  2005,  p.  218).  Se  dois  processos  tiverem  seus  próximos  surtos  de  UCP  de  mesma 
duração,  o  escalonamento  FIFO  será  utilizado  para  desempate.    Silberschatz,  A.,  Galin,  P.; 
Gagne, G. (2000, p. 100) observam que um termo mais apropriado seria próximo surto de UCP 
mais  curto,  porque  o  escalonamento  é  feito  examinando‐se  a  duração  do  próximo  surto  de 
UCP  de  um  processo,  em  vez  de  sua  duração  total.  Usa‐se,  no  entanto,  o  termo  SJF  porque 
muitas pessoas e livros didáticos referem‐se a esse tipo de disciplina de escalonamento como 
SJF.  

O SJF reduz o tempo médio de espera em relação ao FIFO (BRUNO, J.; COFFMAN JR., E. 
G.;  SETHI,  E.  R.,  1974,  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  218)13. 
Entretanto, a variância dos tempos de espera é maior (são mais imprevisíveis) do que no FIFO, 
especialmente para processos grandes (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 
218). 

O algoritmo de escalonamento SJF favorece processos curtos à custa dos mais longos. 
Muitos  projetistas  defendem  que,  quanto  mais  curto  o  processo,  melhor  serviço  deveria 
receber.  Outros  discordam  porque  essa  estratégia  não  incorpora  prioridades  (determinadas 
pela  importância  de  um  processo).  Processos  interativos  em  particular  tendem  a  ser  “mais 
curtos”  do  que  processos  orientados  a  processador,  portanto,  ainda  assim,  parece  que  essa 
disciplina  resultaria  em  bons  tempos  de  resposta  interativos.  O  problema  é  que  ela  é  não 
preemptiva,  por  isso,  em  geral,  processos  interativos  que  estão  chegando  não  receberão 
serviço imediato (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 218). 

Por  outro  lado,  Silberschatz,  A.,  Galin,  P.;  Gagne,  G.  (2000,  p.  102)  dizem  que  o  SJF 
também  pode  ser  implementado  de  forma  preemptiva.  A  opção  surge  quando  um  novo 
processo pode ter seu próximo surto de UCP mais curto do que o que restou do processo em 
execução no momento. Um algoritmo SJF preemptivo interromperá o processo em execução 
no momento, enquanto um algoritmo não preemptivo permitirá que o processo em execução 

                                                            
13
  BRUNO,  J.;  COFFMAN  JR.,  E.  G.;  SETHI,  E.  R.  “Scheduling  independent  tasks  to  reduce  mean  finishing  time”, 
Communications of the ACM, v. 17, nº 7, jul. 1974, p. 382‐387. 
no momento termine seu surto de computação. O escalonamento SJF preemptivo às vezes é 
chamado escalonamento menor‐tempo‐de‐execução‐restante. 

O SJF seleciona processos para atender de um modo que garanta que o próximo será 
concluído  e  sairá  do  sistema  tão  logo  seja  possível,  o  que  tende  a  reduzir  o  número  de 
processos à espera e também o número de processos que estão esperando atrás de processos 
grandes.  O  resultado  é  que  o  SJF  pode  minimizar  o  tempo  médio  de  espera  dos  processos à 
medida que esses passam pelo sistema (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 
218). 

Como exemplo, considere o seguinte conjunto de processos, com a duração do surto 
de UCP expressa em milissegundos. 

Tabela 2.2 – Duração de surtos da UCP, em milissegundos  

Processo  Duração de surto 
P1  6 
P2  8 
P3  7 
P4  3 
 

Usando o escalonamento SJF, poderíamos escalonar esses processos de acordo com o 
seguinte diagrama de Gantt: 

P4  P1  P3  P2 


0    3  9 16 24

O  tempo  de  espera  é  3  milissegundos  para  o  processo  P1,  16  milissegundos  para  o 
processo P2, 9 milissegundos para o processo P3 e 0 milissegundo para o processo P4. Assim, o 
tempo  de  espera  médio  é  (3  +  16  +  9  +  0)/4  =  7  milissegundos.  Se  tivesse  sido  utilizado  o 
esquema de escalonamento FIFO, o tempo de espera médio seria 10,25 milissegundos. 

O algoritmo de escalonamento SJF é comprovadamente ótimo, pois fornece o tempo 
médio de espera mínimo para um determinado conjunto de processos. Quando um processo 
curto é colocado antes de um processo longo, o tempo de espera do processo curto diminui 
mais do que aumenta o tempo de espera do processo longo. Conseqüentemente, o tempo de 
espera médio diminui (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 100‐101). 

Como  o  SJF  sempre  produz  o  menor  tempo  médio  de  resposta,  seria  ótimo  se  ele 
pudesse  ser  utilizado  para  processos  interativos  também.  Em  certa  medida,  ele  pode  ser 
utilizado.  Processos  interativos,  em  geral,  seguem  o  padrão  de  esperar  comando  ‐  executar 
comando – esperar comando – executar comando e assim por diante. Se fosse considerado a 
execução de cada comando como um “trabalho” independente, então poderíamos minimizar o 
tempo  total  de  resposta  para  executar  o  mais  curto  primeiro.  O  único  problema  é  descobrir 
qual dos processos atualmente é o mais curto (TANENBAUM; WOODHULL, 2000, p. 73). 

Realmente,  a  verdadeira  dificuldade  com  o  algoritmo  SJF  é  conhecer  a  duração  do 


próximo  pedido  de  UCP.  Para  o  escalonamento  de  longo  prazo  de  jobs  em  um  sistema  em 
batch,  pode‐se  usar  como  duração  o  limite  de  tempo  do  processo  que  um  determinado 
usuário  especifica  quando  submete  o  job.  Assim,  os  usuários  ficam  motivados  a  estimar  o 
limite  de  tempo  do  processo  com  precisão,  já  que  um  valor  menor  pode  significar  resposta 
mais rápida. Entretanto, um valor baixo demais poderá causar um erro de estouro do limite de 
tempo  e  exigir  nova  submissão  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G.,  2000,  p.  101). 
Portanto,  neste  caso,  o  SJF  precisa  confiar  em  estimativas  de  tempo  de  execução  fornecidas 
pelo  usuário  ou  pelo  sistema.  Em  ambientes  de  produção  em  que  os  mesmos  processos  são 
executados repetidamente, o sistema  pode ser capaz de  manter heurísticas razoáveis para o 
tempo de execução. Em ambientes de desenvolvimento, o usuário raramente sabe por quanto 
tempo um processo executará. Um outro problema de depender de estimativas de duração de 
processos usuários é que esses podem fornecer estimativas baixas (e talvez inexatas) para que 
o sistema atribua prioridades mais altas a seus programas. Todavia, se um processo executar 
por  mais  tempo  do  que  o  estimado,  o  sistema  poderá  termina‐lo  e  reduzir  a  prioridade  dos 
outros processos daquele usuário, até mesmo invocando penalidades. Um segundo método é 
executar  o  processo  pelo  tempo  estimado  mais  uma  pequena  porcentagem  extra  e,  então, 
“colocá‐lo na prateleira” (preservá‐lo na sua forma atual) para que o sistema possa reiniciá‐lo 
mais  tarde  (DEITEL,  H.  M.,  1968  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p. 
218)14. 

O  escalonamento  SJF  é  usado  freqüentemente  no  escalonamento  de  longo  prazo. 


Embora o algoritmo SJF seja ótimo, ele não pode ser implementado no nível do escalonamento 
de  UCP  de  curto  prazo  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G.,  2000,  p.  101).  Como 
discutido,  não  existe  como  saber  exatamente  a  duração  do  próximo  surto  de  UCP.  Uma 
alternativa  é  tentar  fazer  estimativas  com  base  no  comportamento  passado  e  executar  o 
processo com o menor tempo de execução estimado (TANENBAUM; WOODHULL, 2000, p. 73). 
O  próximo  surto  de  UCP  geralmente  é  previsto  como  uma  média  exponencial  das  durações 
                                                            
14
 DEITEL, H. M. “Absentee computations in a multiple access computer system”, M.I.T.Project MAC, MAC‐TR‐52 ‐‐‐ 
Agência de Projetos de Pesquisa Avançados, Departamento de Defesa dos Estados Unidos, 1968. 
medidas dos surtos de UCP anteriores. Seja tn a duração do enésimo surto de UCP e τn+1 o valor 
previsto para o próximo surto. Em seguida, para α, 0 ≤ α ≤ 1, define‐se 

τn+1 = αtn  + (1 – α)τn 

Essa fórmula define uma média exponencial. O valor de tn contém a informação mais 
recente; τn armazena o histórico. O parâmetro α controla o peso relativo do histórico recente e 
passado para a previsão. Se α = 0, τn+1  = τn  e o histórico recente não tem efeito (as condições 
atuais  são  consideradas  transitórias);  se  α  =  1,  então  τn+1  =  tn  e  apenas  o  surto  de  UCP  mais 
recente importa (o histórico é considerado velho e irrelevante). Mais comumente, α =  1/2, de 
modo que os históricos recente e passado têm peso igual. O τ0  inicial pode ser definido como 
uma  constante  ou  como  uma  média  geral  do  sistema.  A  figura  seguinte  mostra  uma  média 
exponencial com α = 1/2 e τ0 = 10. 

  Figura 2.2. Previsão da duração do próximo surto de UCP  

Para  entender  o  comportamento  da  média  exponencial,  expandimos  a  fórmula  para 


τn+1 substituindo τn para encontrar 

τn+1 = αtn  + (1 – α)αtn‐1 + ... + (1 – α)jαtn‐j + ... + (1 – α)n+1τ0 

Como α e (1 – α) são menores ou iguais a 1, cada termo sucessivo tem menos peso do 
que seu precedente. 

A  técnica  de  estimar  o  próximo  valor  em  uma  série  pegando  a  média  ponderada  do 
valor  atual  medido  e  a  estimativa  anterior  é,  às  vezes,  chamada  de  envelhecimento.  Ela  é 
aplicável  a  muitas  situações  nas  quais  uma  previsão  deve  ser  feita  com  base  em  valores 
anteriores. O envelhecimento é especialmente fácil de implementar quando α =  1/2. Tudo que 
é necessário é adicionar o novo valor à estimativa atual e dividir a soma por 2 (rotacionando‐o 
1 bit para direita) (TANENBAUM; WOODHULL, 2000, p. 73). 

Tanenbaum (2003, p. 103) e Tanenbaum; Woodhull (2000, p. 73) ressaltam que o SJF é 
adequado  somente  quando  todos  os  jobs  estiverem  disponíveis  simultaneamente.  Como  um 
contra‐exemplo,  considere  cinco  jobs,  de  A  a  E,  com  tempos  de  execução  2,  4,  1,  1,  e  1, 
respectivamente.  Seus  tempos  de  chegada  são  0,  0,  3,  3  e  3.  Inicialmente,  somente  A  ou  B 
podem ser escolhidos, já que outros três jobs ainda não chegaram. Usando o JSF, os jobs serão 
executados na ordem A, B, C, D, E para um tempo médio de espera 4,6. Contudo, executa‐los 
na ordem B, C, D, E, A implica em um tempo médio de espera de 4,4. 

Da  disciplina  SJF  derivou‐se  a  disciplina  processo‐mais‐curto‐primeiro  (Shortest‐


Process‐First  ‐  SPF),  que  segue  os  mesmos  princípios  de  funcionamento  de  seu  predecessor, 
mas ao invés de utilizar o conceito de job, utiliza o conceito de processo. Assim como o SJF, o 
SPF  também  é  claramente  inadequado  para  escalonamento  de  baixo  nível  em  sistemas 
operacionais modernos. Além disso, o SPF, assim como o FIFO e o SJF, é não preemptivo e, por 
isso,  não  é  adequado  para  ambientes  nos  quais  é  preciso  garantir  tempos  de  resposta 
razoáveis (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 218). 

2.4.3 Escalonamento por próxima taxa de resposta mais alta (HRRN) 
Brinch Hansen (1971, p. 103‐105 apud Deitel H. M.; Deitel, P. J.; Choffnes, D. R., 2005, 
p.  218‐219)15  desenvolveu  a  política  próxima‐taxa‐de‐resposta‐mais‐alta  (Highest  Response 
Ratio  Next  –  HRRN)  que  corrige  algumas  das  deficiências  do  SJF,  particularmente  o  viés 
excessivo  contra  processos  mais  longos  e  o  favoritismo  excessivo  em  relação  a  processos 
curtos.  A  HRRN  é  uma  disciplina  de  escalonamento  não  preemptiva  na  qual  a  prioridade  de 
cada processo é uma função não apenas do seu tempo de serviço, mas também do tempo que 
passou à espera pelo serviço. 

Uma  vez  obtido  o  serviço,  o  processo  executa  até  o  fim.  HRRN  calcula  prioridades 
dinâmicas segundo a fórmula: 

Prioridade = tempo de espera + tempo de serviço 
                         tempo de serviço 

                                                            
15
 BRINCH HANSEN, P. “Short‐term scheduling in multiprogramming systems”, Third ACM Symposium on Operating 
Systems Principles, Universidade de Stanford, out. 1971, p. 103‐105.  
Como  o  tempo  de  serviço  aparece  no  denominador,  processos  mais  curtos  recebem 
preferência.  Entretanto,  pelo  fato  de  o  tempo  de  espera  aparecer  no  numerador,  processos 
mais longos que estão à espera também receberão tratamento favorável. Essa técnica é similar 
ao  envelhecimento  (aging)  e  impede  que  um  escalonador  adie  processos  indefinidamente 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 219). 

2.4.4 Escalonamento por menor tempo de execução restante (SRT) 
O escalonamento por menor tempo de execução restante (Shortest Remaining Time – 
SRT),  também  conhecido  como  próximo  de  menor  tempo  restane  (Shortest  Remaining  Time 
Next ‐ SRTN), é a contraparte preemptiva do SJF que tenta aumentar o rendimento atendendo 
pequenos processos que chegam. O SRT era efetivo para sistemas de processamento de jobs 
que recebiam um fluxo de entrada de jobs; hoje já não tem mais utilidade para a maioria dos 
sistemas operacionais (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 219). Com esse 
algoritmo, o escalonador sempre escolhe o processo cujo tempo de execução restante seja o 
menor (TANENBAUM, 2003, p. 103). No SJF, quando um processo começa a executar, continua 
até o final. No SRT, um processo recém‐chegado cujo tempo estimado de execução até o final 
é  menor  provoca  a  preempção  de  um  processo  em  execução  cujo  tempo  estimado  de 
execução até o final é maior. Novamente, o SRT requer que as estimativas do comportamento 
futuro  do  processo  sejam  efetivas,  e  o  projetista  deve  levar  em  conta  o  potencial  abuso  da 
estratégia de escalonamento da parte do usuário (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 
2005, p. 219). 

Como exemplo, considere os quatro processos seguintes, com a duração do surto de 
UCP expressa em milissegundos: 

Tabela 2.3 – Duração de surtos da UCP em milissegundos e instantes de chegada de processos 

Processo  Instante de chegada  Duração de surto 


P1  0  8 
P2  1  4 
P3  2  9 
P4  3  5 
 

Se  os  processos  chegarem  na  fila  de  processos  prontos  nos  tempos  indicados  e 
precisarem dos tempos de surto a seguir, o escalonamento SRT resultante será o apresentado 
no diagrama de Gantt seguinte: 

P1  P2  P4  P1  P3 


0    1  5  10 17 26
O processo P1  é iniciado no instante 0, já que é o único processo da fila. O processo P2 
chega no instante 1. O tempo restante para o processo P1  (7 milissegundos) é maior do que o 
tempo exigido pelo processo P2 (4 milissegundos), de modo que o processo P1 é interrompido e 
o processo P2  é escalonado. O tempo de espera médio para esse exemplo é ((10 – 1) + (1 – 1) + 
(17  –  2)  +  (5  –  3))/4  =  26/4  =  6,5  milissegundos.  Um  escalonamento  SJF  resultaria  em  um 
tempo de espera médio de 7,75 milissegundos. 

O  algoritmo  SRT  deve  manter  informações  sobre  o  tempo  que  está  sendo  gasto  no 
serviço do processo em execução e realizar preempções ocasionais. Processos que acabaram 
de  chegar  cujos  tempos  de  execução  são  curtos  executam  quase  imediatamente.  Todavia,  o 
tempo  médio  de  espera  e  a  variância  dos  tempos  de  espera  dos  processos  mais  longos  são 
ainda maiores do que no SJF. Esses fatores contribuem para uma sobrecarga maior no SRT do 
que no SJF (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 219). 

O  algoritmo  SRT  teoricamente  oferece  tempos  de  espera  mínimos,  mas,  em  certas 
ocasiões,  devido  à  sobrecarga  de  preempção,  o  SJF  pode  se  sair  melhor.  Por  exemplo, 
considere  um  sistema  no  qual  um  processo  em  execução  esteja  quase  no  final  e  chegue  um 
novo processo cujo tempo estimado de serviço seja pequeno. O processo em execução deve 
sofrer  preempção?  A  disciplina  SRT  faria  preempção,  mas  essa  pode  não  ser  a  alternativa 
ótima.  Uma  solução  é  garantir  que  um  processo  em  execução  não  possa  mais  sofrer 
preempção  quando  o  tempo  de  execução  restante  atingir  um  determinado  nível  baixo.  Um 
problema  semelhante  surge  quando  um  processo  recém‐chegado  requer  um  tempo 
ligeiramente  menor  para  concluir  do  que  o  processo  em  execução.  Embora  o  algoritmo 
impusesse  corretamente  a  preempção  do  processo  em  execução,  essa  poderia  não  ser  a 
política ótima. Por exemplo, se a sobrecarga de preempção for maior do que a diferença dos 
tempos de serviço entre os dois processos, a preempção resultará em desempenhos inferiores 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 219). 

De  acordo  com  Deitel,  H.  M.;  Deitel,  P.  J.;  Choffnes  (2005,  p.  219),  como  esses 
exemplos  ilustram,  o  projetista  de  sistemas  operacionais  deve  pesar  cuidadosamente  a 
sobrecarga  de  mecanismos  de  gerenciamento  de  recursos  contra  os  benefícios  esperados. 
Observam também que políticas de escalonamento relativamente simples podem resultar em 
mau desempenho por razões sutis. 

2.4.5 Escalonamento em três níveis 
De um certo ponto de vista, os sistemas em lote permitem um escalonamento em três 
níveis  (Figura  2.3).  À  medida  que  chegam  ao  sistema,  os  jobs são  inicialmente  colocados  em 
uma  fila  de  entrada  armazenada  em  disco.  O  escalonador  de  admissão  decide  qual  job  será 
admitido no sistema. Os outros são mantidos na fila de entrada até que sejam selecionados. 
Um  algoritmo  típico  para  controle  de  admissão  pode  ser  pensado  com  uma  mescla  de  jobs 
orientados  a  computação  e  jobs  orientados  a  E/S.  Por  outro  lado,  jobs  curtos  poderiam  ser 
admitidos mais rapidamente, ao passo que jobs mais longos teriam de esperar. O escalonador 
de  admissão  é  livre  para  manter  alguns  jobs  na  fila  de  entrada  e  admitir  jobs  que  cheguem 
depois, se lhe convier (TANENBAUM, 2003, p. 103). 

 
Figura 2.3. Escalonamento em três níveis 
 

Assim que um job é admitido no sistema, um processo pode ser criado para ele, que 
passa então a competir pela UCP. Contudo, pode acontecer de o número de processos ser tão 
grande  que  não  haverá  lugar  suficiente  para  todos  na  memória.  Nesse  caso,  alguns  dos 
processos devem ser levados para o disco (swapped out). O segundo nível de escalonamento é 
que decide quais processos deverão ser mantidos na memória e quais permanecerão no disco 
e por isso pode ser denominado escalonador de memória. Essa decisão precisa ser revista com 
freqüência  para  permitir  que  os  processos  em  disco  obtenham  algum  serviço.  No  entanto, 
como  trazer  o  processo  do  disco  é  computacionalmente  caro,  essa  revisão  não  ocorrerá, 
provavelmente, mais que uma vez a cada segundo, talvez menos que isso. Se o conteúdo da 
memória  principal  estiver  muito  desorganizado,  uma  grande  parcela  da  largura  de  banda  de 
disco será gasta, tornando a E/S de arquivos lenta (TANENBAUM, 2003, p. 103). 

Segundo Tanenbaum (2003, p. 104), para otimizar o desempenho do sistema como um 
todo,  o  escalonador  de  memória  deve  decidir,  com  parcimônia,  quantos  processos  ele  quer 
manter na memória (ou seja, o grau de multiprogramação) e que tipo de processos. Se tiver 
informação  sobre  quais  processos  são  orientados  a  computação  e  a  E/S,  ele  poderá  tentar 
conservar  na  memória  uma  mistura  desses  tipos  de  processo.  Em  uma  aproximação  muito 
grosseira,  se  uma  certa  classe  de  processos  computa  por  aproximadamente  20%  do  tempo, 
manter  cerca  de  cinco  processos  é  uma  boa  aproximação  para  manter  a  UCP  ocupada. 
Tanenbaum  (2003,  p.  142)  ainda  ressalta  que  esse  é  um  modelo  otimista,  não  realista,  pois 
presume  que  os  cinco  processos  nunca  poderão  estar  ao  mesmo  tempo  esperando  por  E/S. 
Um  modelo  melhor  é  considerar  a  utilização  da  UCP  de  um  ponto  de  vista  probabilístico. 
Suponha que um processo gaste uma fração p de seu tempo esperando pela finalização de sua 
solicitação  de  E/S.  Com  n  processos  simultâneos  na  memória,  a  probabilidade  de  todos  os  n 
processos estarem esperando por E/S (nessa situação a UCP estaria ociosa) é pn. A utilização da 
UPC é então dada pela fórmula 

Utilização da UCP = 1 ‐ pn 

A figura que segue mostra a utilização da UCP em função de n, ou seja, do grau da 
multiprogramação. 

 
Figura 2.4. Utilização da UCP como uma função do número de processos na memória  
 

A figura deixa claro que, se os processos gastarem 80% de seus tempos esperando pela 
conclusão de E/S, no mínimo dez processos deveriam estar simultaneamente na memória para 
que o grau de ociosidade da UCP pudesse ser mantido abaixo de 10%. Tempos de espera iguais 
ou  superiores  a  80%  não  são  incomuns  em  um  processo  interativo  que  espera  um  usuário 
digitar algo em um terminal. Entretanto, mesmo em sistemas em lote, processos que realizam 
muitos  acessos  a  disco  poderão,  com  freqüência,  atingir  essa  porcentagem  ou  superá‐la 
(TANENBAUM, 2003, p. 142). 
Para  tomar  suas  decisões,  o  escalonador  de  memória  revisa  periodicamente  cada 
processo  que  está  no  disco  para  decidir  se  o  traz  ou  não  para  a  memória.  Entre  os  critérios 
utilizados para tomar essa decisão estão os seguintes: 

1. Há quanto tempo o processo passou por uma troca entre o disco e a 
memória (swapped in ou out)? 
2. Quanto tempo de UCP o processo teve da última vez? 
3. Qual o tamanho do processo? (Os pequenos não entram) 
4. Qual a importância do processo? 
O terceiro nível de escalonamento, na verdade, escolhe um dos processos prontos na 
memória principal para executá‐lo depois. Muitas vezes, esse nível é chamado de escalonador 
de UCP e é nele que normalmente se pensa quando se fala sobre o “escalonador”. Qualquer 
algoritmo adequado pode ser usado aqui, seja preemptivo ou não preemptivo (TANENBAUM, 
2003, p. 104). 

2.5 Escalonamento em sistemas interativos 
São  apresentados  alguns  algoritmos  aplicados  a  sistemas  interativos.  Todos  eles 
podem  também  ser  utilizados  como  escalonadores  de  UCP  em  sistemas  em  lote.  Se  por  um 
lado o escalonamento em três níveis não é adequado para sistemas interativos, por outro, o 
escalonamento  em  dois  níveis  (escalonador  de  memória  e  de  UCP)  não  só  é  possível  como 
também comum (TANENBAUM, 2003, p. 104). 

2.5.1 Escalonamento Round Robin 
 

Um  dos  algoritmos  de  escalonamento  mais  simples,  mais  antigos,  justo  e  mais 
amplamente  utilizado  é  o  Round  Robin  (RR),  também  chamado  de  revezamento  circular 
(TANENBAUM;  WOODHULL,  2000,  p.  70;  TANENBAUM,  2003,  p.  104).  O  RR  foi  projetado 
especialmente  para  sistemas  de  tempo  compartilhado.  Trata‐se  de  uma  política  de 
escalonamento  preemptiva.  É  semelhante  ao  escalonamento  FIFO,  mas  a  preempção  é 
acrescentada  para  alternar  entre  processos.  A  cada  processo  é  atribuído  um  pequeno 
quantum de tempo, geralmente entre 10 e 100 milissegundos, durante o qual lhe é permitido 
executar. A fila de processos prontos é tratada como uma fila circular. O escalonador de UCP 
percorre a fila de processos prontos, alocando a UCP a cada processo por intervalo de tempo 
de  até  1  quantum  de  tempo  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G.,  2000,  p.  103).  Se  o 
processo ainda está executando no fim do quantum, é feita a preempção da UCP e ela é dada a 
outro processo. Se o processo bloqueou ou terminou antes de o quantum ter se esgotado, é 
feita  a  comutação  da  UCP  quando  o  processo  bloqueia,  naturalmente.  Este  processo  é 
ilustrado na figura que segue. 

Figura 2.5. Escalonamento Round Robin 
 

A alternância circular é efetiva para ambientes interativos nos quais o sistema precisa 
garantir tempos de resposta razoáveis. O sistema pode minimizar a sobrecarga de preempção 
por meio de mecanismos eficientes de chaveamento de contexto e mantendo os processos na 
memória principal (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 216). 

Como o FIFO, a alternância circular é comumente encontrada dentro de algoritmos de 
escalonamento de processador mais sofisticados, mas raramente é o esquema mestre. Muitos 
outros  algoritmos  sofisticados  de  escalonamento  de  UCP  degeneram  para  FIFO  ou  para 
alternância circular, quando todos os processos têm a mesma prioridade. Por essa razão, FIFO 
e RR são dois dos três algoritmos de escalonamento requeridos pela especificação POSIX para 
sistemas de tempo real (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 216). 

O RR é fácil de implementar. Tudo que é necessário que o escalonador faça é manter 
uma lista de processos prontos como uma fila FIFO. O escalonador então seleciona o primeiro 
processo da fila, define um temporizador para interromper depois de 1 quantum e submete o 
processo, como mostrado na Figura 2.6(a). Quando o processo utiliza todo seu quantum, ele é 
posto  no  fim  da  lista,  como  ilustrado  na  Figura  2.6(b)  (TANENBAUM,  2003,  P.  104; 
SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 103). 

Figura 2.6. Agendamento Round Robin. (a) Lista de processos executáveis. (b) Lista de processos 
executáveis depois que B utiliza todo seu quantum  
Como  dito  anteriormente,  neste  momento,  duas  opções  podem  ocorrer.  O  processo 
poderá ter um surto de UCP de menos de 1 quantum. Nesse caso, o próprio processo liberará a 
UCP  voluntariamente.  O  escalonador  procederá  então  para  o  próximo  processo  na  fila  de 
processos prontos. Caso contrário, se o surto de UCP do processo em execução no momento 
for maior do que 1 quantum de tempo, o temporizador se esgotará e causará um interrupção 
para o sistema operacional. Uma troca de contexto será executada, e o processo será colocado 
no  final  da  fila  de  processos  prontos.  O  escalonador  de  UCP  selecionará  então  o  próximo 
processo da fila. No algoritmo de escalonamento RR, nenhum processo recebe UCP por mais 
do  que  1  quantum  de  tempo  consecutivo,  a  menos  que  seja  o  único  processo  pronto 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 104). 

Uma  questão  importante  para  o  escalonamento  RR  é  o  tamanho  do  quantum  que  é 
atribuído  aos  processos  (TANENBAUM,  2003,  p.  104).  A  determinação  do  tamanho  do 
quantum,  q,  é  crítica  para  a  operação  efetiva  de  um  sistema  de  computação  com 
escalonamento preemptivo (POTIER, D; GELENBE, E.; LENFANT,  J., 1976  apud DEITEL, H.  M.; 
DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 217)16. O quantum deve ser pequeno ou grande? Deve 
ser  fixo  ou  variável?  Deve  ser  o  mesmo  para  todos  os  processos  ou  deve  ser  determinado 
separadamente para cada processo? Primeiro, considere o comportamento do sistema quando 
o  quantum  torna‐se  extremamente  grande  ou  extremamente  pequeno.  À  medida  que  o 
quantum torna‐se grande, processos tendem a receber o tempo que precisam para concluir, 
portanto, o esquema RR degenera para FIFO. À medida que o quantum torna‐se pequeno,  o 
chaveamento de contexto predomina; o desempenho eventualmente se degrada até o ponto 
em  que  o  sistema  passa  grande  parte  de  seu  tempo  fazendo  chaveamento  de  contexto  e 
realizando pouco, ou nenhum, trabalho (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 
217). 

Exatamente onde, entre zero e infinito, o quantum deve ser estabelecido? Considere o 
seguinte experimento. Suponha que os valores estampados na face de um mostrador circular 
variem  entre  q  =  0  e  q  =  c,  onde  c  é  um  valor  extremamente  grande.  O  mostrador  inicia‐se 
posicionado  em  zero.  À  medida  que  gira‐se  o  mostrador,  o  quantum  do  sistema  aumenta. 
Suponha  que  o  sistema  esteja  em  funcionamento  e  que  haja  muitos  processos  interativos. 
Quando  começa‐se  a  girar  o  mostrador,  os  tamanhos  dos  quanta  estão  perto  de  zero  e  a 
sobrecarga  de  chaveamento  de  contexto  consome  a  maioria  dos  cliclos  do  processador.  Os 
usuários  interativos  defrontam‐se  com  um  sistema  vagaroso  com  tempos  de  resposta  ruins. 
                                                            
16
 POTIER, D.; GELENBE, E.; LENFANT, J. “Adaptative allocation of central processing unit Quant”, Journal of the ACM, 
v. 23, nº 1, jan. 1976, p. 97‐102. 
Conforme  aumenta‐se  o  quantum,  os  tempos  de  resposta  melhoram.  A  porcentagem  do 
processador  consumida  por  sobrecarga  é  suficientemente  pequena  para  que  os  processos 
recebam um pouco de serviço do processador, mas os tempos de resposta ainda não estão tão 
rápidos quanto cada usuário gostaria. Ao continuar a girar o mostrador, os tempos de resposta 
melhoram  e,  eventualmente,  alcança‐se  um  tamanho  de  quantum  com  o  qual  grande  parte 
dos processos interativos recebe resposta imediatas do sistema, mas ainda não está claro se o 
ajuste  do  quantum  é  ótimo.  Girando  o  mostrador  um  pouquinho  mais,  e  os  tempos  de 
resposta  ficam  ligeiramente  melhores.  Girando  o  mostrador  novamente,  e  os  tempos  de 
resposta voltam a ficar vagarosos. O quantum vai ficando maior até que eventualmente torna‐
se grande o suficiente para que cada processo execute até o final após receber o processador. 
O escalonamento está degenerando para FIFO, pelo qual processos mais longos fazem os mais 
curtos  esperar,  e  o  tempo  médio  de  espera  aumenta  enquanto  processos  mais  longos 
executam  até  a  finalização  antes  de  devolver  o  processador  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 217). 

A alternância de um processo para outro requer uma certa quantidade de tempo para 
sua administração – salvar e carregar registradores e mapas de memória, atualizar várias listas 
e  tabelas,  carregar  e  descarregar  a  memória  cache  etc.  Suponha  que  esse  chaveamento  de 
contexto dure 1 ms e que o comprimento do quantum seja de 4 ms. Dessa forma, depois de 
realizar  4  ms  de  trabalho  útil,  a  UCP  terá  de  gastar  1  ms  para  alternar  o  processo.  Nesse 
exemplo,  20%  do  tempo  de  UCP  é  gasto  em  administração,  o  que  sem  dúvida  é  demais 
(TANENBAUM, 2003, p. 104). 

Para  melhorar  a  eficiência  da  UCP,  pode‐se  estabelecer  o  valor  do  quantum  em  100 
ms,  por  exemplo.  Agora,  o  tempo  gasto  com  chaveamento  de  contexto  é  de  apenas  1%.  No 
entanto,  considere  o  que  pode  acontecer  em  um  sistema  de  tempo  compartilhado  se  dez 
usuários  interativos  clicarem  a  tecla  <Enter>  quase  ao  mesmo  tempo.  Dez  processos  serão 
colocados na lista de processos executáveis. Se a UCP estiver ociosa, o primeiro dos processos 
iniciará  imediatamente,  o  segundo  não  poderá  iniciar  enquanto  não  se  passarem  100  ms  e 
assim  por  diante.  O  último  azarado  pode  ter  de  esperar  um  segundo  antes  de  ter  uma 
oportunidade para executar – supondo que todos os outros usem inteiramente seus quanta. A 
maioria dos usuários verá como problema uma resposta para um pequeno comando demorar 
um segundo (TANENBAUM, 2003, p. 105). 

Por curiosidade, no Linux, o quantum‐padrão designado para um processo é 100 ms, 
podendo  variar  de  10  ms  a  200  ms  dependendo  da  prioridade  e  do  comportamento  do 
processo.  Processos  de  alta  prioridade  e  processos  orientados  a  E/S  recebem  um  quantum 
maior do que processos de baixa prioridade e processos orientados a UCP (LINUX apud DEITEL, 
H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  217)17.  No  Windows  XP,  o  quantum‐padrão 
designado  a  um  processo  é  um  valor  específica  da  arquitetura  igual  a  20  ms  na  maioria  dos 
sistemas. Esse valor pode variar dependendo de o processo executar no primeiro plano ou no 
segundo plano da GUI (SOLOMON, D.; RUSSINOVICH, M., 2000 apud DEITEL, H. M.; DEITEL, P. 
J.; CHOFFNES, D. R., 2005, p. 217)18. 

Se  houver  n  processos  na  fila  de  processo  prontos  e  o  quantum  for  q,  então  cada 
processo  obterá  1/n  do  tempo  de  UCP  em  lotes  de  no  máximo  q  unidades  de  tempo.  Cada 
processo deve esperar no máximo (n ‐ 1) x q unidades de tempo até seu próximo quantum. Por 
exemplo,  se  houver  5  processos  com  um  quantum  de  tempo  de  20  milissegundos,  cada 
processo obterá até 20 milissegundos a cada 100 milissegundos (SILBERSCHATZ, A.; GALIN, P.; 
GAGNE, G., 2000, p. 104). 

O  tempo  de  espera  médio  na  política  RR,  no  entanto,  é  geralmente  longo. 
Considerando  o  seguinte  conjunto  de  processos  que  chegam  no  instante  0,  com  duração  de 
surto de UCP expressa em milissegundos: 

Tabela 2.4 ‐  Duração de surtos da UCP, em milissegundos  

Processo  Duração de surto 
P1  24 
P2  3 
P3  3 
 

Com  um  quantum  de  4  milissegundos,  o  processo  P1  obtém  os  4  primeiros 
milissegundos.  Como  mais  20  milissegundos  são  necessários,  ele  será  interrompido  após  o 
primeiro quantum de tempo, e a UCP será passada ao próximo processo na fila, o processo P2. 
Como  o  processo  P2  não  precisa  de  4  milissegundos,  ele  encerra  antes  que  o  seu  quantum 
expire.  A  UCP  é  então  passada  para  o  próximo  processo,  o  processo  P3.  Assim  que  cada 
processo  tiver  recebido  1  quantum,  a  UCP  é  retornada  ao  processo  P1  para  uma  quantum 
adicional. O escalonamento RR resultante é esquematizado no gráfico de Gantt abaixo: 

P1  P2  P3  P1  P1  P1  P1  P1 


0    4  7  10 14 18 22 26  30

                                                            
17
  LINUX  source  code,  version  2.6.0‐test3,  sched.c,  linhas  62‐135, 
miller.cs.wm.edu/lxr3.linux/http/source/kernel/sched.c?v=2.6.0‐test3. 
18
 SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000. 3 ed. Redmond: Microsoft Press, 2000, p. 338‐347. 
O tempo de espera médio para este caso é 17/3 = 5,66 milissegundos. 

Outro ponto importante a considerar é que o desempenho do algoritmo RR depende 
muito do tamanho do quantum de tempo. Se o quantum for maior que o surto médio de UCP, 
a preempção raramente ocorrerá e a regra de RR será a mesma que a regra FIFO. Na verdade, 
a maior parte dos processos bloqueará antes que o quantum acabe, causando uma alternância 
de processo. Eliminar a preempção melhora o desempenho porque a alternância de processo 
somente ocorre quando é logicamente necessária, isto é, quando um processo bloqueia e não 
é mais capaz de continuar (TANENBAUM, 2003, p. 105; SILBERSCHATZ, A.; GALIN, P.; GAGNE, 
G.,  2000,  p.  104).  Por  outro  lado,  se  o  quantum  de  tempo  for  extremamente  pequeno  (por 
exemplo,  1  microssegundo),  a  abordagem  RR  será  chamada  de  compartilhamento  de 
processador  e,  para  os  usuários,  é  como  se  em  teoria  cada  um  dos  n  processos  tivesse  seu 
próprio  processador  executando  a  1/n  da  velocidade  do  processador  real.  A  abordagem  foi 
usada  no  hardware  da  Control  Data  Corporation  (CDC)  para  implementar  10  processadores 
periféricos com apenas um conjunto de hardware e 10 conjuntos de registradores. O hardware 
executa uma instrução para um conjunto de registradores e passa para o próximo. Esse ciclo 
continua, resultando em 10 processadores lentos em vez de um rápido. (Na verdade, como o 
processador  era  muito  mais  rápido  do  que  a  memória  e  cada  instrução  referenciava  a 
memória, os processadores não eram muito mais lentos do que 10 processadores reais teriam 
sido.) (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 104). 

Como  já  citado,  no  software,  no  entanto,  também  precisa‐se  considerar  o  efeito  da 
troca  de  contexto  no  desempenho  do  escalonamento  RR.  Suponha  que  exista  apenas  um 
processo  com  10  unidades  de  tempo.  Se  o  quantum  for  12  unidades  de  tempo,  o  processo 
terminará em menos de 1 quantum, sem custo adicional. Se o quantum for de 6 unidades de 
tempo,  entretanto,  o  processo  exigirá  2  quanta,  resultando  em  uma  troca  de  contexto.  Se  o 
quantum for 1 unidade de tempo, novo troca de contexto ocorrerão, tornando a execução do 
processo  mais  lenta,  como  ilustrado  na  Figura  2.7  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G., 
2000, p. 104). 
 

Figura 2.7.  A forma como um quantum de tempo menor aumenta as trocas de contexto 

Dessa forma, o quantum deve ser grande com relação ao tempo de troca de contexto. 
Se o tempo de troca for de cerca de 10% do quantum, então cerca de 10% do tempo de UCP 
será gasto em troca de contexto (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 105). 

O  tempo  de  retorno  também  depende  do  tamanho  do  quantum.  Como  pode‐se 
observar na Figura 2.8, o tempo de retorno médio de um conjunto de processos não melhora 
necessariamente  à  medida  que  o  quantum  aumenta.  Em  geral,  o  tempo  de  retorno  médio 
pode  ser  melhorado  se  a  maioria  dos  processos  terminar  seu  próximo  surto  de  UCP  em  um 
único  quantum.  Por  exemplo,  dados  três  processos  com  10  unidades  de  tempo  cada  e  um 
quantum de  1 unidade de tempo, o tempo de retorno médio é 29. Se o quantum for 10, no 
entanto, o tempo de retorno cairá para 20. Se o tempo de troca de contexto for acrescentado, 
o tempo médio aumentará para um quantum menor, já que um número maior de trocas de 
contexto será necessário (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 105). 

Figura 2.8. A forma como o tempo de retorno varia com a duração do quantum 

 
Assim, adotar um quantum muito curto causa muitas alternâncias de processo e reduz 
a  eficiência  da  UCP,  mas  um  quantum  muito  longo  pode  gerar  uma  resposta  pobre  às 
requisições interativas curtas e o RR degenera para a política FIFO. Tanenbaum (2003, p. 105) 
considera  que  um  quantum  em  torno  de  20  a  50  ms  é  bastante  razoável.  Silberschatz,  A.; 
Galin, P.; Gagne, G. (2000, p. 105) observam que uma regra geral é que 80% do surtos de UCP 
devem ser menores do que o quantum de tempo para tempos de resposta aceitáveis. 

2.5.2 Escalonamento por Prioridades 
O  algoritmos  SJF  é  um  caso  especial  do  algoritmo  geral  de  escalonamento  por 
prioridade. Uma prioridade está associada a cada processo, e a UCP é alocada ao processo com 
prioridade mais alta (Figura 2.9). Processos de prioridade igual são escalonados na ordem FIFO. 
Um algoritmo SJF nada mais é do que um algoritmo por prioridade no qual a prioridade (p) é o 
inverso do próximo surto de UCP previsto. Quanto maior o surto, menor a prioridade, e vice‐
versa (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 102). 

Figura 2.9. Escalonamento por prioridades 
Figura 2.9. Escalonamento por prioridades

O  escalonamento  RR  pressupõe  que  todos  os  processos  sejam  igualmente 


importantes.  É  freqüente  as  pessoas  que  possuem  e  operam  computadores  multiusuários 
pensarem  de  modo  diferente  sobre  o  assunto.  Da  necessidade  de  se  considerarem  fatores 
externos  resulta  o  escalonamento  por  prioridades.  A  idéia  é  simplória:  a  cada  processo  é 
atribuída  um  prioridade  e  ao  processo  executável  com  a  prioridade  mais  alta  é  permitido 
executar (TANENBAUM, 2003, p. 105; TANENBAUM; WOODHULL, 2000, p. 71). 
Mesmo em um PC com um único proprietário, pode haver múltiplos processos, alguns 
mais  importantes  que  outros.  No  Unix,  por  exemplo,  a  um  processo  daemon  que  envia 
mensagens  de  correio  eletrônico  em  segundo  plano  deve  ser  atribuída  uma  prioridade  mais 
baixa que a um processo que exibe um vídeo na tela em tempo real. Para evitar que processos 
de  alta  prioridade  executem  indefinidamente,  o  escalonador  pode  reduzir  a  prioridade  do 
processo  em  execução  a  cada  interrupção  de  relógio.  Se  isso  fizer  que  sua  prioridade  caia 
abaixo  da  prioridade  do  próximo  processo  com  prioridade  mais  alta,  então  ocorrerá  uma 
alternância  de  processo.  De  outro  modo,  a  cada  processo  pode  ser  atribuído  um  quantum 
máximo  no  qual  ele  pode  executar.  Quando  esse  quantum  estiver  esgotado,  será  dada  a 
oportunidade para que o próximo processo com prioridade mais alta execute (TANENBAUM, 
2003, p. 105). 

Discute‐se  o  escalonamento  em  termos  de  alta  e  baixa  prioridade.  Silberschatz,  A.; 
Galin, P.; Gagne, G. (2000, p. 102) observam que as prioridades em geral estão em uma faixa 
fixa de números, tais como 0 a 7, ou 0 a 4095. No entanto, não existe consenso geral sobre se 
0  é  a  prioridade  mais  alta  ou  mais  baixa.  Alguns  sistemas  usam  números  baixos  para 
representar baixa prioridade; outros usam números baixos para alta prioridade. Essa diferença 
pode  levar  à  confusão.  Neste  texto,  considera‐se  que  os  números  baixos  representam  baixa 
prioridade. 

Como  um  exemplo,  considerando  o  seguinte  conjunto  de  processos,  que  têm  seu 
instante  de  chegada  definido  em  0,  na  ordem  P1,  P2,  ...,  P5,  com  a  duração  do  surto  de  UCP 
expressa em milissegundos: 

Tabela 2.5 ‐ Duração de surtos da UCP, em milissegundos e prioridades 

Processo  Duração de surto  Prioridade 


P1  10  3 
P2  1   5 
P3  2   2 
P4  1  1 
P5  5  4 
 

Usando  o  escalonamento  por  prioridade,  esses  processos  seriam  escalonados  de 


acordo com o seguinte diagrama de Gantt: 

P2  P5  P1  P3  P4 


0    1  6  16 18  19
O tempo de espera médio é de 8,2 milissegundos. 

Prioridades podem ser atribuídas estatística ou dinamicamente aos processos a partir 
de  fatores  internos  ou  externos  ao  sistema.  As  prioridades  definidas  internamente  utilizam 
alguma  quantidade  ou  quantidades  mensuráveis  a  fim  de  calcular  a  prioridade  de  um 
processo.  Por  exemplo,  os  limites  de  tempo,  requisitos  de  memória,  o  número  de  arquivos 
abertos  e  a  razão  entre  os  surtos  de  E/S  e  UCP  médios  têm  sido  usados  no  cálculo  de 
prioridades. As prioridades externas são definidas pro critérios que são externos aos sistema 
operacional, tais como a importância do processo, o tipo e a quantidade de fundos pagos para 
uso  do  computador,  o  departamento  patrocinando  o  trabalho  e  outros  fatores,  geralmente 
políticos.  Exemplificando,  em  um  computador  militar,  os  processos  iniciados  por  generais 
podem partir com prioridade 100; os processos iniciados por coronéis, em 90; os de majores, 
em 80; os de capitães, em 70; os de tenentes, em 60 e assim por diante. Assim, em um centro 
de  computação  comercial,  trabalhos  de  alta  prioridade  podem  custar  cem  dólares  por  uma 
hora; um de prioridade média, 75 dólares por hora, e os de prioridade baixa, 50 dólares pelo 
mesmo período. O sistema Unix tem um comando, nice, que permite que um usuário reduza 
voluntariamente  a  prioridade  de  seu  processo  e  assim  seja  gentil  com  os  outros  usuários. 
Ninguém usa esse comando (TANENBAUM, 2003, p. 105; SILBERSCHATZ, A.; GALIN, P.; GAGNE, 
G., 2000, p. 103).   

O  sistema  também  pode  atribuir  dinamicamente  as  prioridades  para  atingir  certos 
objetivos.  Por  exemplo,  alguns  processos  são  altamente  orientados  a  E/S  e  gastam  a  maior 
parte de seu tempo esperando que um E/S termine. Se um processo como esse requisitasse a 
UCP, ela deveria ser dada a ele imediatamente, para deixá‐lo iniciar sua próxima requisição de 
E/S, a qual poderia então continuar em paralelo com outro processo que estivesse realmente 
computando. Fazer o processo orientado a E/S esperar um longo tempo pelo UCP significa tê‐
lo ocupando a memória desnecessariamente por tempo demais. Um algoritmo simples e que 
funciona bem para processos orientados a E/S é atribuir 1/f à prioridade, sendo f a fração do 
último quantum que o processo usou. Um processo que tivesse utilizado somente 1 ms de seu 
quantum de 50 ms obteria prioridade 50 (já que ele utilizou 1/50 ms de seu último quantum, 
logo 1/(1/50) = 50 ms), enquanto  um processo que houvesse consumido todo o quantum teria 
prioridade 1 (TANENBAUM, 2003, p. 105). 

O escalonamento por prioridade pode ser preemptivo ou não preemptivo. Quando um 
processo chega na fila de processos prontos, sua prioridade é comparada com a prioridade do 
processo  em  execução  no  momento.  Um  algoritmo  de  escalonamento  por  prioridade 
preemptivo interromperá a UCP se a prioridade do processo recém‐chegado for maior do que 
a  prioridade  do  processo  em  execução  no  momento.  Um  algoritmo  de  escalonamento  não 
preemptivo  simplesmente  colocará  o  novo  processo  no  topo  da  fila  de  processos  prontos 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 103). 

É  muitas  vezes  conveniente  agrupar  processos  em  classes  de  prioridade  e  usar  o 
escalonamento  por  prioridade  entre  as  classes  –  contudo,  dentro  de  cada  classe,  usar  o 
escalonamento circular. A Figura 2.10  mostra um sistema com quatro classes de prioridade. O 
algoritmo  de  escalonamento  é  o  seguinte:  enquanto  houver  processos  executáveis  na  classe 
de prioridade 4, execute apenas um por quantum em RR e nunca perca tempo com as classes 
de  baixa  prioridade.  Se  a  classe  de  prioridade  4  estiver  vazia  (sem  processos  para  executar), 
então  execute  os  processos  da  classe  3  em  RR.  Se  as  classes  4  e  3  estiverem  ambas  vazias, 
então  execute  a  classe  2  em  RR  e  assim  por  diante.  Se  as  prioridades  não  forem 
ocasionalmente ajustadas, as classes de prioridade mais baixas poderão todas morrer de fome 

(TANENBAUM, 2003, p. 105‐106). 

 
Figura 2.10. Um algoritmo de escalonamento com quatro classes de prioridade 

Um problema crítico com os algoritmos de escalonamento por prioridade é o bloqueio 
por tempo indefinido ou starvation (estagnação).  Um processo que está pronto para executar 
mas que não tem a UCP pode ser considerado bloqueado, esperando pela UCP. Um algoritmo 
de  escalonamento  por  prioridade  pode  deixar  que  alguns  processos  de  baixa  prioridade 
fiquem  esperando  indefinidamente  pela  UCP.  Em  um  sistema  de  computação  altamente 
carregado,  um  fluxo  constante  de  processos  de  maior  prioridade  pode  impedir  que  um 
processo  de  baixa  prioridade  obtenha  a  UCP.  Geralmente,  ocorre  uma  de  duas  opções.  O 
processo  acabará  sendo  executado  tardiamente,  quando  o  sistema  finalmente  ficar  com 
menos carga, ou o sistema de computador acabará falhando e perderá todos os processos de 
baixa  prioridade  não  terminados.  (Há  boatos,  inclusive,  que  quando  o  IBM  7094  do  MIT  foi 
desligado em 1973, encontraram um processo de baixa prioridade que  tinha sido submetido 
em  1967  e  que  ainda  não  tinha  sido  executado)  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G., 
2000, p. 103) 

Uma solução para o problema do bloqueio indefinido de processo de baixa prioridade 
é o envelhecimento (aging). O envelhecimento é uma técnica para aumentar gradualmente a 
prioridade dos processos que ficam esperando no sistema durante muito tempo. Por exemplo, 
se as prioridades tiverem uma faixa de  0 (baixa) a  127 (alta), pode‐se aumentar a prioridade 
de  um  processo  em  espera  em  espera  em  1  ponto  a  cada  15  minutos.  Por  fim,  mesmo  um 
processo com prioridade inicial 0 teria a maior prioridade no sistema e poderia ser executado. 
Na verdade, bastariam 32 horas para um processo de prioridade 0 passar para um processo de 
prioridade 127 (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 103). 

2.5.2.1 Alternância Circular Egoísta 

Kleinrock (1970 apud Deitel H. M.; Deitel, P. J.; Choffnes, D. R., 2005, p. 216) discutiu 
uma  variante  da  alternância  circular  denominada  alternância  circular  egoísta  (Selfish  Round 
Robin  ‐  SRR)  que  usa  o  envelhecimento  para  elevar  gradativamente  as  prioridades  dos 
processos ao longo do tempo19. 

Nesse esquema, ao entrar em um sistema, cada processo fica primeiramente em uma 
fila de retenção onde envelhece até sua prioridade atingir o nível dos processos que estão na 
fila  ativa.  Nesse  ponto  ele  é  passado  para  a  fila  ativa  e  escalonado  por  RR  juntamente  com 
outros processos que também estão na fila ativa, o que significa que processos mais velhos são 
favorecidos  sobre  os  que  acabaram  de  entrar  no  sistema  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 216). 

Na SSR, a prioridade de um processo aumenta a uma taxa a enquanto está na fila de 
espera, e a uma taxa b, onde b ≤ a, quando está na fila ativa. Quando b < a, os processos da fila 
de  retenção  envelhecem  a  uma  taxa  mais  alta  do  que  os  que  estão  na  fila  ativa,  portanto, 
eventualmente entrarão na fila ativa e disputarão um processador. O ajuste dos parâmetros a 
e  b  causa  impacto  sobre  o  modo  como  a  idade  de  um  processo  afeta  a  latência  média  e  o 
rendimento. Por exemplo, à medida que a fica muito maior do que b, os processos que entram 
                                                            
19
 KLEINROCK, L. “A continuum of time‐sharing scheduling algorithms”, Proceedings of AFIPS, SJCC, 1970, p. 453‐458. 
no  sistema  passarão  pouco  tempo,  ou  nenhum,  na  fila  de  retenção.  Se  b  <<  a,  os  processos 
passarão  uma  quantidade  insignificante  de  tempo  na  fila  de  retenção,  portanto,  a  SRR 
degenera para RR. Se b = a, cada processo do sistema funciona à mesma taxa, portanto, SRR 
degenera para FIFO (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 216‐217). 

2.5.3 Escalonamento por Múltiplas Filas 
Outra  classe  de  algoritmos  de  escalonamento  foi  criada  para  situações  em  que  os 
processos são facilmente classificados em diferentes grupos. Por exemplo, uma divisão comum 
é feita entre processos de primeiro plano (interativos) e processos de segundo plano (batch). 
Esses  dois  tipos  de  processos  têm  diferentes  requisitos  de  tempo  de  resposta  e,  por  isso, 
podem  ter  diferentes  necessidades  de  escalonamento.  Além  disso,  os  processos  de  primeiro 
plano  podem  ter  prioridade  (extremamente  definida)  em  relação  aos  processos  de  segundo 
plano (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 105). 

Um dos primeiros escalonadores por prioridades foi implementado no CTSS (CORBATÓ 
et al., 1962 apud TANENBAUM, 2003, p. 106)20. O CTSS tinha um problema: a alternância de 
processo  era  muito  lenta  porque  o  7094  só  podia manter  na  memória  um  processo  por vez. 
Cada  alternância  significava  trocar  o  processo,  ou  seja,  enviá‐lo  para  o  disco  e  ler  outro  do 
disco. Os projetistas do CTSS logo perceberam  que era mais eficiente dar de vez em quando 
um quantum grande para os processos orientados a UCP do que fornecer freqüentemente um 
quantum pequeno (para reduzir as operações de troca entre o disco e a memória). Por outro 
lado,  dar  a  todos  os  processos  um  quantum  grande  significaria  ter  um  tempo  de  resposta 
inadequado, conforme visto anteriormente. A solução, então, foi definir classes de prioridade. 
Os  processos  na  classe  de  prioridade  mais  alta  eram  executados  por  um  quantum.  Os 
processos  na  classe  seguinte  de  prioridade  mais  alta  executavam  por  dois  quanta.  Os 
processos  na  próxima  classe  executavam  por  quatro  quanta  e  assim  por  diante.  Se  um 
processo  terminasse,  todos  os  quanta  a  ele  alocados  iriam  para  uma  classe  abaixo 
(TANENBAUM, 2003, p. 106). 

Como exemplo, imagine um processo que precisasse computar continuamente por 100 
quanta. Inicialmente, a ele seria dado um quantum, e ele então seria levado da memória para 
o disco (troca para o disco). Na vez seguinte ele teria dois quanta antes de ocorrer a troca para 
o disco. As próximas execuções obteriam 4, 8, 16, 32 e 64 quanta, embora ele tivesse usado 
apenas 37 dos últimos 64 quanta para realizar seu trabalho. Seriam necessárias somente sete 
trocas entre a memória e o disco (incluindo a carga inicial), em vez de cem para um algoritmo 
                                                            
20
 CORBATÓ, F. J.; MERWIN‐DAGGETT, M.; DALEY, R. C. “An experimental time‐sharing system”,  Proc. AFIPS Fall Joint 
Computer Conf., AFIPS, 1962, p. 335‐344. 
puramente  circular.  Além  disso,  à  medida  que  o  processo  se  aprofundasse  mais  nas  filas  de 
prioridade,  ele  seria  cada  vez  menos  freqüentemente  executado,  liberando  a  UCP  para 
processos interativos e rápidos (TANENBAUM, 2003, p. 106). 

Assim,  um  algoritmo  de  escalonamento  por  múltiplas  filas  divide  a  fila  de  processos 
prontos em várias filas separadas (Figura 2.11). Os processos são permanentemente atribuídos 
a uma fila, geralmente com base em alguma propriedade do processo, tais como tamanho da 
memória, prioridade do processo ou tipo de processo. Cada fila tem seu próprio algoritmo de 
escalonamento. Por exemplo, filas separadas podem ser usadas para processos de primeiro e 
segundo planos. Afila de primeiro plano pode ser escalonada por um algoritmo RR, enquanto a 
fila  de  segundo  plano  é  escalonada  por  um  algoritmo  FIFO  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 106). 

Figura 2.11. Escalonamento por múltiplas filas 

Além  disso,  deve  haver  escalonamento  entre  as  filas,  que  é  normalmente 
implementado  como  escalonamento  preemptivo  de  prioridade  fixa.  Por  exemplo,  a  fila  de 
primeiro plano pode ter prioridade absoluta sobre a fila de segundo plano (SILBERSCHATZ, A.; 
GALIN, P.; GAGNE, G., 2000, p. 106).  

Analisando  um  exemplo  de  um  algoritmo  de  escalonamento  por  múltiplas  filas  com 
cinco filas com prioridade descendente: 

1. Processos do sistema 
2. Processos interativos 
3. Processos de edição interativa 
4. Processos em batch 
5. Processos secundários 

Cada  fila  tem  prioridade  absoluta  sobre  as  filas  de  menor  prioridade.  Nenhum 
processo na fila batch, por exemplo, poderia executar a menos que as filas para os processos 
do sistema, processos interativos e processos de edição interativa estivessem todas vazias. Se 
um processo de edição interativa entrasse na fila de processos prontos enquanto um processo 
em batch estivesse executando, o processo em batch seria interrompido. Outra possibilidade é 
fracionar o tempo entre as filas. Cada fila obtém uma certa parte do tempo de UCP, que pode 
então  ser  escalonado  entre  os  vários  processos  na  fila.  Por  exemplo,  no  exemplo  de  fila  de 
primeiro e segundo planos, a fila de primeiro plano pode receber 80% do tempo de UCP para o 
escalonamento RR entre seus processos, enquanto a fila de segundo plano recebe 20% da UCP 
para dar aos seus processos de modo FIFO (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 
106). 

Para  impedir  uma  longa  punição  de  um  processo  que,  quando  iniciado  pela  primeira 
vez,  precisasse  executar  por  um  longo  intervalo  de  tempo,  mas  que  depois  se  tornasse 
interativo,  adotou‐se  a  seguinte  estratégia:  se  for  digitado  um  <Enter>  em  um  terminal,  o 
processo  pertencente  àquele  terminal  era  movido  para  a  classe  de  prioridade  mais  alta, 
supondo que ele estivesse para se tornar interativo. Entretanto, certo dia, algum usuário com 
um processo pesadamente orientado à CPU descobriu que, sentando ao terminal e digitando 
<Enter>  de  maneira  aleatória  e  a  intervalos  de  poucos  segundos,  fazia  maravilhas  por  seu 
tempo de resposta, negligenciando o sistema. Ele contou isso para todos os seus amigos que 
passaram também a negligenciar a execução de seus processos. Moral da história: conseguir 
acertar na prática é muito mais difícil que acertar na teoria (TANENBAUM, 2003, p. 106). 

Muitos outros algoritmos foram usados para atribuir processos a classes de prioridade. 
Por exemplo, o influente sistema XDS 940 (LAMPSON, B. W., 1968 apud TANENBAUM, 2003, p. 
106) 21, construído em Berkeley, possuía quatro classes de prioridade: terminal, E/S, quantum 
curto  e  quantum  longo.  Quando  um  processo  que  estivesse  esperando  pela  entrada  de  um 
terminal finalmente acordasse, ele iria para classe de prioridade mais alta (terminal). Quando 
um processo bloqueado pelo disco ficasse pronto, ele iria para a segunda classe. Se, enquanto 
um processo ainda estivesse executando, seu quantum acabasse, seria inicialmente alocado na 

                                                            
21
 LAMPSON, B.W. “A scheduling philosophy for multiprogramming systems”. Communications of the ACM, vol. 11, p. 
347‐360. Maio 1968. 
terceira  classe.  Contudo,  se  um  processo  terminasse  seu  quantum  várias  vezes  sem  ser 
bloqueado pelo terminal ou por outra EIS, iria para a última fila. Muitos outros sistemas usam 
algo semelhante para favorecer os usuários interativos mais do que os processos em segundo 
plano (TANENBAUM, 2003, p. 106). 

2.5.4 Escalonamento por múltiplas filas com realimentação 
Normalmente,  em  um  algoritmo  de  escalonamento  por  múltiplas  filas,  os  processos 
são permanentemente atribuídos a uma fila ao entrar no sistema. Os processos não se movem 
entre  as  filas.  Se  houver  filas  separadas  para  processos  de  primeiro  e  segundo  planos,  por 
exemplo, os processos não passam de uma fila para outra, já que não mudam sua natureza de 
primeiro ou segundo plano. Essa configuração tem a vantagem de apresentar baixo custo de 
escalonamento, mas é inflexível (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 106). 

O  escalonamento  por  múltiplas  filas  com  realimentação  ou  filas  multiníveis  de 
retorno,  no  entanto,  permite  que  um  processo  se  mova  entre  as  filas.  A  idéia  é  separar  os 
processos com diferentes características de surto de UCP. Se um processo usar tempo de CPU 
excessivo,  será  movido  para  uma  fila  de  menor  prioridade.  Esse  esquema  deixa  os  processo 
orientados a E/S e interativos nas filas de prioridade mais alta. Da mesma forma, um processo 
que espera demais em uma fila de baixa prioridade pode ser passado para uma fila de maior 
prioridade.  Essa  forma  de  envelhecimento  evita  a  estagnação  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 106‐107). 

Um  algoritmo  de  escalonamento  normalmente  deve  favorecer  processos  curtos, 


favorecer processos orientados a E/S para que obtenham uma boa utilização dos dispositivos 
de E/S e bons tempos interativos de resposta, e devem determinar a natureza de um processo 
o mais rapidamente possível e escalonar o processo de acordo. O algoritmo de escalonamento 
por  múltiplas  filas  com  realimentação  ajuda  a  cumprir  esses  objetivos  (KLEINROCK,  L.,  1970 
apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 220)22. Um novo processo entra na 
rede de enfileiramento no final da fila de nível mais alto. Vai passando para a frente na ordem 
FIFO  até  obter  um  processador.  Se  o  processo  concluir  sua  execução,  ou  se  devolver  o 
processador  para  esperar  pela  conclusão  de  uma  E/S  ou  pela  conclusão  de  algum  outro 
evento, ele sairá da rede de enfileiramento. Se o quantum de um processo expirar antes que 
esse devolva voluntariamente o processador, o sistema colocará o processo no final da fila de 
nível mais baixo imediatamente inferior. Contanto que use totalmente o quantum fornecido a 
cada  nível,  o  processo  continua  e  passa  para  o  final  da  fila  de  nível  mais  baixo  seguinte. 

                                                            
22
 KLEINROCK, L. “A continuum of time‐sharing scheduling algorithms”, Proceeding of AFIPS, SJCC, 1970, p. 453‐458. 
Usualmente há uma fila de nível limite na qual o processo percorre em alternância circular até 
concluir. O processo que obtém um processador em seguida é aquele que está no início da fila, 
não  vazia,  de  nível  mais  alto  de  multinível  de  retorno.  Um  processo  que  está  em  execução 
sofre preempção em favor de outro que está chegando a uma fila de nível mais alto (DEITEL, H. 
M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 220‐221). 

Nesse  sistema,  um  processo  que  está  em  uma  fila  de  nível  mais  baixo  pode  sofrer 
adiamento indefinido se uma fila de nível mais alto contiver pelo menos um processo. Isso não 
pode ocorrer em sistemas cuja taxa de processos que chegam para serem atendidos é alta, ou 
nos  quais  há  diversos  processos  orientados  a  E/S  consumindo  seus  quanta  (DEITEL,  H.  M.; 
DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 220‐221).  

Em  muitos  esquemas  de  filas  multiníveis  de  retorno,  o  escalonador  aumenta  o 
tamanho  do  quantum  de  um  processo  à  medida  que  esse  passa  para  cada  fila  de  nível  mais 
baixo. Assim, quanto mais tempo um processo estiver na rede de enfileiramento, maior será o 
quantum  que  recebe  cada  vez  que  obtém  um  processador  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 220‐221). 

Por  exemplo,  considere  um  escalonador  por  múltiplas  filas  com  realimentação  que 
tenha três filas,numeradas de 0 a 2, onde a fila de menor número comporta os processos de 
maior  prioridade  (Figura  2.12).  O  escalonador  primeiro  executa  todos  os  processos  na  fila  0. 
Somente quando a fila 0 estiver vazia, ela executará os processos na fila 1. Da mesma forma, 
os processos na fila 2 só serão executados se as filas 0 e 1 estiverem vazias. Um processo que 
chega  na  fila  1  interromperá  um  processo  na  fila  2.  Um  processo  na  fila  1,  por  sua  vez,  será 
interrompido por um processo que chega na fila 0 (SILBERSCHATZ, A.; GALIN,  P.; GAGNE,  G., 
2000, p. 106‐107). 

Figura 2.12. Escalonamento por múltiplas filas de realimentação 
Um processo que entra na fila de processos prontos é colocado na fila 0.Um processo 
na  fila  0  recebe  um  quantum  de  8  milissegundos.  Se  não  terminar  dentro  desse  prazo,  ele  é 
passado para o final da fila 1. Se a fila 0 estiver vazia, o processo no início da fila 1 recebe um 
quantum de 16 milissegundos. Se não completar, ele será interrompido e colocado na fila 2. Os 
processos na fila 2 são executados em modo FIFO, apenas quando as filas 0 e 1 ficam vazias 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 107). 

Esse  algoritmo  de  escalonamento  fornece  prioridade  mais  alta  a  qualquer  processo 
com  um  surto  de  UCP  de  8  milissegundos  ou  menos.  Tal  processo  obterá  UCP  rapidamente, 
terminará seu surto de UCP e passará para o próximo surto de E/S. Os processos que precisam 
de mais de 8, mas menos de 24 milissegundos, também são atendidos rapidamente, embora 
com  menor  prioridade  do  que  os  processos  mais  curtos.  Os  processos  mais  longos 
automaticamente caem para fila 2 e são servidos na ordem FIFO com quaisquer ciclos de UCP 
deixados das filas 0 e 1 (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 107). 

Considerando como essa disciplina responde a diferentes tipos de processo é possível 
fazer  uma  análise  do  tratamento  que  cada  processo  recebe  em  relação  ao  seu  tipo.  Filas 
múltiplas  com  realimentação  favorecem  processos  orientados  a  E/S  e  outros  processos  que 
necessitam  apenas  de  pequenos  surtos  de  tempo  de  processador,  porque  esses  processos 
entram  na  rede  com  prioridade  alta  e  obtêm  um  processador  rapidamente.  A  disciplina 
escolhe um quantum grande o suficiente para a primeira fila, de modo que a vasta maioria dos 
processos  orientados  a  E/S  (e  processos  interativos)  emita  uma  requisição  de  E/S  antes  da 
expiração do quantum. Quando um processo requisita E/S, ele sai da rede de enfileiramento 
depois  de  ter  recebido  o  tratamento  favorecido  desejado.  O  processo  volta  à  rede  quando 
estiver pronto novamente (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

Com relação aos processos orientados à UCP, o processo entra na rede com prioridade 
alta, e o sistema o coloca na fila de nível mais alto. Nesse ponto a rede de enfileiramento não 
“sabe” se o processo é orientado a UCP ou a E/S – a meta da rede é decidir isso rapidamente. 
O processo obtém o processador rapidamente, usa todo o seu quantum, seu quantum expira e 
o escalonador passa o processo para a fila seguinte de nível mais baixo. Agora o processo tem 
uma prioridade mais baixa e os processos que chegam obtêm o processador primeiro, o que 
significa  que  processos  interativos  ainda  continuarão  a  receber  bons  tempos  de  resposta, 
mesmo  que  muitos  processos  orientados  a  UCP  passem  mais  para  baixo  na  rede  de 
enfileiramento. Eventualmente o processo orientado a UCP obtém o processador, recebe um 
quantum maior do que na fila de nível mais alto e novamente usa todo o seu quantum. Então 
o  escalonador  coloca  o  processo  no  final  da  próxima  fila  de  nível  mais  baixo.  O  processo 
continua a passar para filas de nível mais baixo, espera mais tempo entre intervalos de tempo 
e sua todo o seu quantum cada vez que obtém o processador (a menos que sofra preempção 
por um processo que chegue). Em algum momento o processo orientado a UCP chega à fila de 
nível  mais  baixo,  onde  percorre  em  alternância  circular  juntamente  com  outros  processos 
orientado a UCP até finalizar (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

Portanto,  múltiplas  filas  com  realimentação  são  ideais  para  separar  processos  em 
categorias  segundo  suas  necessidades  de  processador.  Quando  um  processo  sair  da  rede  de 
enfileiramento  pode  ser  “marcado”  com  a  identidade  da  fila  de  nível  mais  baixo  na  qual 
residiu.  Quando  o  processo  entrar  novamente  na  rede  de  enfileiramento,  o  sistema  poderá 
colocá‐lo  diretamente  na  fila  em  que  concluiu  a  operação  da  última  vez  –  nesse  caso  o  
escalonador  estará  empregando  a  heurística  que  diz  que  o  comportamento  recente  de  um 
processo é um bom indicador de seu comportamento futuro próximo. Essa técnica permite ao 
escalonador evitar colocar um processo orientado a UCP  que está retornando nas filas de nível 
mais alto, em que interferiria no serviço para processos curtos de alta prioridade ou processos 
orientados a E/S (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

Infelizmente,  se  o  escalonador  sempre  colocar  um  processo  que  retorne  na  fila  de 
nível  mais  baixo  que  ocupava  da  última  vez  que  esteve  no  sistema,  o  escalonador  não 
conseguirá  responder  a  mudanças  no  comportamento  do  processo  (o  processo  pode  estar 
transitando  de  orientado  a  UCP  para  orientado  a  E/S).  O  escalonador  pode  resolver  esse 
problema registrando não somente a identidade da fila de nível mais baixo na qual o processo 
residia, mas também a quantidade de seu quantum que não foi utilizada durante sua  última 
execução. Se o processo consumir todo o seu quantum, então será colocado em uma fila de 
nível mais baixo (se houver uma disponível). Se o processo emitir uma requisição de E/S antes 
de  seu  quantum  expirar,  poderá  ser  colocado  em  uma  fila  de  nível  mais  alto.  Se  o  processo 
estiver entrando em uma nova fase na qual mudará de orientado a UCP para orientado a E/S, 
inicialmente  poderá  experimentar  alguma  lentidão  enquanto  o  sistema  determinar  que  sua 
natureza  está  mudando,  mas  o  algoritmo  de  escalonamento  responderá  a  essa  mudança 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

Uma outra maneira de tornar o sistema responsivo a mudanças no comportamento de 
um processo é permitir que o processo suba um nível na rede de filas de retorno cada vez que 
devolver  voluntariamente  o  processador  antes  de  seu  quantum  expirar.  Similarmente,  o 
escalonador  ‐  ao  designar  uma  prioridade  –  pode  considerar  o  tempo  que  um  processo  tem 
gasto  à  espera  por  serviço.  O  escalonador  pode  envelhecer  o  processo  promovendo‐o  e 
colocando‐o na fila de nível mais alto seguinte depois de ele ter passado uma certa quantidade 
de tempo à espera por serviço  (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

Em  geral,  um  escalonador  por  múltiplas  filas  com  realimentação  é  definido  pelos 
seguintes parâmetros: 

• O número de filas 
• O algoritmo de escalonamento para cada fila 
• O método usado para determinar quando promover um processo para 
uma fila de maior prioridade 
• O  método  usado  para  determinar  quando  rebaixar  um  processo  para 
uma fila de menor prioridade 
• O  método  usado  para  determinar  em  que  fila  um  processo  entrará 
quando esse processo precisar de serviço 

Uma variação comum do mecanismo de múltiplas filas com realimentação é fazer um 
processo passar por alternância circular diversas vezes em cada fila antes de passar para a fila 
de nível mais baixo seguinte. E também, o número de ciclos por que passa em cada fila pode 
ser aumentado à medida  que o processo passa para a fila de nível mais baixo seguinte.  Essa 
variação tenta refinar mais ainda o serviço que o escalonador fornece a processos orientados a 
E/S  e  a  processos  orientados  a  processador  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R., 
2005, p. 221). 

Múltiplas filas com realimentação é um bom exemplo de mecanismo adaptativo, um 
mecanismo que responde às mudanças no comportamento do sistema que controla (BLEVINS, 
P. R.; RAMAMOORTHY, C. V., 1976; POTIER, D.; GELENBE, E.; LENFANT, J., 1976 apud DEITEL, H. 
M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.,  2005,  p.  221)23,  24.  Mecanismos  adaptativos  em  geral 
requerem  mais  sobrecarga  do  que  os  não‐adaptativos,  mas  a  resultante  sensibilidade  a 
mudanças  no  sistema  torna  o  sistema  mais  responsivo  e  ajuda  a  justificar  o  aumento  de 
sobrecarga (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 221). 

A definição de um escalonador por múltiplas filas com realimentação torna o algoritmo 
de escalonamento de UCP mais geral. Pode ser configurado para corresponder a um sistema 

                                                            
23
 BLEVINS, P. R.; RAMAMOORTHY, C. V. “Aspects of a dynamically adaptative operating system”, IEEE Transactions on 
Computers, v. 25, nº 7, jul. 1976, p. 713‐715. 
24
 POTIER, D.; GELENBE, E.; LENFANT, J. “Adaptive allocation of central processing unit Quanta”, Journal of the ACM, 
v. 23, nº 1, jan. 1976, p. 97‐102. 
específico em desenvolvimento. Infelizmente, requer algum meio segundo o qual seja possível 
selecionar valores para todos os parâmetros para definir o melhor escalonador. Embora uma 
fila  multinível  com  realimentação  seja  o  esquema  mais  geral,  também  é  o  mais  complexo 
(SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 107). 

2.5.5 Próximo processo mais curto (shortest process next ‐ SPN) 
Como o algoritmo de escalonamento SJF sempre resulta no mínimo tempo médio de 
resposta para sistemas em lote, seria bom se ele pudesse ser usado para processos interativos 
também. Até certo ponto, isso é possível. Processos interativos geralmente seguem o padrão 
de esperar por comando, executar comando, esperar por comando, executar comando e assim 
por  diante.  Se  a  execução  de  cada  comando  fosse  visualizada  como  um  'job'  isolado,  então 
seria possível minimizar o tempo de resposta geral executando o SJF.O único problema é saber 
qual dos processos atualmente executáveis é o mais curto (TANENBAUM, 2003, p. 107). 

Uma saída é realizar uma  estimativa com base no comportamento passado e, então, 
executar o  processo cujo  tempo  de  execução estimado seja o menor. Suponha que o  tempo 
estimado por comando para algum terminal seja T0 e que sua próxima execução seja medida 
como  T1.  A  estimativa  pode  ser  atualizada  tomando  uma  soma  ponderada  desses  dois 
números, isto é, aT0 + (1 – a)T1.  Pela escolha de a pode‐se decidir se o processo de estimativa 
esquecerá  rapidamente  as  execuções  anteriores  ou  se  lembrará  delas  por  um  longo  tempo. 
Com a = 1/2, obtém‐se estimativas sucessivas de 

T0, T0/2 + T1/2, T0/4 + T1/4 + T2/2, T0/8 + T1/8 + T2/4 + T3/2 

Depois de três novas execuções, o peso de T0 na nova estimativa caiu para 1/8. 

A técnica de estimar o valor seguinte da série, tomando a média ponderada do valor 
sendo  medido  e  a  estimativa  anterior,  é  algumas  vezes  chamada  de  aging.  Essa  técnica  é 
aplicável a muitas situações nas quais é preciso uma previsão baseada nos valores anteriores. 
Aging  é  especialmente  fácil  de  implementar  quando  a  =  1/2.  Basta  apenas  adicionar  o  novo 
valor à estimativa atual e dividir a soma por 2 (deslocando1bit à direita) (TANENBAUM, 2003, 
p. 107). 

2.5.6 Escolamento Garantido 
Um  método  completamente  diferente  de  lidar  com  o  escalonamento  é  fazer 
promessas  reais  sobre  o  desempenho  aos  usuários  e  então  satisfazê‐los.  Uma  promessa 
realista e fácil de cumprir é a seguinte: se houver n usuários conectados, cada qual receberá 
cerca  de  1/n  de  tempo  de  UCP.  De  modo  semelhante,  em  um  sistema  monousuário  com  n 
processos em execução, todos iguais, cada um deve receber 1/n ciclos de UCP (TANENBAUM, 
2003, p. 107). 

Para  fazer  valer  essa  promessa,  o  sistema  deve  manter  o  controle  da  quantidade  de 
UCP  que  cada  processo  recebe  desde  sua  criação.  Ele  então  calcula  a  quantidade  de  UCP 
destinada  a  cada  um  ou  simplesmente  o  tempo  desde  a  criação  dividido  por  n.  Como  a 
quantidade de tempo de UCP que cada processo realmente teve é também conhecida, torna‐
se fácil calcular a taxa entre o tempo de UCP de fato consumido e o tempo de UCP destinado a 
cada processo. Uma taxa de 50% significa que um processo teve somente a metade do que ele 
deveria ter e uma taxa de 200% significa que um processo teve duas vezes mais do que lhe foi 
destinado.  O  algoritmo  então  executará  o  processo  com  a  taxa  mais  baixa,  até  que  sua  taxa 
cresça e se aproxime da taxa de seu competidor (TANENBAUM, 2003, p. 107). 

2.5.7 Escalonamento por Loteria 
Fazer  promessas  aos  usuários  e  satisfazê‐Ios  é  uma  boa  idéia,  porém  difícil  de 
implementar.  Contudo,  um  outro  algoritmo  pode  ser  usado  com  resultados  similarmente 
previsíveis,  mas  de  implementação  muito  mais  simples.  É  o  chamado  escalonamento  por 
loteria (WALDSPURGER ; WEIHL, 1994 apud TANENBAUM, 2003, p. 107)25. 

A idéia básica é dar bilhetes de loteria aos processos, cujos prêmios são vários recursos 
do  sistema,  como  tempo  de  UCP.  Se  houver  uma  decisão  de  escalonamento,  um  bilhete  de 
loteria  será  escolhido  aleatoriamente  e  o  processo  que  tem  o  bilhete  conseguirá  o  recurso. 
Quando  aplicado  ao  escalonamento  de  UCP,  o  sistema  pode  fazer  um  sorteio  50  vezes  por 
segundo e, portanto, cada vencedor terá 20 ms de tempo de CPU como prêmio (TANENBAUM, 
2003, p. 107). 

Parafraseando  George  Orwell:  "Todos  os  processos  são  iguais,  mas  alguns  são  mais 
iguais  que  os  outros".  Aos  processos  mais  importantes  podem  ser  atribuídos  bilhetes  extras 
para  aumentar  suas  probabilidades  de  vitória.  Se  houver  cem  bilhetes  extras  e  um  processo 
detiver vinte deles, esse processo terá uma chance de 20% de vencer cada loteria. Ao longo da 
execução, ele obterá 20% da UCP. Diferentemente de um escalonador por prioridades, no qual 
é muito difícil estabelecer o que de fato significa uma prioridade 40, aqui há uma regra clara: 
um  processo  que  detenha  uma  fração  f  dos  bilhetes  obterá  em  torno  de  uma  fração  f  do 
recurso em questão (TANENBAUM, 2003, p. 107). 

                                                            
25
  WALDSPURGER,  C.  A.;  WEIHL,  W.  E.  Lottery  scheduling:  Flexible  proportionalshare  resource  management.  In 
Proceedings of the First Symposium on Operating System Design and Implementation. Nov. 1994, p. 1‐11. 
O  escalonamento  por  loteria  tem  várias  propriedades  interessantes.  Por  exemplo,  se 
aparece  um  novo  processo  e  a  ele  são  atribuídos  alguns  bilhetes,  já  no  próximo  sorteio  da 
loteria sua probabilidade de vencer será proporcional ao número de bilhetes que ele tiver. Em 
outras palavras, o escalonamento por loteria é altamente responsivo (TANENBAUM, 2003, p. 
107‐108). 

Os  processos  cooperativos  podem  trocar  bilhetes  entre  si,  se  assim  desejarem.  Por 
exemplo,  quando  um  processo  cliente  envia  uma  mensagem  para  um  processo  servidor  e 
então  é  bloqueado,  ele  pode  dar  todos  os  seus  bilhetes  ao  servidor,  para  que  aumentem  as 
probabilidades  de  o  servidor  executar  logo.  Quando  o  servidor  termina,  retorna  os  bilhetes 
para  o  cliente  executar  novamente.  Na  verdade,  na  ausência  de  clientes,  os  servidores  nem 
precisam de bilhetes (TANENBAUM, 2003, p. 108). 

O  escalonamento  por  loteria  pode  ser  usado  para  resolver  problemas  difíceis  de 
solucionar  a  partir  de  outros  métodos.  Um  exemplo  é  o  de  um  servidor  de  vídeo,  no  qual 
vários  processos  alimentam  o  fluxo  de  vídeo  de  seus  clientes,  mas  em  diferentes  taxas  de 
apresentação  dos  quadros.  Supondo‐se  que  os  processos  precisem  de  taxas  em  10,  20  e  25 
quadros/s.  Alocando  a  esses  processos  10,  20  e  25  bilhetes,  respectivamente,  eles  vão 
automaticamente  dividir  a  UCP  aproximadamente  na  proporção  correta,  que  é  10:20:25 
(TANENBAUM, 2003, p. 108). 

2.5.8 Escalonamento por Fração Justa (fair share scheduling ‐ FSS) 
Até agora partiu‐se do pressuposto de que cada processo é escalonado por si próprio, 
sem preocupar‐se com quem é o dono do processo. Como resultado, se o usuário 1 inicia nove 
processos e o usuário 2 inicia um processo, com alternância circular ou com prioridades iguais, 
o usuário 1 obterá 90% da UCP e o usuário 2 terá somente 10% dela (TANENBAUM, 2003, p. 
108). 

Para  evitar  isso,  alguns  sistemas  consideram  a  propriedade  do  processo  antes  de 
escaloná‐lo.  Nesse  modelo,  a  cada  usuário  é  alocada  uma  fração  da  UCP,  e  o  escalonador 
escolhe os processos de modo que garanta essa fração. Assim, se dois usuários tiverem 50% da 
UCP  prometida  a  cada  um  deles,  cada  um  obterá  os  50%,  não  importando  a  quantidade  de 
processos que eles tenham gerado (TANENBAUM, 2003, p. 108). 

Sistemas  geralmente  suportam  vários  conjuntos  de  processos  relacionados.  Por 


exemplo, o sistema Unix (e outros sistemas multiusuários) agrupa processos que pertencem a 
um usuário individual. O escalonamento por fração justa (fair share scheduling ‐ FSS) suporta 
escalonamento por meio desses conjuntos de processos (NEWBURY, J. P., 1982; HENRY, G. J., 
1984;  WOODSIDE,  C.  M.,  1986;  KAY,  J.;  LAUDER,  P.,  1988  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES,  D.  R.,  2005,  p.  222)26,  27,  28,  29.  O  sistema  por  fração  justa  habilita  um  sistema  a 
garantir justiça por meio de grupos de processos restringindo cada grupo a um subconjunto de 
recursos de sistema. No ambiente Unix, por exemplo, o FSS foi desenvolvido especificamente 
para  “dar  uma  taxa  pré‐especificada  de  recursos  de  sistema  (...)  a  um  conjunto  de  usuários 
relacionados” (HENRY, G. J., 1984 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 
222)30. 

Como  exemplo,  imagine  um  grupo  de  pesquisa  cujos  membros  compartilhem  um 
sistema multiusuário; eles estão divididos em dois grupos. Os pesquisadores principais – cujo 
número  é  pequeno  –  usam  o  sistema  para  executar  trabalhos  importantes,  intensivos  em 
computação, como fazer simulações. Os assistentes de pesquisa – em grande número – usam 
o sistema para trabalhos menos intensivos, como agregar dados e imprimir resultados. Agora 
imagine  que  muitos  assistentes  de  pesquisa  e  somente  um  pesquisador  principal  esteja 
utilizando  o  sistema.  Os  assistentes  de  pesquisa  podem  consumir  a  maioria  do  tempo  do 
processador  em  detrimento  do  pesquisador  principal  que  deve  executar  o  trabalho  mais 
importante.  Todavia,  se  o  sistema  permitisse  que  o  grupo  de  assistentes  de  pesquisa  usasse 
somente 25% do tempo de processador e permitisse que o grupo de pesquisadores principais 
usasse  75%,  o  pesquisador  principal  não  sofreria  tal  degradação  do  serviço.  Desse  modo,  o 
escalonamento  por  fração  justa  assegura  que  o  desempenho  de  um  processo  seja  afetado 
somente  pela  população  de  seu  grupo  de  processo,  e  não  pela  população  de  usuários  como 
um todo (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 222). 

Dessa  maneira,  em  um  sistema  com  dois  usuários,  cada  qual  com  50%  da  UCP 
prometida  a  ele,  sendo  que  o  usuário  1  possui  quatro  processos,  A,  B,  C  e  D,  e  o  usuário  2 
possui  somente  um  processo,  E;  se  for  usado  o  escalonamento  circular,  uma  seqüência 
possível de escalonamento que cumpra todas as exigências será a seguinte: 

A E B E C E D E A E B E C E D E... 

                                                            
26
 NEWBURY, J. P. “Immediate turnaround: an elusive goal”, Software: Practice and Experience, v. 12, nº 10, ou. 1982, 
p. 897‐906. 
27
  HENRY,  G.  J.  “The  fair  share  scheduler”,  Bell  Systems  Technical  Journal,  v.  63,  nº  8,  parte  2,  out.  1984,  p.  1845‐
1857. 
28
  WOODSIDE,  C.  M.  “Controllability  of  computer  performance  tradeoffs  obtained  using  controlled‐share  queue 
schedulers”, IEEE Transactions on Software Engineering, v. SE‐12, nº 10, out. 1986, p. 1041‐1048. 
29
 KAY, J.; LAUDER, P. “A fair share scheduler”, Communications of the ACM, v. 31, nº 1, jan. 1988, p. 44‐55.
30
 HENRY, G. J. “The fair share scheduler”, Bell Systems Technical Journal, v. 63, nº 8, parte 2, out. 1984, p. 1846. 
Por outro
o lado, se ao
o usuário 1 se destinar duas vezes m
mais tempo d
de UCP que p
para o 
usuárrio 2, obtém‐se: 

A B E C D E A B E C D EE... 

Certamen
nte  existem  inúmeras  outras 
o possib
bilidades,  igu
ualmente  paassíveis  de  serem 
s
explo
oradas, dependendo da n
noção de justtiça (TANENB
BAUM, 2003
3, p. 108). 

Para  enteender  melho


or  o  funcion
namento  do  escalonameento  por  fração  justa,  te
em‐se 
uma  análise  de  como  esse  algoritmo  de  escalonaamento  funciona  em  u
um  sistema  Unix. 
Norm
malmente o U
Unix consideera taxas de  consumo de por todos os  processos (FFigura 
e recursos p
2.13). Contudo, ssob o FSS, o  sistema rep
parte os recu
ursos entre vvários grupo
os de fração
o justa 
(Figura  2.14),  disstribuindo  recursos  não
o  utilizados  por  um  gru
upo  de  fraçãão  justa  a  outros 
o
os de fração justa na pro
grupo oporção de  suas necessiidades relativas (DEITEL,, H. M.; DEITTEL, P. 
J.; CH
HOFFNES, D. R., 2005, p. 2
222). 

Figura 2..13. Escalonad
dor de processso‐padrão do
o Unix. O escalonador conceede o processsador 
aos usuário
os, cada um deeles pode ter muitos proce dade de AT&TT Archives)31 
essos (Propried

                                                            
31
 HEN
NRY, G. J. “The fair share sched
duler”, Bell Systeems Technical Journal, v. 63, nº 8, parte 2, ou
ut. 1984, p. 1847. 
 

4. Escalonador por fração ju
Figura 2.14 usta. O escalo
onador por fraação justa divide a capacidaade de 
reccursos do sisteema em porçõ por escalonadores de proceesso designados a 
ões, as quais ssão alocadas p
vários grupo edade de AT&TT Archives)32 
os de fração justa. (Proprie

As  instru
uções  do  Unix  estabeleecem  grupo
os  de  fração
o  justa  e  aassociam  usu
uários 
especcíficos a eless (CHAPTER 9 ud DEITEL, H.. M.; DEITEL,, P. J.; CHOFFNES, D. R.,  2005, 
9, 2003  apu
22)33.  Para  o  propósito  dessa 
p.  22 d discusssão,  conside
era‐se  a  premissa  de  qu
ue  o  Unix  ussa  um 
escalonador  de  processo 
p po
or  prioridadee  em  alternâância  circulaar  (HENRY,  G
G.  J.  ,  1984  apud 
DEITEEL,  H.  M.;  DEITEL, 
D 05,  p.  222)344.  Cada  proccesso  possui  uma 
P.  J.;;  CHOFFNESS,  D.  R.,  200
prioridade, e o esscalonador aassocia proceessos de umaa dada prioridade com a fila de priorridade 
para aquele valorr. O escalonaador de proccesso seleciona o processso pronto qu
ue está à fren
nte na 
fila  de 
d prioridadee  mais  alta.  Processos  dentro 
d de  um
ma  dada  priioridade  são
o  escalonado
os  por 
nância circular. Um processo que req
altern quer mais serviços após ssofrer preem
mpção recebe
e uma 
prioridade mais b
baixa. Priorid
dades de núccleo são altaas e aplicam‐‐se a processsos que execcutam 
úcleo; priorid
no nú dades de usuário são mais baixas. Eventos de disco recebem
m prioridade
e mais 
alta  do 
d que  even minal.  O  escaalonador  designa  a  prioridade  do  usuário  como
ntos  de  term o  uma 
razão
o entre a utillização recen
nte do proceessador e o ttempo real d
decorridos; q
quanto mais  baixo 

                                                            
32
 HEN
NRY, G. J. “The fair share sched
duler”, Bell Systeems Technical Journal, v. 63, nº 8, parte 2, ou
ut. 1984, p. 1846. 
33
  “C
CHAPTER  9,  fair  share  shceduler”,  So olaris  9  Systeem  Administrrator  Collectio on,  11  nov.  2003, 
docs.sun.com/db/doc/806‐4076/6jd d6amqqo?a=vieew. 
34
 HEN
NRY, G. J. “The fair share sched
duler”, Bell Systeems Technical Journal, v. 63, nº 8, parte 2, ou
ut. 1984, p. 1848. 
o tempo decorrido, mais alta a prioridade (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, 
p. 222). 

Os grupos de fração justa são priorizados segundo o quanto estão próximos de atingir 
seus  objetivos  especificados  de  utilização  de  recursos.  Grupos  que  estão  indo  mal  recebem 
prioridade  mais  alta;  grupos  que  estão  indo  bem  recebem  prioridade  mais  baixa  (DEITEL,  H. 
M.; DEITEL, P. J.; CHOFFNES, D. R., 2005, p. 223). 

2.6 Escalonamento em sistemas de tempo real 

2.6.1 Escalonamento por prazo 
No escalonamento por prazo, certos processos são escalonados para concluir em um 
momento ou prazo específico. Esses processos podem ter alto valor, se entregues a tempo, e 
nenhum  valor,  caso  isso  não  aconteça  (NIELSEN,  N.  R.,  1970;    MCKELL,  L.  J.;  HANSEN,  J.  V.; 
HEITGER, L. E. , 1979; KLEIJNEN, A. J. V., 1983 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. 
R., 2005, p. 223)35, 36, 37. 

O escalonamento por prazo é complexo. Primeiro, o usuário deve fornecer suas exatas 
requisições de recursos antecipadamente para garantir que o processo seja concluído dentro 
do  prazo.  Essa  informação  raramente  está  disponível.  Segundo,  o  sistema  deve  executar  o 
processo  que  tem  prazo  sem  degradar  seriamente  o  serviço  oferecido  a  outros  usuários.  O 
sistema  também  deve  planejar  cuidadosamente  seus  requisitos  de  recursos  até  o  final  do 
prazo,  o  que  pode  ser  difícil,  porque  podem  chegar  novos  processos  requerendo  demandas 
imprevisíveis.  Por  fim,  se  houver  muitos  processos  com  prazos  ativos  ao  mesmo  tempo,  o 
escalonador  poderá  se  tornar  extremamente  complexo  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R., 2005, p. 223). 

O  gerenciamento  intensivo  de  recursos  exigido  pelo  escalonamento  por  prazo  pode 
gerar  sobrecarga  substancial.  O  consumo  líquido  de  recursos  do  sistema  pode  ser  alto, 
degradando  o  serviço  para  outros  processos  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R., 
2005, p. 223). 

O  escalonamento  por  prazo  é  importante  para  o  escalonamento  de  processos  de 


tempo  real.  Dertouzos  (1974  apud  Deitel,  H.  M.;  Deitel,  P.  J.;  Choffnes,  D.  R.,  2005,  p.  223) 

                                                            
35
 NIELSEN, N. R. “The allocation of computing resourses – is pricing the answer?”, Communications of the ACM, v. 
13, nº 8, ago. 1970, p. 467‐474. 
36
 MCKELL, L. J.; HANSEN, J. V.; HEITGER, L. E. “Charging for computer resources”, ACM Computing Surveys, v. 11, nº 
2, jun. 1979, p. 105‐120. 
37
    KLEIJNEN,  A.  J.  V.  “Principles  of  computer  charging  in  a  university‐type  organization”,  Communications  of  the 
ACM, v. 26, nº 11, nov. 1983, p. 926‐932. 
demonstrou que, quando todos os processos podem cumprir seus prazos independentemente 
da  ordem  em  que  são  executados,  escalonar  primeiro  os  processos  de  prazo  mais  curtos  é 
ótimo38.  Entretanto,  quando  o  sistema  fica  sobrecarregado,  esse  deve  alocar  tempo 
significativo  de  processador  ao  escalonador  para  determinar  a  ordem  adequada  na  qual 
executar  processos  para  que  cumpram  seus  prazos.  Pesquisas  recentes  concentram‐se  na 
velocidade  ou  número  de  processadores  que  o  sistema  deve  alocar  ao  escalonador  para 
cumprir os prazos (KALYANASUNDARAM, B.; PRUHS, K. , 2002;  LAM, T.; TO, K., 2001; KOO, C  
et al., 2002 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 223)39, 40, 41. 

2.6.2 Escalonamento de Tempo Real 
Um  objetivo  primário  dos  algoritmos  de  escalonamento  apresentados  anteriormente 
era garantir alta utilização de recursos. Processos que devem executar periodicamente (como 
uma  vez  por  minuto)  requerem  algoritmos  de  escalonamento  diferentes.  Por  exemplo,  os 
tempos de espera ilimitados do SJF podem ser catastróficos para um processo que verifique a 
temperatura de um reator nuclear. Similarmente, um sistema que use SRT para escalonar um 
processo que produza um videoclipe produziria uma reprodução entrecortada. Escalonamento 
de  tempo  real  atende  às  necessidades  de  processos  que  devem  produzir  saídas  corretas  em 
determinado momento (ou seja, que têm uma restrição de tempo) (STANKOVIC, J., 1996 apud 
DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 225)42. 

Um  sistema  de  tempo  real  é  aquele  no  qual  o  tempo  tem  uma  função  essencial.  Em 
geral,  um  ou  mais  dispositivos  físicos  externos  ao  computador  geram  estímulos,  e  o 
computador deve reagir apropriadamente a eles dentro de um dado intervalo de tempo. Por 
exemplo, o computador em um tocador de CD obtém os bits que chegam do drive e precisa 
convertê‐los em música em um intervalo crítico de tempo. Se o cálculo que ele fizer for muito 
demorado,  a  música  soará  diferente.  Outros  exemplos  de  sistemas  de  tempo  real  incluem: 
monitoração de pacientes em unidades de terapia intensiva de hospitais, piloto automático de 
aeronaves  e  robôs  de  controle  em  fábricas  automatizadas.  Em  todos  esses  casos,  ter  a 
resposta certa mas tardia é tão ruim quanto não ter nada (TANENBAUM, 2003, p. 108). 

                                                            
38
  DERTOUZOS,  M.  L.  “Control  robotics:  the  procedural  controlo  f  physical  processes”,  Proceedings  IFIP  Congress, 
1974, p. 807‐813. 
39
 KALYANASUNDARAM, B.; PRUHS, K. “Speed is as powerful as clairvoyance”, Journal of the ACM (JACM), v. 47, nº 4, 
jul. 2002, p. 617‐643. 
40
 LAM, T.; TO, K. “Performance guarantee for online deadline scheduling in the presence of overload”, Proceedings 
of the Twelfth Annual ACM‐SIAM Symposium on Discrete Algorithms, 7‐9 jan. 2001, p. 755‐764. 
41
  KOO,  C.;  LAM,  T.;  NGAN,  T.;  TO,  K.  “Extra  processors  versus  future  information  in  optimal  deadline  scheduling”, 
Proceedings of the Fourteenth Annual ACM Symposium on Parallel Algorithms and Architectures, 2002, p. 133‐142. 
42
 STANKOVIC, J. “Real‐time and embedded systems”, ACM Computing Surveys, v. 28, nº 1, mar. 1996, p. 205‐208. 
Sistemas de tempo real são em geral categorizados como tempo real crítico, isto é, há 
prazos absolutos que devem ser cumpridos para completar uma tarefa crítica ou, então, como 
tempo  real  não  crítico,  no  qual  o  descumprimento  ocasional  de  um  prazo  é  indesejável, 
contudo tolerável (TANENBAUM, 2003, p. 108). Desta forma, as disciplinas de escalonamento 
de  tempo  real  são  classificadas  conforme  quão  bem  cumprem  os  prazos  de  um  processo. 
Escalonamento  de  tempo  real  crítico  garante  que  as  restrições  de  prazo  de  um  processo 
sejam sempre atendidas. Cada tarefa especificada por um processo de tempo real crítico deve 
concluir  antes  de  seu  prazo  final;  caso  isso  não  aconteça,  os  resultados  poderão  ser 
catastróficos,  entre  eles  trabalho  inválido,  falha  de  sistema  ou  até  danos  aos  usuários  do 
sistema.  Por  outro  lado,  escalonamento  de  tempo  real  não  crítico  garante  que  processos  de 
tempo  real  sejam  despachados  antes  de  outros  processos  do  sistema,  mas  não  garante  qual 
processo,  se  é  que  algum  deles,  cumprirá  suas  restrições  de  tempo  (XU,  J.;  PARNAS,  D.  L., 
1991;  STEWART,  D.;  KHOSLA,  P.,  1991    apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 225)43, 44. 

Em geral, em um sistema de tempo real crítico, um processo é submetido juntamente 
com  uma  instrução  sobre  a  quantidade  de  tempo  necessária  para  concluir  ou  efetuar  uma 
operação de entrada e saída. O escalonador admite o processo, garantindo que ele concluirá 
no prazo, ou rejeita o pedido como sendo impossível. Essa garantia, feita mediante reserva de 
recurso, exige que o escalonador saiba exatamente quanto tempo leva para realizar cada tipo 
de função do sistema operacional; portanto, deve‐se garantir a quantidade máxima de tempo 
que cada operação utilizará. Essa garantia é impossível em um sistema com  armazenamento 
secundário  ou  memória  virtual  porque  esses  subsistemas  causam  variação  inevitável  e 
imprevisível na quantidade de tempo utilizada para executar determinado processo. Portanto, 
os  sistemas  de  tempo  real  crítico  são  compostos  por  software  de  propósito  especial 
executando  em  hardware  dedicado  aos  seus  processos  críticos  e  não  têm  a  plena 
funcionalidade  dos  computadores  e  sistemas  operacionais  modernos  (SILBERSCHATZ,  A.; 
GALIN, P.; GAGNE, G., 2000, p. 108). 

A computação de tempo real não‐crítico é menos restritiva. Requer que os processos 
críticos  recebam  prioridade  em  relação  a  outros  menos  favorecidos.  Embora  acrescentar 
funcionalidade de tempo real não‐crítico a um sistema de tempo compartilhado possa causar 
alocação injusta de recursos e resultar em atrasos maiores, ou mesmo starvation (paralisação), 
                                                            
43
 XU, J.; PARNAS, D. L. “On satisfying timing constraints in hard‐real‐time systems”, Proceedins of the Conference on 
Software for Critical Systems. Nova Orleans, LO, 1991, p. 132‐146. 
44
  STEWART,  D.;  KHOSLA,  P.  “Real‐time  scheduling  of  dynamically  reconfigurable  systems”,  Proceedings  of  the  IEEE 
International Conference on Systems Engineering. Dayton, OH, ago. 1991, p. 139‐142. 
para  alguns  processos,  é  pelo  menos  possível  de  alcançar.  O  resultado  é  um  sistema  de  uso 
geral  que  também  pode  suportar  multimídia,  gráficos  interativos  de  alta  velocidade  e  uma 
variedade de tarefas que não funcionariam aceitavelmente em um ambiente que não suporta 
computação de tempo real não‐crítico (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 108). 
O  escalonamento  de  tempo  real  não  crítico  é  comumente  implementado  em  computadores 
pessoais  nos  quais  uma  reprodução  suave  de  multimídia  é  desejável,  mas  tolera‐se 
interrupções ocasionais quando a carga do sistema estiver pesada. Sistemas de tempo real não 
crítico  podem  se  beneficiar  de  taxas  altas  de  interrupção  que  evitam  que  o  sistema  fique 
“preso”  executando  um  processo,  enquanto  outros  perdem  seus  prazos.  Todavia,  o  sistema 
pode incorrer em sobrecargas significativas se a taxa de interrupção for muito alta, resultando 
em mau desempenho e prazos perdidos (ETSION, Y.; TSAFRIR, D.; FEITEELSON, D., 2003 apud 
DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 225)45. 

Em ambos os casos, o comportamento de tempo real é implementado dividindo‐se o 
programa em vários processos cujos comportamentos são previamente conhecidos. De modo 
geral,  esses  processos  têm  vida  curta  e  podem  executar  em  bem  menos  de  um  segundo. 
Quando é detectado um evento externo, o trabalho do escalonador é escalonar os processos 
de tal maneira que todos os prazos sejam cumpridos (TANENBAUM, 2003, p. 108). No entanto, 
implementar  a  funcionalidade  de  tempo  real  não‐crítico  requer  o  projeto  cuidadoso  do 
escalonador  e  aspectos  relacionados  do  sistema  operacional.  Em  primeiro  lugar,  o  sistema 
deve ter escalonamento por prioridade, e os processos de tempo real devem ter a prioridade 
mais  alta.  A  prioridade  dos  processos  de  tempo  real  não  deve  se  degradar  com  o  tempo, 
embora a prioridade de outros processos possa. Em segundo lugar, a latência de dispatch deve 
ser pequena. Quanto menor a latência, mais rápido o processo de tempo real poderá começar 
a  execução  assim  que  estiver  no  estado  executável  ou  pronto  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 108‐109). 

É  relativamente  simples  garantir  a  validade  da  primeira  propriedade.  Por  exemplo, 


pode‐se  desabilitar  o  envelhecimento  em  processos  de  tempo  real,  garantindo  assim  que  a 
prioridade  dos  vários  processos  não  mude.  No  entanto,  garantir  a  segunda  propriedade 
envolve muitos outros aspectos. O problema é que muitos sistemas operacionais, incluindo a 
maioria das versões do Unix, são forçados a esperar a conclusão de uma chamada ao sistema 
ou  a  finalização  de  um  bloco  de  operações  de  E/S  antes  que  possam  realizar  uma  troca  de 
contexto.  A  latência  de  dispatch  em  tais  sistemas  pode  ser  demorada,  já  que  algumas 
                                                            
45
 ETSION, Y.; TSAFRIR, D.; FEITEELSON, D. “Effects of clock resolution on the scheduling of interactive and soft real‐
time processes”, SIGMETRICS’03, 10‐14 jun. 2003, p. 172‐183. 
chamadas ao sistema são complexas e alguns dispositivos de E/S são lentos (SILBERSCHATZ, A.; 
GALIN, P.; GAGNE, G., 2000, p. 109). 

Para  manter  a  latência  de  dispatch  baixa,  precisa‐se  permitir  que  as  chamadas  ao 
sistema possam ser interrompidas. Existem várias maneiras de atingir essa meta. Uma delas é 
inserir pontos de preempção em chamadas ao sistema de longa duração, que verificam se um 
processo de alta prioridade precisa ser executado. Se precisar, ocorre uma troca de contexto; 
quando o processo de alta prioridade termina, o processo interrompido continua sua chamada 
ao sistema. Os pontos de preempção só podem ser colocados em posições seguras no kernel ‐ 
somente  onde  as  estruturas  de  dados  do  kernel  não  estiverem  sendo  modificadas.  Mesmo 
com  pontos  de  preempção,  a  latência  de  dispatch  pode  ser  grande,  porque  é  praticável 
acrescentar  apenas  alguns  pontos  de  preempção  ao  kernel  (SILBERSCHATZ,  A.;  GALIN,  P.; 
GAGNE, G., 2000, p. 108‐109). 

Outro  método  para  lidar  com  a  preempção  é  tornar  todo  o  kernel  preemptível.  Para 
garantir a operação correta, todas as estruturas de dados do kernel devem ser protegidas com 
o  uso  de  vários  mecanismos  de  sincronização.  Com  esse  método,  o  kernel  sempre  pode  ser 
preemptível,  porque  quaisquer  dados  sendo  atualizados  são  protegidos  contra  modificação 
pelo processo de alta prioridade. Esse método é usado no Solaris 2 (SILBERSCHATZ, A.; GALIN, 
P.; GAGNE, G., 2000, p. 109). 

O  que  acontece  se  o  processo  de  prioridade  mais  alta  precisar  ler  ou  modificar  os 
dados  do  kernel  que  estão  sendo  acessados  no  momento  por  outro  processo  de  menor 
prioridade?  O  processo  de  alta  prioridade  estaria  esperando  o  término  de  um  processo  de 
menor prioridade. Essa situação é chamada de inversão de prioridade. Na verdade, pode haver 
uma cadeia de processos, todos acessando recursos que o processo de alta prioridade precisa. 
Esse problema pode ser resolvido via protocolo de herança de prioridade, no qual todos esses 
processos  (os  processos  que  estão  acessando  recursos  que  o  processo  de  alta  prioridade 
precisa) herdam a alta prioridade até terminarem com o recurso em questão. Quando tiverem 
concluído,  a  sua  prioridade  volta  ao  valor  original  (SILBERSCHATZ,  A.;  GALIN,  P.;  GAGNE,  G., 
2000, p. 109). 

Na Figura 2.15, os componentes de latência de dispatch estão representados. A fase de 
conflito da latência de dispatch possui dois componentes: 

1. Preempção de qualquer processo em execução no kernel; 
2. Liberação por parte de processos de baixa prioridade dos recursos que 
o processo de alta prioridade necessita. 

Figura 2.15. Latência de dispatch 

Como exemplo, no Solaris 2, com a preempção desabilitada, a  latência de dispatch fica 
acima  de  100  milissegundos;  com  a  preempção  habilitada,  geralmente  cai  para  2 
milissegundos (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 109‐110). 

Os  eventos  aos  quais  um  sistema  de  tempo  real  pode  precisar  responder  podem  ser 
categorizados  ainda  como  periódicos  (ocorrem  em  intervalos  regulares)  ou  aperiódicos  – 
também chamados de assíncronos ‐ (acontecem de modo imprevisível) (TANENBAUM, 2003, 
p. 108‐109; DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 225‐226).  

Um  sistema  pode  ter  de  responder  a  múltiplos  fluxos  de  eventos  periódicos. 
Dependendo de quanto tempo cada evento requeira para processar, talvez nem seja possível 
tratar  de  todos.  Por  exemplo,  se  houver  m  eventos  periódicos  e  o  evento  i  ocorrer  com 
período Pi  e requerer Ci  segundos de UCP  para tratar cada evento, então a carga poderá ser 
tratada somente se  

m
Ci

i =1 Pi
≤1
 

Um  sistema  de  tempo  real  que  satisfaça  esse  critério  é  chamado  de  escalonável 
(TANENBAUM, 2003, p. 108‐109). 
Como  exemplo,  considere  um  sistema  de  tempo  real  não‐crítico  com  três  eventos 
periódicos,  com  períodos  de  100,  200  e  500  ms,  respectivamente.  Se  esses  eventos 
requererem  50,  30  e  100  ms  de  tempo  de  UCP  por  evento,  nessa  ordem,  o  sistema  é 
escalonável  porque  0,5  +  0,15  +  0,2  <  1.  Se  um  quarto  evento,  com  período  de  1  s,  for 
adicionado, o sistema permanecerá escalonável desde que esse evento não precise de mais de 
150 ms do tempo de UCP por evento. Implícita nesse cálculo está a hipótese de que o custo 
extra  do  chaveamento  de  contextoé  tão  pequeno  que  pode  ser  desprezado  (TANENBAUM, 
2003, p. 109). 

Os algoritmos de escalonamento de tempo real podem ser estáticos ou dinâmicos. Os 
primeiros tomam suas decisões de escalonamento antes de o sistema começar a executar. Os 
últimos  o  fazem  em  tempo  de  execução.  O  escalonamento  estático  só  funciona  quando  há 
prévia informação perfeita disponível sobre o trabalho necessário a ser feito e os prazos que 
devem  ser  cumpridos.  Os  algoritmos  de  escalonamento  dinâmico  não  apresentam  essas 
restrições (TANENBAUM, 2003, p. 109).  

2.6.3 Algoritmos de escalonamento de tempo real estáticos 
Algoritmos  de  escalonamento  de  tempo  real  estáticos  não  ajustam  a  prioridade  do 
processo  ao  longo  do  tempo.  Porque  as  prioridades  são  calculadas  somente  uma  vez,  esses 
algoritmos tendem a ser simples e a incorrer em pouca sobrecarga. Eles são limitados, pois não 
podem se ajustar ao comportamento variável do processo e dependem de os recursos estarem 
funcionando  e  à  sua  disposição  para  garantir  que  sejam  cumpridas  as  restrições  de  tempo 
(DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 226). 

Sistemas de tempo real críticos tendem a usar algoritmos de escalonamento estáticos, 
porque  incorrem  em  baixa  sobrecarga  e  é  relativamente  fácil  de  provar  que  as  restrições  de 
prazo de cada processo sejam atendidas. O algoritmo de escalonamento por taxa monotônica 
(Rate Monotonic ‐ RM), por exemplo, é um algoritmo de alternância circular preemptivo, por 
prioridade,  que  eleva  a  prioridade  de  um  processo  linearmente  (monotonicamente)  com  a 
freqüência  (a  taxa)  com  a  qual  ele  deve  executar.  Esse  algoritmo  de  escalonamento  estático 
favorece processos periódicos que executam freqüentemente (STEWART, D.; KHOSLA, P., 1991 
apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  ,  2005,  p.  226)46.  O  algoritmo  por  taxa 
monotônica  com  prazo  pode  ser  usado  quando  um  processo  periódico  especifica  um  prazo 

                                                            
46
  STEWART,  D.;  KHOSLA,  P.  “Real‐time  scheduling  of  dynamically  reconfigurable  systems”,  Proceedings  of  the  IEEE 
International Conference on Systems Engineering. Dayton, OH, ago. 1991, p. 139‐142. 
que  não  seja  igual  ao  seu  período  (POTKONJAK,  M.;  WOLF,  W.,  1999  apud  DEITEL,  H.  M.; 
DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 226)47. 

2.6.4 Algoritmos de escalonamento de tempo real dinâmicos 
Algoritmos  de  escalonamento  de  tempo  real  dinâmicos  escalonam  processos 
ajustando  suas  prioridades  durante  a  execução,  o  que  pode  causar  sobrecarga  significativa. 
Alguns  algoritmos  tentam  minimizar  a  sobrecarga  de  escalonamento  designando  prioridades 
estáticas  a  alguns  processos,  e  prioridades  dinâmicas  a  outros  (XU,  J.;  PARNAS,  D.  L.,  1991 
apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 226)48. 

O algoritmo de escalonamento por prazo mais curto primeiro (Earliest Deadline First ‐ 
EDF)  é  do  tipo  preemptivo  que  despacha  primeiro  o  processo  com  o  prazo  mais  curto.  Se  o 
processo  que  chegar  tiver  um  prazo  mais  curto  do  que  o  processo  em  execução,  o  sistema 
provocará  a  preempção  do  processo  em  execução  e  despachará  o  que  acabou  de  chegar.  O 
objetivo é maximizar o rendimento cumprindo os prazos do maior número de processos por 
unidade de tempo (análogo ao algoritmo STR) e minimizando o tempo médio de espera (o que 
evita  que  processos  curtos  percam  seus  prazos  enquanto  processos  longos  executam). 
Dertouzos (1974,  apud Deitel, H. M.; Deitel, P. J.; Choffnes, D. R., 2005, p. 226) provou que, se 
um sistema fornecer preempção por hardware (temporizadores de interrupção) e os processos 
de  tempo  real  que  estão  em  escalonamento  não  forem  independentes,  o  EDF  minimizará  a 
quantidade de tempo pela qual o projeto “mais atrasado” perde seu prazo49. Todavia, muitos 
sistemas  de  tempo  real  não  fornecem  preempção  por  hardware,  portanto  outros  algoritmos 
devem  ser  empregados  (STEWART,  D.;  KHOSLA,  P.,  1991  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R. , 2005, p. 226)50. 

O  algoritmo  de  escalonamento  por  folga  mínima  primeiro  (Minimum  Laxity  First  ‐ 
MLF) é similar ao EDF, mas baseia sua prioridade na folga de um processo. Folga é uma medida 
da importância de um processo baseada na quantidade de tempo que falta até seu prazo final 
e  o  tempo  de  execução  que  ainda  resta  até  que  sua  tarefa  (que  pode  ser  periódica)  tenha 
terminado. A folga é calculada usando‐se a fórmula 

L = D – (T + C), 
                                                            
47
 POTKONJAK, M.; WOLF, W. “A methodology and algorithms for the design of hard real‐time multitasking ASICs”, 
ACM Transactions on Design Automation of Electronic Systems (TODAES), v. 4, nº 4, out. 1999. 
48
 XU, J.; PARNAS, D. L. “On satisfying timing constraints in hard‐real‐time systems”, Proceedins of the Conference on 
Software for Critical Systems. Nova Orleans, LO, 1991, p. 132‐146. 
49
  DERTOUZOS, M. L. “Control robotics: the procedural control of physical processes”, Information Processing, v. 74, 
1974. 
50
  STEWART,  D.;  KHOSLA,  P.  “Real‐time  scheduling  of  dynamically  reconfigurable  systems”,  Proceedings  of  the  IEEE 
International Conference on Systems Engineering. Dayton, OH, ago. 1991, p. 139‐142. 
onde L é a folga, D é o prazo do processo, T é o tempo atual e C é o tempo de execução 
restante do processo. Por exemplo, se o tempo atual for 5, o prazo de um processo for 9 e o 
processo precisar de 3 unidades de tempo para concluir, a folga será 1. Se um processo tiver 
folga  0,  deverá  ser  despachado  imediatamente  ou  perderá  seu  prazo.  Prioridades  no 
escalonamento  por  folga‐mínima‐primeiro  são  mais  precisas  do  que  as  do  EDF,  porque  são 
determinadas  incluindo  o  tempo  de  processador  restante  que  cada  processo  requer  para 
concluir  sua  tarefa.  Porém,  às  vezes  essa  informação  não  está  disponível  (STEWART,  D.; 
KHOSLA, P., 1991  apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 226)51. 

2.7 Escalonamento de threads  
Antes  de  abordar  o  escalonamento  de  threads  deve‐se  diferenciar  os  SOs  que 
reconhecem threads com os que não reconhecem. Os SOs que não reconhecem threads junto 
com seus processos de usuário devem carregar uma biblioteca que fará o papel de intermédio 
entre  as  threads  do  processo  e  o  kernel.  Já  os  SOs  que  reconhecem  threads  não  necessitam 
destas  bibliotecas  pois  o  próprio  kernel  se  encarregará  dessas  rotinas.  No  Primeiro  caso  a 
biblioteca de threads escalona threads de usuário para a execução em um LWP disponível, um 
esquema  chamado escalonamento local ao processo. Considere‐se LWP como processo leve. 
No segundo caso o kernel utiliza o escalonamento global do sistema para decidir que thread de 
kernel escalonar (SILBERSCHATZ, A.; GALIN, P.; GAGNE, G., 2000, p. 110). 

Para ilustrar esta explicação observa‐se na figura 2.16(a) os SOs orientados a processos 
com suporte a threads  e na figura 2.16(b) os SOs orientados a threads. 

         
(a)                                                                                  (b) 

   
 
  Figura 2.16. Processos e threads. (a) SO orientado a processos com suporte a threads. (b) SO orientado a 
                                                             threads.
51
  STEWART,  D.;  KHOSLA,  P.  “Real‐time  scheduling  of  dynamically  reconfigurable  systems”,  Proceedings  of  the  IEEE 
International Conference on Systems Engineering. Dayton, OH, ago. 1991, p. 139‐142. 
mplo 1: Solaris 2 
Exem

Este SO eescala thread
ds baseados eem prioridad
des que são ssubdividas em 4 níveis: ttempo 
real, sistema, inteerativo e tem
mpo comparttilhado. 

Os thread
ds na classe d prioridade paara executar entre 
de tempo reeal recebem aa mais alta p
todass as classes.  Essa atribuiçção permite  que um pro
ocesso de tempo real ten
nha uma ressposta 
ntida do sisteema em um período limitado de tem
garan mpo. (SILBERSSCHATZ, A.; G
GALIN, P.; GA
AGNE, 
G., 20
000, p. 111).   

2.17 ilustra o
A figura 2 o escalonameento de threads no Solaris 2. 

Figura 2.17. Escalonamentto no Solaris 2
2

Exem
mplo 2: Java 

No  Java  uma  applet  ou  aplicação  é  multtithread.  Cad


da  thread  JJava  recebe  uma 
prioridade  na  faixa  e
entre  Threead.MIN_PR
RIORITY(uma  constantte  de  1) 
1 e 
Threaad.MAX_PRIO
ORITY(uma  constante  de 
d 10).  Por  Padrão,  cada  thread  rrecebe  priorridade 
Threaad.NORM_PR
RIORITY(umaa constante de 5). Cada novo thread herda a prio
oridade do thread 
que o
o criou (DEITTEL, H. M.; DEEITEL, P. J.; C
CHOFFNES, D
D. R. , 2005, p
p. 227). 

Ao implementar threeads de usuáário, o tempo de execuçção Java conta com intervalos 
de  teempo  para  executar 
e o  de  threads  (DEITEL,  H.  M.;  DEITEL,,  P.  J.; 
escaalonamento  preemptivo
CHOFFFNES, D. R. , 2005, p. 22
27). 
O Escalon
nador de threead Java garrante que o tthread de priioridade maiis alta da mááquina 
virtuaal  Java  esteeja  executan
ndo  o  temp
po  todo.  Se
e  houver  mú
últiplos  threeads  no  nívvel  de 
prioridade,  essess  executarão
o  usando  alternância 
a circular. 
c A  Figura 
F 2.18  ilustra  a  fiila  de 
prioridade multin
nível de priorridade para tthreads Javaa. Na figura ssupondo um computador com 
o  processado
único or,  cada  um  dos  thread
ds,  A  e  B,  exxecuta  duran
nte  um  quan
ntum  por  ve
ez  em 
altern
nância circullar até que aambos concluam a execu
ução. Em segguida, o threead C executta até 
finalizar. Os threaads D, E e F  executam durante um q
quantum cad
da um, em alternância circular  
até  que 
q todos  concluam  a  execução.EEsse  processo  continuaa  até  que  ttodos  os  th
hreads 
execu
utem  até  o  final.  Note  que, 
q depend
dendo  do  sisstema  operaacional,  threeads  que  che
egam, 
cuja  prioridade  mais 
m alta,  po
odem  adiar  indefinidam
mente  a  execcução  daqueeles  de  priorridade 
mais baixa (DEITEEL, H. M.; DEITEL, P. J.; CH
HOFFNES, D.. R. , 2005, p. 227‐228). 

Figura 2..18. Escalonam
mento de thre
ead Java por p
prioridade 

2.8 Esscalonamento de Multip processadores 
O objetivvo do escalon
namento commo já foi dito anteriormente é maximizar rendim
mento 
bem  como minim po de respostta e colocar  prioridades  de escalonamento tanto
mizar o temp o para 
mas 
sistem mono
oprocessadoss  como  em  mas 
sistem multip
processados.  Os  Sisttemas 
multiiprocessadoss  diferentem
mente  dos  monoprocesssados,  que  simplesmente  despach
ha  os 
proceessos,  devem
m  assegurar  que  os  processadore
p es  não  fiquem  ociosos  enquanto  estão 
esperrando que os processos  executem (D
DEITEL, H. M.; DEITEL, P.  J.; CHOFFNEES, D. R. , 20
005, p. 
463). 

m  atingidos  há  dois  tip


Para  quee  esses  objeetivos  sejam pos  de  polííticas  que  seriam 
s
escalonamentos  cegos  a  job
b  e  escalonaamento  cienttes  a  job.  Os 
O escalonam
mento  cego  a  job 
escalonam jobs em qualquer processador disponível já os cientes a jobs avalia as propriedades 
do  job  e  tenta  maximizar  o  paralelismo  de  cada  job  ou  a  afinidade  do  processador,  o  que 
aumenta  o  desempenho  ao  custo  do  aumento  de  sobrecarga  (DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES,  D.  R.  ,  2005,  p.  464).  Uma  outra  definição  bastante  parecida  é  dada  por 
Silberschatz  (2000)  só  que  ele  muda  a  nomenclatura  em  multiprocessadores  homogêneos 
(cegos a job) e heterogêneos (cientes a job).  

Todos  os  algoritmos  vistos  anteriormente  de  escalonamento  são  validos  para 
multiprocessadores  com  pequenas  diferenças  evidentes,  pois  tinha  um  processador  e  agora 
tem‐se vários. 

2.9 Política versus Mecanismo 
Até  o  momento,  tem‐se  presumido  tacitamente  que  todos  os  processos  no  sistema 
pertencem  a  usuários  diferentes  e  estão,  portanto,  competindo  pela  UCP.  Embora  isso  seja 
muitas  vezes  verdade,  um  processo  pode  ter  muitos  filhos  executando  sob  seu  controle  ‐ 
como, por exemplo, um processo de um sistema de gerenciamento de bancos de dados. Cada 
filho  pode  estar  atendendo  uma  requisição  diferente  ou  ter  uma  função  específica  para 
realizar  (análise  sintática  de  consultas,  acesso  a  disco  etc.).  É  totalmente  possível  que  o 
processo principal tenha uma idéia clara de quais de seus filhos sejam os mais importantes (ou 
tenham  tempo  crítico)  e  quais  sejam  os  menos  importantes.  Infelizmente,  nenhum  dos 
escalonadores discutidos anteriormente aceita qualquer entrada proveniente de processos do 
usuário  sobre  decisões  de  escalonamento.  Como  resultado,  o  escalonador  raramente  faz  a 
melhor escolha (TANENBAUM, 2003, p. 109). 

A solução para esse problema é separar o mecanismo de escalonamento da política de 
escalonamento.  Isso  significa  que  o  algoritmo  de  escalonamento  é  de  algum  modo 
parametrizado, mas que os parâmetros podem ser preenchidos pelos processos dos usuários. 
Considerando  novamente  o  exemplo  do  banco  de  dados.  Supondo‐se  que  o  núcleo  use  o 
algoritmo de escalonamento por prioridades, mas que faça uma chamada ao sistema na qual 
um processo seja capaz de configurar (e alterar) as prioridades e seus filhos. Desse modo, o pai 
pode  controlar  em  detalhes  como  seus  filhos  são  escalonados,  mesmo  que  ele  próprio  não 
faça o escalonamento. Nesse exemplo, o mecanismo de escalonamento está no núcleo, mas a 
política é estabelecida por um processo de usuário (TANENBAUM, 2003, p. 109). 
2.10 Avaliação de Algoritmos 
Existem  muitos  algoritmos  de  escalonamento,  cada  qual  com  seus  próprios 
parâmetros.  Como  resultado,  selecionar  um  algoritmo  de  escalonamento  de  UCP  para 
determinado sistema pode se tornar uma tarefa difícil.  

O  primeiro  problema  é  definir  os  critérios  usados  na  seleção  de  um  algoritmo.  Os 
critérios  geralmente  são  definidos  em  termos  de  utilização  da  UCP,  tempo  de  resposta  ou 
throughput.  Para  selecionar  um  algoritmo,  deve‐se  primeiro  definir  a  importância  relativa 
dessas medidas. Esses critérios podem incluir várias medidas, como: 

• Maximizar a utilização de UCP sob a limitação de que o tempo 
de resposta máximo é 1 segundo; 
• Maximizar o throughput de modo que o tempo de retorno seja 
(em média) linearmente proporcional ao tempo de execução total. 
Assim  que  os  critérios  de  seleção  tiverem  sido  definidos,  deve‐se  avaliar  os  vários 
algoritmos  em  consideração.  Existem  vários  métodos  de  avaliação  diferentes,  como  os  que 
serão apresentados a seguir. 

2.10.1 Modelagem determinista 
Uma  classe  importante  de  métodos  de  avaliação  é  a  avaliação  analítica.  A  avaliação 
analítica utiliza o algoritmo dado e o volume de trabalho do sistema para gerar uma fórmula 
ou número que avalia o desempenho do algoritmo para aquele volume de trabalho. 

Um  tipo  de  avaliação  analítica  é  a  modelagem  determinista.  Esse  método  pega  um 
determinado volume de trabalho predeterminado e define o desempenho de cada algoritmo 
para esse volume de trabalho. 

Por  exemplo,  considere  o  volume  de  trabalho  indicado  na  tabela  abaixo.  Todos  os 
cinco  processos  chegam  no  instante  0,  na  ordem  dada,  com  a  duração  do  surto  de  UCP 
expressa em milissegundos: 

Tabela 2.6 – Duração de surtos da UCP, em milissegundos  

Processo  Duração de surto 
P1  10 
P2  29 
P3  3 
P4  7 
P5  12 
 
Considere  os  algoritmos  de  escalonamento  FIFO,  SJF  e  RR  (quantum  =  10 
milissegundos)  para  esse  conjunto  de  processos.  Qual  dos  algoritmos  deve  dar  o  mínimo 
tempo de espera médio? 

Para o algoritmo FIFO, os processos seriam executados da seguinte maneira: 

P1  P2  P3  P4  P5 


0    10  39 42 49 61

O  tempo  de  espera  é  0  milissegundo  para  o  processo  P1,  10  milissegundos  para  o 
processo  P2,  39  milissegundos  para  o  processo  P3,  42  milissegundos  para  o  processo  P4  e  49 
milissegundos para o processo P5. Assim, o tempo de espera médio é (0 + 10 + 39 + 42 + 49)/5 
= 28 milissegundos. 

Com o escalonamento SJF, os processos seriam executados na forma que segue: 

P3  P4  P1  P5  P2 


0  3   10  20 32 61

O  tempo  de  espera  é  10  milissegundos  para  o  processo  P1,  32  milissegundos  para  o 
processo  P2,  0  milissegundo  para  o  processo  P3,  3  milissegundos  para  o  processo  P4  e  20 
milissegundos para o processo P5. Logo, o tempo de espera médio é (10 + 32 + 0 + 3 + 20)/5 = 
13 milissegundos. 

Com o algoritmo RR, os processos seriam executados assim: 

P1  P2  P3  P4  P5  P2  P5  P2 


0    10  20  23  30 40 50 52  61

O  tempo  de  espera  é  0  milissegundos  para  o  processo  P1,  32  milissegundos  para  o 
processo  P2,  20  milissegundo  para  o  processo  P3,  23  milissegundos  para  o  processo  P4  e  40 
milissegundos para o processo P5. Assim, o tempo de espera médio é (0 + 32 + 20 + 23 + 40)/5 
= 23 milissegundos. 

Verifica‐se, nesse caso, que a regra SJF resulta em menos do que a metade do tempo 
de  espera  médio  obtido  com  o  escalonamento  FIFO;  o  algoritmo  RR  retorna  um  valor 
intermediário. 

A  modelagem  determinista  é  simples  e  rápida.  Fornece  números  exatos,  permitindo 


que  os  algoritmos  sejam  comparados.  No  entanto,  requer  números  exatos  como  entrada,  e 
suas respostas só se aplicam nesses casos. Os principais usos da modelagem determinista são 
em  descrever  algoritmos  de  escalonamento  e  em  fornecer  exemplos.  Nos  casos  em  que  os 
mesmos programas estejam sendo executados seguidamente e nos quais seja possível medir 
exatamente  os  requisitos  de  processamento  do  programa,  a  modelagem  determinista  talvez 
possa  ser  usada  para  selecionar  um  algoritmo  de  escalonamento.  Em  um  conjunto  de 
exemplos, a modelagem  determinista  poderá indicar tendências que  podem  ser analisadas e 
comprovadas separadamente. Por exemplo, pode‐se demonstrar que, para o ambiente acima 
descrito  (todos  os  processos  e  seus  tempos  disponíveis  no  instante  0),  a  regra  SJF  sempre 
resultará no tempo de espera mínimo. 

Em geral, no entanto, a modelagem determinista é específica demais e requer muito 
conhecimento exato para ser útil. 

2.10.2 Modelo de filas 
Os  processos  que  são  executados  em  muitos  sistemas  variam  todos  os  dias,  por  isso 
não existe um conjunto fixo de processos (e tempos) para uso da modelagem determinista. O 
que  pode  ser  determinado,  no  entanto,  é  a  distribuição  dos  surtos  de  UCP  e  de  E/S.  Essas 
distribuições  podem  ser  medidas  e  aproximadas,  ou  simplesmente  estimadas.  O  resultado  é 
uma  fórmula  matemática  para  descrever  a  probabilidade  de  determinado  surto  de  UCP. 
Geralmente, essa distribuição é exponencial e é descrita pela sua média. Da mesma forma, a 
distribuição  dos  tempos  de  chegada  dos  processos  no  sistema  (a  distribuição  do  tempo  de 
chegada) deve ser dada. A partir dessas duas distribuições, é possível calcular o valor médio de 
throughput, utilização, tempo de espera etc. para a maioria dos algoritmos. 

O  sistema  de  computação  pode  ser  descrito  como  uma  rede  de  servidores.  Cada 
servidor tem uma fila de processos em espera. A UCP é um servidor com sua fila de processos 
prontos, assim como o sistema de entrada e saída com suas filas de dispositivos. Conhecendo 
as taxas de chegada e as taxas de serviço, pode‐se calcular a utilização, o tamanho médio da 
fila, o tempo de espera médio etc. Essa área de estudo é chamada de análise de redes de filas. 

Como exemplo, seja n o tamanho médio da fila (excluindo o processo sendo atendido), 
seja W o tempo de espera médio na fila e λ a taxa de chegada média para novos processos na 
fila  (como  três  processos  por  segundo).  Assim,  espera‐se  que  durante  o  tempo  W  que 
determinado processo espera, λ x W novos processos chegarão na fila. Se o sistema estiver em 
uma situação estável, o número de processos que saem da fila deverá ser igual ao número de 
processos que chegam. Assim, 

n = λ x W 
Essa  equação,  conhecida  como  a  fórmula  de  Little,  é  particularmente  útil  porque  é 
válida para qualquer algoritmo de escalonamento e distribuição de chegada. 

Pode‐se usar a fórmula de Little para calcular uma das três variáveis, se as outras duas 
forem  conhecidas.  Por  exemplo,  sabendo  que  sete  processos  chegam  a  cada  segundo  (em 
média), e que existem normalmente 14 processos na fila, pode‐se calcular o tempo de espera 
médio por processo como sendo de 2 segundos. 

A análise de filas pode ser útil na comparação dos algoritmos de escalonamento, mas 
também tem limitações. No momento, as classes de algoritmos e distribuições que podem ser 
tratadas são bem limitadas. A matemática  dos algoritmos ou distribuições complicadas pode 
ser difícil de dominar. Assim, as distribuições de chegada e serviço geralmente são definidas de 
forma  irrealista,  mas  matematicamente  tratáveis.  Geralmente,  também  é  necessário  fazer 
uma  série  de  hipóteses  independentes,  que  talvez  não  sejam  precisas.  Assim,  para  que  uma 
resposta possa ser calculada, os modelos de fila geralmente são apenas uma aproximação de 
um sistema real. Como resultado, a precisão dos resultados calculados pode ser questionável. 

2.10.3 Simulações 
Para obter uma avaliação mais precisa dos algoritmos de escalonamento, pode utilizar 
simulações.  Executar  simulações  envolve  programar  um  modelo  de  sistema  de  computador. 
Estruturas  de  dados  em  software  representam  os  principais  componentes  do  sistema.  O 
simulador  tem  uma  variável  que  representa  o  relógio;  à  medida  que  o  valor  dessa  variável 
aumenta, o simulador modifica o estado do sistema para refletir as atividades dos dispositivos, 
dos processos e do escalonador. À medida que a simulação executa, estatísticas que indicam o 
desempenho do algoritmo são coletadas e impressas. 

Os dados que conduzem a simulação podem ser gerados de várias formas. O método 
mais  comum  utiliza  um  gerador  de  números  aleatórios,  que  é  programado  para  gerar 
processos,  tempos  de  surtos  de  UCP,  chegadas,  partidas  e  assim  por  diante,  de  acordo  com 
distribuições  de  probabilidade.  As  distribuições  podem  ser  definidas  matematicamente 
(uniforme,  exponencial,  Poisson)  ou  empiricamente.  Se  a  distribuição  for  definida 
empiricamente, são feitas medidas do sistema real sendo estudado. Os resultados definem a 
distribuição  real  de  eventos  no  sistema  real;  essa  distribuição  pode  então  ser  usada  para 
conduzir a simulação. 

Uma  simulação  baseada  em  distribuição,  no  entanto,  pode  ser  imprecisa  devido  aos 
relacionamentos entre eventos sucessivos no sistema real. A distribuição de freqüência indica 
apenas  quantos  eventos  ocorrem;  não  revela  nada  sobre  a  ordem  de  sua  ocorrência.  Para 
corrigir esse problema, pode‐se usar registros de execução. Um registro de execução é criado 
por meio da monitoração do sistema real, registrando‐se a seqüência de eventos reais, como 
ilustrado na figura a seguir. 

  Figura 2.19. Avaliação dos escalonadores de UCP por simulação  

Em  seguida,  essa  seqüência  é  usada  para  conduzir  a  simulação.  Os  registros  de 
execução fornecem uma forma excelente de comparar dois algoritmos exatamente no mesmo 
conjunto  de  entradas  reais.  Esse  método  pode  produzir  resultados  precisos  para  suas 
entradas. 

As simulações podem ser caras, geralmente exigindo horas de tempo de computador. 
Uma simulação mais detalhada fornece resultados mais precisos, mas requer mais tempo de 
computação. Além disso, registros de execução podem exigir grandes quantidades de espaço 
de  armazenamento.  Finalmente,  o  projeto,  codificação  e  depuração  do  simulador  pode  ser 
uma grande tarefa. 

2.10.4 Implementação 
Mesmo uma simulação é de precisão limitada. A única forma completamente precisa 
de  avaliar  um  algoritmo  de  escalonamento  é  codificá‐lo,  colocá‐lo  no  sistema  operacional  e 
verificar  seu  funcionamento.  Essa  abordagem  coloca  o  algoritmo  real  no  sistema  real  para 
avaliação em condições reais de operação. 
A  principal  dificuldade  dessa  abordagem  é  o  alto  custo.  Os  custos  envolvem  não 
apenas a codificação do algoritmo e modificação do sistema operacional para suportá‐lo e as 
estruturas  de  dados  exigidas  por  ele,  mas  também  a  reação  dos  usuários  a  um  sistema 
operacional  em  constante  mudança.  A  maior  parte  dos  usuários  não  está  interessada  em 
construir  um  sistema  operacional  melhor;  simplesmente  querem  que  seus  processos  sejam 
executados e desejam utilizar seus resultados. Um sistema operacional em constante mudança 
não ajuda os usuários a realizar seu trabalho. 

A outra dificuldade com qualquer avaliação de algoritmo é que o ambiente no qual o 
algoritmo é usado será alterado. O ambiente mudará não só da forma normal, à medida que 
novos programas são escritos e os tipos de problemas mudam, mas também como resultado 
do desempenho do escalonador. Se processos curtos tiverem prioridade, os usuários poderão 
quebrar  processos  maiores  em  grupos  de  processos  menores.  Se  os  processos  interativos 
tiverem  prioridade  sobre  processos  não‐interativos,  os  usuários  poderão  mudar  para  uso 
interativo. 

Por  exemplo,  pesquisadores  projetaram  um  sistema  que  classificava  os  processos 
interativos e não‐interativos automaticamente, analisando a quantidade de entrada e saída no 
terminal. Se um processo não tivesse entrada nem saída para o terminal em um intervalo de 1 
segundo, ele era classificado como não‐interativo e movido para uma fila de baixa prioridade. 
Essa regra resultou em uma situação na qual um programador modificava seus programas para 
escrever  um  caractere  arbitrário  para  o  terminal  em  intervalos  regulares  de  menos  de  1 
segundo. O sistema dava a seus programas uma alta prioridade, embora a saída no terminal 
fosse completamente sem significado. 

Os algoritmos de escalonamento mais flexíveis podem ser alterados pelos gerentes do 
sistema ou pelos usuários de modo que possam ser ajustados para uma aplicação ou conjunto 
de  aplicações  específicas.  Por  exemplo,  uma  estação  de  trabalho  que  executa  aplicações 
gráficas  de  alto  nível  pode  ter  necessidades  de  escalonamento  diferentes  daquelas  de  um 
servidor  Web  ou  servidor  de  arquivos.  Alguns  sistemas  operacionais  ‐  particularmente  várias 
versões  do  UNIX  ‐  permitem  ao  administrador  do  sistema  ajustar  os  parâmetros  de 
escalonamento  para  uma  configuração  de  sistema  específica.  Outra  abordagem  é  usar  APIs 
como  yield(  )  e  setPriority(  ),  permitindo  assim  que  as  aplicações  tenham  comportamento 
previsível. A desvantagem dessa abordagem é que o ajuste de desempenho de um sistema ou 
aplicação muitas vezes não resulta em desempenho melhorado em situações mais gerais. 

   
CAPÍTULO 3 

ESTUDOS DE CASO 

3.1 Escalonamento no UNIX 
O Unix é um sistema interativo projetado para tratar múltiplos processos e usuários ao 
mesmo tempo. Ele foi projetado por e para programadores, para ser usado em um ambiente 
no  qual  a  maioria  dos  usuários  é  relativamente  sofisticada  e  engajada  em  projetos  de 
desenvolvimento  de  software  (freqüentemente  complexos).  Em  muitos  casos,  um  grande 
número  de  programadores  coopera  ativamente  para  produzir  um  único  sistema  e  nesse 
sentido  o  Unix  tem  extensos  recursos  para  permitir  que  as  pessoas  trabalhem  juntas  e 
compartilhem  informação  de  maneira  controlada.  O  modelo  de  grupo  de  programadores 
experientes  trabalhando  juntos  para  produzir  software  avançado  é  obviamente  muito 
diferente  do  modelo  de  computação  pessoal  de  um  único  principiante  trabalhando  sozinho 
com um processador de texto, e essa diferença é refletida por todo o Unix desde o início até o 
fim. 

Um sistema Unix pode ser considerado um tipo de pirâmide, como ilustrado na Figura 
3.1.  

 
Figura 3.1. As camadas em um sistema Unix 
 

Na base está o hardware, que é formado de UCP, memória, discos, terminais e outros 
dispositivos. Executando diretamente sobre o hardware está o sistema operacional Unix. Sua 
função é controlar o hardware e fornecer uma interface de chamadas aos sistema para todos 
os  programas.  Essas  chamadas  ao  sistema  permitem  que  os  programas  do  usuário  criem  e 
gerenciem processos, arquivos e outros recursos. Algumas das principais chamadas ao sistema 
do Unix são relacionadas na figura abaixo. 

 
Figura 3.2. Algumas chamadas ao sistema relacionadas com processos. O código de retorno s é ‐1 
 
quando ocorre um erro, pid é o ID do processo e residual é o tempo restante no alarme anterior. Os 
parâmetros são  aqueles sugeridos pelos próprios nomes.
 

As  únicas  entidades  ativas  no  Unix  são  os  processos,  muito  similares  aos  processos 
seqüenciais  clássicos  já  discutidos  anteriormente  neste  trabalho.  Cada  processo  executa  um 
único  programa  e  inicialmente  tem  um  único  thread  de  controle.  Em  outras  palavras,  ele 
possui  um  único  contador  de  programa  que  guarda  o  caminho  da  próxima  instrução  a  ser 
executada. Muitas versões do Unix permitem que um processo crie outros threads depois de 
iniciar sua execução.  

As  primeiras  versões  do  Unix  não  tinha  threads.  Essa  característica  foi  adicionada 
muitos anos depois. Inicialmente havia muitos pacotes de threads em uso, mas a proliferação 
desses  pacotes  dificultava  a  escrita  de  códigos  portáteis.  Por  fim,  as  chamadas  ao  sistema 
usadas para gerenciar threads foram padronizadas como parte do POSIX (P1003.1c). 

A  especificação  POSIX  não  estabelece  se  os  threads  devem  ser  implementados  no 
núcleo ou no espaço do usuário. A vantagem de ter os threads no espaço do usuário é que eles 
podem ser implementados sem a necessidade de alterar o núcleo, além de o chaveamento de 
contexto de threads ser muito eficiente. A desvantagem dos threads no espaço do usuário é 
que quando um thread é bloqueado (por exemplo, em uma E/S, um semáforo ou uma falta de 
página), todos os threads daquele processo também são bloqueados, pois o núcleo pensa que 
existe  somente  um  thread  e  não  escalona  o  processo  até  que  aquele  thread  seja  liberado. 
Assim,  as  chamadas  definidas  no  P1003.1c  foram  cautelosamente  escolhidas  para  ser 
implementadas  das  duas  maneiras.  Conforme  os  programas  dos  usuários  aderem 
cuidadosamente  à  semântica  do  P1003.1c,  as  duas  implementações  devem  funcionar 
corretamente. 

O  Unix  é  um  sistema  multiprogramado,  de  modo  que  múltiplos  processos 


independentes  podem  executar  ao  mesmo  tempo.  Cada  usuário  pode  ter  vários  processos 
ativos  de  uma  só  vez,  e,  assim,  em  um  grande  sistema,  é  possível  haver  centenas  ou  talvez 
milhares de processos executando. De fato, na maioria das estações de trabalho de um único 
usuário, mesmo que o usuário esteja ausente, muitos processos, chamados de daemons, estão 
executando  em  segundo  plano.  Esses  processos  são  iniciados  automaticamente  quando  o 
sistema é inicializado. (“Daemon” é uma ortografia variante de “demom”, espírito do mal.) 

Um  daemon  típico  é  o  cron.  Ele  acorda  uma  vez  por  minuto  para  verificar  se  existe 
algum trabalho para fazer. Caso exista, ele faz o trabalho. Depois, ele volta a dormir até que 
decorra  o  tempo  da  próxima  verificação.  Esse  daemon  é  necessário  porque  o  Unix  permite 
agendar atividades para serem executadas minutos, horas, dias ou mesmo meses depois. Além 
disso,  o  daemon  cron  também  é  usado  para  agendar  atividades  periódicas,  como  realizar 
backups do disco diariamente ou anualmente, ativar lembretes, etc. Outros daemons tratam 
as  mensagens  eletrônicas  que  chegam  e  que  saem,  gerenciam  a  fila  da  impressora  de  linha, 
verificam  a  quantidade  de  páginas  na  memória  e  assim  por  diante.  Daemons  são  simples  de 
implementar  no  Unix  porque  cada  um  é  um  processo  separado,  independente  de  todos  os 
demais processos. 

Como  o  Unix  sempre  constitui  um  sistema  de  multiprogramação,  seu  algoritmo  de 
escalonamento  foi  projetado  desde  o  início  para  fornecer  uma  boa  resposta  aos  processos 
interativos.  Ele  é  um  algoritmo  de  dois  níveis.  O  algoritmo  do  nível  inferior  escolhe  para 
executar o próximo processo de um conjunto de processos que estão na memória e o disco de 
modo que todos os processos tenham a oportunidade de estar na memória e assim poderem 
executar. 

Cada  versão  do  Unix  tem  um  algoritmo  de  escalonamento  de  nível  inferior 
ligeiramente  diferente,  mas  muitos  deles  são  parecidos  com  o  modelo  genérico  que  será 
apresentado.  O  algoritmo  de  nível  inferior  usa  múltiplas  filas.  Cada  fila  é  associada  a  uma 
prioridade  dentro  de  uma  faixa  de  valores  de  prioridades  não  sobrepostos.  Os  processos 
executando no modo do usuário (o topo do iceberg) têm valores positivos. Os processos que 
executam no modo núcleo (fazendo chamadas ao sistema) apresentam valores negativos. Os 
valores negativos possuem maiores prioridades e os valores positivos grandes têm as menores 
prioridades, como ilustrado na figura que segue. Somente os processos que estão na memória 
e  prontos  para  a  execução  são  colocados  nas  filas,  visto  que  a  escolha  deve  ser  feita  desse 
conjunto. 

  Figura 3.3. O escalonador do Unix é baseado em uma estrutura de fila multinível 

Quando o escalonador (de nível inferior) executa, ele investiga as filas começando com 
a de maior prioridade (isto é, maior valor negativo) até encontrar uma fila que esteja ocupada. 
O primeiro processo dessa fila é então escolhido e iniciado. Esse processo tem a permissão de 
executar  no  máximo  durante  um  quantum,  geralmente  100  ms,  ou  até  ser  bloqueado.  Se  o 
processo usar todo o seu quantum, ele será colocado de volta no final de sua fila e o algoritmo 
de  escalonamento  executará  novamente.  Assim,  os  processos  com  a  mesma  prioridade 
compartilham a UCP usando o algoritmo alternância circular (round‐robin). 

Uma vez por segundo, a prioridade de cada processo é recalculada de acordo com uma 
fórmula de três componentes: 

Prioridade = UCP_usage + nice + base 

Com  base  em  sua  nova  prioridade,  cada  processo  é  ligado  a  uma  fila  apropriada  da 
Figura  3.3,  cujo  número  é  obtido  geralmente  a  partir  da  divisão  da  prioridade  por  uma 
constante. Cada um dos três componentes da fórmula apresentada são analisados a seguir. 
O termo UCP_usage representa o número médio de tiques de relógio por segundo que 
o processo usou durante os últimos segundos decorridos. A cada tique do relógio, o contador 
de uso de UCP na entrada da tabela de processos do processo em execução é acrescido de 1. 
Esse  contador  no  final  será  adicionado  à  prioridade  do  processo  dando  a  ele  um  valor 
numérico maior e assim colocando‐o em uma fila de menor prioridade. 

Contudo, o Unix não pune um processo para sempre, pelo uso da UCP e, por isso, faz o 
termo  UCP_usage  diminuir  com  o  tempo.  Diferentes  versões  do  Unix  implementam  essa 
diminuição de maneiras ligeiramente diferentes. Um modo que tem sido empregado baseia‐se 
em  adicionar  o  valor  atual  do  UCP_usage  ao  número  de  tiques  adquiridos  no  intervalo  Δt 
anterior  e  dividir  o  resultado  por  2.  Esse  algoritmo  pondera  o  Δt  mais  recente  por  ½,  o  Δt 
anterior por ¼ e assim por diante. Esse algoritmo de ponderação é muito rápido, pois consiste 
apenas em uma adição e um deslocamento, mas há ainda outros esquemas de ponderação. 

Cada processo tem um valor nice associado a ele.  O valor‐padrão é 0, mas o alcance 
permitido é geralmente de ‐20 a +20. Um processo pode ajustar nice para um valor entre 0 e 
20 por intermédio da chamada ao sistema nice. Um usuário que calcula que p para um bilhão 
de casas decimais, sem segundo plano, pode colocar essa chamada em seu programa para ser 
camarada (nice, em inglês) com os outros usuários. Somente o administrador do sistema pode 
solicitar um serviço melhor do que o normal (que significa valores de ‐20 a 1). 

Quando um processo interrompe o núcleo, via software, para fazer uma chamada ao 
sistema, é perfeitamente possível que o processo tenha de ser bloqueado antes de completar 
a  chamada  ao  sistema  e  retornar  para  o  modo  usuário.  Por  exemplo,  o  processo  pode 
simplesmente ter realizado uma chamada ao sistema waitpid e com isso ter de esperar pelo 
término  de  um  de  seus  filhos.  Ele  pode  também  precisar  aguardar  pela  conclusão  de  uma 
entrada do terminal ou de uma E/S no disco, entre outras possibilidades. Ao ser bloqueado, ele 
é removido da estrutura de fila, pois já não está mais apto a executar. 

No entanto, quando ocorre o evento que ele estava esperando, ele é colocado de volta 
na fila com um valor negativo. A escolha da fila é determinada pelo evento que ele aguardava 
acontecer. N figura 3.3, a E/S no disco é mostrada como tendo alta prioridade, de modo que 
um processo que apenas leu ou escreveu em um bloco do disco provavelmente obterá a UCP 
dentro de 100 ms. A prioridade relativa da E/S do disco, da E/S do terminal etc. é fixada dentro 
do sistema operacional e somente pode ser modificada pela alteração de algumas constantes 
do  código‐fonte  seguida  de  recompilação  do  sistema.  Esses  valores  (negativos)  são 
apresentados  por  base  na  fórmula  dada  anteriormente  e  espaçados  o  suficiente  para  que 
processos  que  estejam  sendo  reiniciados  por  diferentes  razões  sejam  claramente  separados 
em diferentes filas. 

A  idéia  por  trás  desse  esquema  é  tirar  rapidamente  os  processos  do  núcleo.  Se  um 
processo  está  tentando  ler  um  arquivo  do  disco,  fazê‐lo  esperar  um  segundo  entre  as 
chamadas  read  causará  uma  lentidão  enorme  nesse  processo.  É  muito  melhor  deixá‐lo 
executar imediatamente após cada requisição ter sido concluída, de modo que ele tenha como 
fazer a próxima rapidamente. De maneira similar, se um processo estava bloqueado esperando 
uma entrada no terminal, ele é nitidamente um processo interativo e, como tal, a ele deveria 
ser  atribuída  uma  alta  prioridade,  tão  logo  estivesse  pronto,  para  garantir  que  os  processos 
interativos fossem bem servidos. Desse modo, os processos orientados a UCP (isto é, aqueles 
nas  filas  positivas)  basicamente  conseguem  todo  o  serviço  que  sobra  quando  todos  os 
processos interativos e orientados a E/S estão bloqueados. 

3.2 Escalonamento no Minix 
O  Minix  foi  um  dos  primeiros  sistemas  do  tipo  Unix  baseado  no  projeto  de  um 
micronúcleo (TANENBAUM, 2003, p. 507). Diferentemente do Unix, cujo kernel é um programa 
monolítico e não dividido em módulos, o Minix é uma coleção de processos que se comunicam 
entre  si  e  com  processos  de  usuário  utilizando  uma  única  primitiva  de  comunicação 
interprocesso  –  a  passagem  de  mensagem.  Esse  projeto  proporciona  uma  estrutura  mais 
flexível e modular, tornando fácil, por exemplo, substituir o sistema de arquivos inteiro por um 
completamente  diferente,  sem  nem  mesmo  precisar  recompilar  o  kernel  (TANENBAUM; 
WOODHULL, 2000, p. 76). 

Micronúcleos  têm  vantagens  sobre  os  sistemas  monolíticos  por  serem  fáceis  de 
compreender e manter devido a suas estruturas altamente modulares. Além disso, a migração 
de código no modo núcleo para o modo usuário permite que eles sejam altamente confiáveis 
porque a quebra de um processo no modo usuário causa menos prejuízo do que a quebra de 
um  componente  do  modo  núcleo.  A  principal  desvantagem  que  eles  apresentam  é  o 
desempenho  ligeiramente  menor  devido  às  trocas  extras  entre  o  modo  usuário  e  o  modo 
núcleo (TANENBAUM, 2003, p. 507‐508). 

O Minix é estruturado em quatro camadas, com cada camada executando uma função 
bem‐definida. Essas quatro camadas são ilustradas na figura abaixo. 
 
Figura 3.4. O Minix é estruturado em quatro camadas 

No Minix, o gerenciamento de recursos está em grande parte no kernel (camadas 1 e 
2) e a interpretação de chamadas de sistema está na camada 3. Servidores adicionais também 
podem  existir  na  camada  3.  Embora  os  servidores  sejam  processos  independentes,  eles 
diferem de processos de usuário por que são iniciados quando o sistema é inicializado e nunca 
terminam enquanto o sistema está ativo. Adicionalmente, embora executem no mesmo nível 
de  privilégio  que  os  processos  de  usuário  em  termos  das  instruções  de  máquina  que  lhes  é 
permitido  executar,  eles  recebem  prioridade  mais  alta  de  execução  que  os  processos  de 
usuário.  Para  acomodar  um  novo  servidor,  o  kernel  precisa  ser  recompilado.  O  código  de 
inicialização do kernel instala os servidores em entradas privilegiadas na tabela de processos 
antes de qualquer processo de usuário receber permissão para executar. 

Os processos no Minix seguem o modelo geral de processos descritos anteriormente 
neste  trabalho.  Os  processos  podem  criar  subprocessos,  que,  por  sua  vez,  podem  criar  mais 
subprocessos,  produzindo  uma  hierarquia  de  processos  constituída  no  formado  de  uma 
árvore.  De  fato,  todos  os  processos  de  usuário  no  sistema  inteiro  são  parte  de  uma  única 
árvore com init na raiz, como observa‐se na Figura 3.4. 

As  duas  principais  chamadas  de  sistema  do  Minix  para  gerenciamento  de  processos 
são  fork  e  exec.  Fork  é  o  único  meio  de  criar  um  novo  processo.  Exec  permite  criar  um 
processo  para  executar  um  programa  especificado.  Quando  um  programa  é  executado,  ele 
recebe  uma  parte  da  memória  cujo  tamanho  é  especificado  no  cabeçalho  do  arquivo  de 
programa.  Ele  mantém  essa  quantidade  de  memória  durante  toda  sua  execução,  embora  a 
distribuição  entre  segmento  de  dados,  segmento  de  pilha  e  não‐utilizado  possa  variar  à 
medida  que  o  processo  executa.  Todas  as  informações  sobre  um  processos  são  mantidas  na 
tabela de processos, que é dividida entre o kernel, o gerenciador de memória e o sistema de 
arquivos,  com  cada  um  desses  tendo  os  campos  que  precisa.  Quando  um  novo  processo 
aparece (por fork), ou um processo antigo termina (por exit ou por um sinal), o gerenciador de 
memória primeiro atualiza sua parte na tabela de processos e, então, envia mensagens para o 
sistema de arquivos e para o kernel informando‐os para fazer o mesmo. 

O sistema de interrupções é o que mantém um sistema operacional multiprogramado 
em  funcionamento.  Os  processos  bloqueiam  quando  fazem  requisições  entrada,  permitindo 
que  outros  processos  executem.  Quando  a  entrada  torna‐se  disponível,  o  processo  atual  em 
execução é interrompido pelo disco, pelo teclado ou por outro  hardware. O  relógio também 
gera interrupções utilizadas para certificar que um processo de usuário em execução que não 
solicitou  entrada  acabe  abandonando  a  UCP,  para  dar  a  outro  processo  sua  chance  de 
executar.  É  trabalho  da  camada  mais  baixa  do  Minix  ocultar  essas  interrupções, 
transformando‐as  em  mensagens.  No  que  diz  respeito  aos  processos  (e  tarefas),  quando  um 
dispositivo  de  E/S  completa  uma  operação  ele  envia  uma  mensagem  para  o  processo, 
acordando‐o e tornando‐o executável. 

Cada vez que um processo é interrompido, seja a partir de um dispositivo convencional 
de  E/S  ou  a  partir  do  relógio,  há  uma  oportunidade  para  determinar  qual  processo  merece 
uma  oportunidade  de  executar.  Naturalmente,  isso  também  deve  ser  feito  sempre  que  um 
processo  termina,  mas  em  um  sistema  como  o  Minix  as  interrupções  em  decorrência  das 
operações de E/S ou geradas pelo relógio ocorrem mais freqüentemente que o término de um 
processo. O escalonador do Minix utiliza um sistema de filas em três níveis, correspondentes 
às  camadas  2,  3  e  4  da  Figura  3.4.  Dentro  dos  níveis  de  tarefa  e  de  servidor,  os  processos 
executam até bloquearem, mas os processos de usuário são agendados utilizando round robin. 
As tarefas têm a prioridade mais alta, o gerenciador de memória e o servidor de arquivos vêm 
em seguida e, por último, os processos de usuário (Figura 3.5). 

 
Figura 3.5. O escalonador no Minix mantém três filas, uma para cada nível de prioridade 
 

 
Ao  selecionar  um  processo  para  executar,  o  escalonador  verifica  se  qualquer  tarefa 
está pronta. Se uma ou mais estiver pronta, a primeira da fila é executada. Se nenhuma tarefa 
estiver  pronta,  um  servidor  (sistema  de  arquivos  –  FS  ou  gerenciador  de  memória  –  MM)  é 
escolhido,  se  possível;  caso  contrário  um  processo  do  usuário  é  executado.  Se  nenhum 
processo  estiver  pronto,  o  processo  IDLE  é  escolhido.  Esse  é  um  laço  que  executa  até  que  a 
próxima interrupção ocorra. 

A  cada  tique  do  relógio,  uma  verificação  é  feita  para  ver  se  o  processo  atual  é  um 
processo de usuário que executou mais de 100 ms. Se for, o escalonador é chamado para ver 
se  outro  processo  de  usuário  está  esperando  pela  UCP.  Se  algum  for  localizado,  o  processo 
atual é movido para o fim de sua fila de agendamento e o processo agora no topo é executado. 
As tarefas, o gerenciador de memória e o sistema de arquivos nunca sofrem preempção pelo 
relógio, independente de quanto tempo eles tenham estado executando. 

3.2.1 Código e comentários 
Como  visto,  o  Minix  utiliza  um  algoritmo  de  escalonamento  de  múltiplos  níveis  que 
segue  bem  a  estrutura  mostrada  na  Figura  X.  Nessa  figura,  observa‐se  tarefas  de  E/S  na 
camada  2,  processos  de  servidor  na  camada  3  e  processos  de  usuário  na  camada  4.  O 
escalonador matem três filas de processo executáveis, um para cada camada, como mostrado 
na Figura 3.4. A matriz rdy_head tem uma entrada para cada fila, com essa entrada apontando 
para  o  processo  na  cabeça  da  fila.  De  maneira  semelhante,  rdy_tail  é  uma  matriz  cujas 
entradas apontam para o último processo em cada fila. Essas duas matrizes são definidas com 
a macro EXTERN em proc.h (linhas 5595 e 5596 da Figura 3.6). 

Sempre que um processo é bloqueado e acordado, ele é anexado ao fim de sua fila. A 
existência da matriz rdy_tail torna a adicionar um processo ao fim de uma fila uma definição 
eficiente.  Sempre  que  um  processo  em  execução  torna‐se  bloqueado,  ou  um  processo 
executável  é  eliminado  por  um  sinal,  esse  processo  é  removido  das  filas  do  escalonador. 
Somente processos executáveis são enfileirados. 

Dadas as estruturas de fila descritas acima, o algoritmo de escalonamento é simplório: 
encontrar a fila de prioridade mais alta que não está vazia e selecionar o processo na cabeça 
dessa  fila.  Se  todas  as  filas  estiverem  vazias,  a  rotina  de  espera  será  executada.  Na  figura  Y, 
TAXK_Q  tem  a  maior  prioridade.  O  código  de  escalonamento  está  no  arquivo  proc.c 
demonstrado na figura B.   

 
 

  Figura 3.6. Definição das matrizes rdy_head e rdy_tail. 

A fila é escolhida em pick_prock (linha 7910 da Figura 3.7). O principal trabalho dessa 
função é configurar proc_ptr. Qualquer alteração nas filas, que possa afetar a escolha de qual 
processo deve executar em seguida, requer que pick_proc seja chamada novamente. Sempre 
que o processo atual bloqueia, pick_proc é chamada para reescalonar a UCP. 

Prick_proc é simples. Há um teste para cada fila. TASK_Q é testada primeiro e se um 
processo nessa fila estiver pronto, pick_proc configura proc_ptr e imediatamente retorna. Em 
seguida,  SERVER_Q  é  testada,  e,  novamente,  se  um  processo  estiver  pronto,  pick_proc 
configura proc_ptr e retorna. Se houver um processo pronto na fila USER_Q, bill_ptr é alterada 
para  contabilizar  ao  processo  de  usuário  o  tempo  da  UCP  que  está  para  ser  fornecido  (linha 
7927  da  Figura  3.7).  Isso  garante  que  o  último  processo  de  usuário  a  executar  seja  cobrado 
pelo  trabalho  feito  em  seu  benefício  pelo  sistema.  Se  nenhuma  das  filas  tem  uma  tarefa 
pronta,  a  cobrança  é  transferida  para  o  processo  IDLE,  o  qual  sempre  está  pronto,  e  o 
escalona. O processo escolhido para executar não é removido de sua fila meramente porque 
foi selecionado. 

Os procedimentos enqueue (linha 7787 da Figura 3.7) e dequeue (linha 7823 da Figura 
3.7)  são  chamadas  para  colocar  um  processo  executável  em  sua  fila  e  remover  um  processo 
não  mais  executável  de  sua  fila,  respectivamente.  Enqueue  é  chamado  tanto  a  partir  de 
mini_send  como  de  mini_receive.  Enqueue  manipula  uma  das  três  filas  de  processos.  Ele 
simplesmente adiciona o processo ao final da fila apropriada. 

Dequeue  também  gerencia  filas.  Normalmente,  o  processo  que  ele  remove  está  na 
cabeça da sua fila, já que um processo deve estar executando para ser bloqueado. Nesse caso, 
dequeue chama pick_proc antes de retornar, como, por exemplo, na linha 7852 da Figura 3.7. 
Um processo de usuário que não está executando também pode tornar‐se não‐pronto se ele 
enviar um sinal e se o processo não for encontrado na cabeça de uma das filas, uma pesquisa é 
feita ao longo de USER_Q e ele é removido se for encontrado. 

Embora  a  maioria  das  decisões  de  escalonamento  seja  feita  quando  um  processo 
bloqueia ou desbloqueia, o escalonamento também deve ser feito quando a tarefa de relógio 
nota  que  o  processo  de  usuário  atual  excedeu  seu  quantum.  Nesse  caso,  a  tarefa  de  relógio 
chama sched (linha 7862 da Figura 3.7) para mover o processo da cabeça de USER_Q para o 
fim  dessa  fila.  Esse  algoritmo  resulta  na  execução  de  processos  de  usuário  estritamente  no 
estilo round robin. O sistema de arquivos, o gerenciador de memória e as tarefas de E/S nunca 
são colocados no fim de suas filas porque estiveram executando por muito tempo. Confia‐se 
em que elas funcionarão adequadamente e bloquearão depois de finalizarem seu trabalho. 

Ainda há mais algumas rotinas em proc.c que suportam escalonamento de processos. 
Por  exemplo,  lock_notify,  lock_send,  lock_enqueue  e  lock_dequeue  definem  um  bloqueio  
chamando  a  rotina  lock  e  então  liberam  o  bloqueio  por  meio  da  chamada  de  unlock  ao  seu 
término. 

Em  suma,  o  algoritmo  de  escalonamento  do  Minix  mantém  três  filas  de  prioridade, 
uma  para  as  tarefas  de  E/S,  uma  para  os  processos  de  servidor  e  uma  para  os  processos  de 
usuário. O primeiro processo na fila de prioridade mais alta sempre é executado primeiro. As 
tarefas e os servidores sempre têm permissão para executar até bloquearem, mas a tarefa de 
relógio  monitora  o  tempo  utilizado  por  processos  de  usuário.  Se  um  processo  de  usuário 
utilizar  todo  seu  quantum,  ele  é  colocado  no  fim  de  sua  fila,  obtendo,  assim,  um 
escalonamento por round robin simples entre os processos de usuário. 
 

   

Figura 3.7. Código de escalonamento no Minix (parte 1 de 11) 
 

   
Figura 3.7. Código de escalonamento no Minix (parte 2 de 11) 
Figura 3.7. Código de escalonamento no Minix (parte 3 de 11) 
   
Figura 3.7. Código de escalonamento no Minix (parte 4 de 11)
   
Figura 3.7. Código de escalonamento no Minix (parte 5 de 11)
 
 

   
Figura 3.7. Código de escalonamento no Minix (parte 6 de 11)
 

   
Figura 3.7. Código de escalonamento no Minix (parte 7 de 11) 
 

   
Figura 3.7. Código de escalonamento no Minix (parte 8 de 11)
 

   
Figura 3.7. Código de escalonamento no Minix (parte 9 de 11)
 

  Figura 3.7. Código de escalonamento no Minix (parte 10 de 11)
 
 

 
Figura 3.7. Código de escalonamento no Minix (parte 1 de 11)
 

3.3 Escalonamento no Windows XP 
No  Windows  XP,  um  processo  consiste  em  código  do  programa,  um  contexto  de 
execução, recursos (por exemplo, manipuladores de objeto) e um ou mais threads associados. 
O contexto de execução inclui itens como o espaço de endereçamento virtual do processo e 
vários atributos (por exemplo, prioridade de escalonamento) (PROCESSES apud DEITEL, H. M.; 
DEITEL,  P.  J.;  CHOFFNES,  D.  R.  ,  2005,  p.  673)52.  Ambos,  processos  e  threads,  são  objetos, 
portanto,  outros  processos  podem  obter  manipuladores  para  processos  e  threads  e  outros 
threads podem esperar por processos e eventos de threads exatamente como acontece com 
outros tipos de objetos (CREATING;  EVENT apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 
2005, p. 673)53, 54. 

3.3.1 Organização de processos e trheads 
O Windows XP armazena informações de contexto de processos e threads em diversas 
estruturas de dados. Um bloco de processo executivo (EPROCESS block) é a principal estrutura 
de  dados  que  descreve  um  processo.  O  bloco  EPROCESS  armazena  informações  que 
componentes do executivo usam quando manipulam um objeto processo; essas informações 
incluem  o  ID  (identificador)  do  processo,  um  ponteiro  para  a  tabela  de  manipuladores  do 
processo,  um  ponteiro  para  a  ficha  de  acesso  do  processo  e  informações  de  conjunto  de 
trabalho (por exemplo, os tamanhos mínimo e máximo do conjunto de trabalho do processo, 
histórico  de  falta  de  páginas  e  o  conjunto  de  trabalho  corrente).  O  sistema  armazena  blocos 

                                                            
52
  “PROCESSES  and  threads”,  MSDN  Library,  msdn.microsoft.com/library/en‐
us/dllproc/base/about_processes_and_threads.asp. 
53
 “CREATING processes”, MSDN Library, msdn.microsoft.com/library/en‐us/dllproc/base/creating_processes.asp. 
54
  “EVENT objects”, MSDN Library, msdn.microsoft.com/library/em‐us/dllproc/base/event_objects.asp. 
EPROCESS  em  uma  lista  encadeada  (SOLOMON,  D.;  RUSSINOVICH,  M.,  2000;  SCHREIBER,  S., 
2001 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 673)55, 56. 

Cada  bloco  EPROCESS  também  contém  um  bloco  de  processo  de  núcleo  (bloco 
KPROCESS). Um bloco KPROCESS armazena informações de processo usadas pelo micronúcleo 
(o  micronúcleo  gerencia  escalonamento  de  thread  e  sincronização  de  thread).  Portanto,  o 
bloco KPROCESS armazena informações, tais como a classe de prioridade básica do processo, o 
quantum  padrão  para  cada  um  de  seus  threads  e  sua  trava  giratória  (SCHREIBER,  S.,  2001; 
SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 673)57, 58. 

Os  blocos  EPROCESS  e  KPROCESS  existem  em  espaço  de  núcleo  e  armazenam 
informações  para  que  componentes  de  modo  núcleo  as  acessem  enquanto  manipulam  um 
processo.  O  sistema  também  armazena  informações  de  processo  em  um  bloco  de  ambiente 
de  processo  (process  enviroment  block  ‐  PEB),  que  é  armazenado  no  espaço  de 
endereçamento  do  processo.  O  bloco  EPROCESS  de  um  processo  aponta  para  o  PEB  do 
processo.  O  PEB  armazena  informações  úteis  para  os  processos  usuários,  como  uma  lista  de 
DLLs  ligadas  ao  processo  e  informações  sobre  o  heap  do  processo  (SCHREIBER,  S.,  2001; 
SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 673)59, 60. 

O  Windows  XP  armazena  dados  de  thread  de  maneira  similar.  Um  bloco  de  thread 
executivo  (bloco  ETRHEAD)  é  a  principal  estrutura  de  dados  que  descreve  um  thread. 
Armazena informações que componentes do executivo usam ao manipular um objeto thread. 
Essas  informações  incluem  o  ID  do  processo  do  thread,  seu  endereço  de  início,  sua  ficha  de 
acesso e uma lista de requisições de E/S pendentes. O bloco ETHREAD para um thread também 
aponta  para  o  bloco  EPROCESS  do  seu  processo  (SCHREIBER,  S.,  2001;  SOLOMON,  D.; 
RUSSINOVICH, M., 2000 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 673)61, 62. 

Cada  bloco  ETHREAD  armazena  o  bloco  de  thread  de  núcleo  (bloco  KTHREAD).  O 
micronúcleo  usa  informações  do  bloco  KTHREAD  para  escalonamento  e  sincronização  de 
thread. Por exemplo, o bloco KTHREAD armazena informações, tais como a prioridade básica e 
                                                            
55
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000. 
56
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001. 
57
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001, p. 416. 
58
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 291. 
59
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001, p. 429. 
60
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 291. 
61
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001, p. 416. 
62
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 319. 
a prioridade corrente do thread (a prioridade de um thread pode mudar), seu estado corrente 
(isto  é,  pronto,  em  espera)  e  quaisquer  objetos  de  sincronização  pelos  quais  ele  esteja 
esperando (SCHREIBER, S., 2001; SOLOMON, D.; RUSSINOVICH, M., 2000 apud DEITEL, H. M.; 
DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 673)63, 64.  

Os  blocos  ETHREAD  e  KTHREAD  existem  em  espaço  de  núcleo  e,  portanto,  não  são 
acessíveis  a  usuários.  O  bloco  de  ambiente  de  thread  (thread  enviroment  block  ‐  TEB) 
armazena informações sobre um thread no espaço de endereçamento do processo do thread. 
Cada bloco KTHREAD aponta para um TEB. O TEB de um thread armazena informações, como 
as seções críticas que o thread possui, seu ID e informações sobre sua pilha. Um TEB também 
aponta para o PEB do processo do thread (SCHREIBER, S., 2001; SOLOMON, D.; RUSSINOVICH, 
M., 2000 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 673)65, 66. 

Todos  os  threads  que  pertencem  ao  mesmo  processo  compartilham  um  espaço  de 
endereçamento  virtual.  Embora  grande  parte  de  sua  memória  seja  global,  threads  podem 
manter seus próprios dados no armazenamento local do thread (thread local storage ‐ TLS). 
Um thread dentro de um processo pode alocar um índice TLS ao processo; o thread armazena 
um ponteiro para dados locais em uma localização especificada (denominada um slot TLS) do 
índice. Cada thread que usar o índice recebe um slot TLS no índice no qual pode armazenar um 
item de dado. Uma utilização comum para um índice TLS é armazenar dados associados com 
uma  DLL  à  qual  um  processo  se  liga.  Processos  freqüentemente  contêm  muitos  índices  TLS 
para  acomodar  múltiplos  propósitos,  como  dados  de  subsistemas  de  DLL  e  de  ambiente. 
Quando threads não precisam mais de um índice TLS (por exemplo, a DLL conclui a execução), 
o  processo  pode  descartar  o  índice  (THREAD,  2003  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R. , 2005, p. 673‐674)67. Um thread também possui sua própria pilha de tempo 
de execução na qual também pode armazenar dados locais. 

3.3.2 Escalonamento de threads 
O  Windows  XP  não  contém  um  módulo  específico  de  “escalonador  de  threads”  –  o 
código  do  escalonador  é  dispersado  por  todo  o  micronúcleo.  O  código  de  escalonamento  é 
denominado  coletivamente  despachador  (SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud 
DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  ,  2005,  p.  675)68.  O  Windows  XP  suporta 
                                                            
63
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001, p. 419. 
64
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 320‐321. 
65
  SCHREIBER, S. Undocumented Windows 2000 secrets. Boston: Assison Wesley, 2001, p. 429. 
66
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 328. 
67
  “THREAD  local  storage”,  MSDN  Library,  fev.  2003,  msdn.microsoft.com/library/en‐
us/dllproc/base/thread_local_storage.asp. 
68
 SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000.  
escalonamento  preemptivo  entre  múltiplos  threads.  O  despachador  escalona  cada  thread 
independentemente do processo ao qual o thread pertence, significando que, se todo o resto 
for  igual,  o  mesmo  processo  implementado  com  mais  threads  terá  mais  tempo  de  execução 
(SCHEDULING,  2003  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  ,  2005,  p.  675)69.  O 
algoritmo  de  escalonamento  usado  pelo  Windows  XP  é  baseado  na  prioridade  do  thread. 
Antes de descrever detalhadamente o algoritmo de escalonamento, é conveniente investigar o 
ciclo  de  vida  de  um  thread  no  Windows  XP  (DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 675). 

3.3.3 Estados de threads 
No Windows XP, threads podem estar em qualquer um de oito estados, como 
demonstrado na Figura 3.8. 

Figura 3.8. Diagrama de transição de estado de thread 

Um thread começa no estado inicializado durante a sua criação. Uma vez concluída a 
inicialização,  o  thread  entra  no  estado  pronto.  Threads  no  estado  pronto  estão  esperando 
para usar um processador. Quando um despachador decide que um thread executará em um 
determinado processador em seguida, o thread entra no estado de reserva enquanto espera 
sua vez por aquele processador. Um thread está no estado de reserva, por exemplo, durante o 

                                                            
69
  “SCHEDULING  priorities”,  MSDN  Library,  fev.  2003,  msdn.microsoft.com/library/en‐
us/dllproc/base/scheduling_priorities.asp. 
chaveamento  de  contexto  do  thread  que  estava  executanto  anteriormente  para  aquele 
thread. Uma vez obtido um processador, o thread entra no estado de execução. Um thread sai 
do  estado  de  execução  se  terminar  a  execução,  exaurir  seu  quantum,  sofrer  preempção,  for 
suspenso ou estiver esperando um objeto. Se um thread terminar, entra no estado terminado. 
O  sistema  não  apaga  necessariamente  um  thread  terminado;  o  gerenciador  de  objeto  apaga 
um thread somente quando a contagem de referência do objeto do thread torna‐se zero. Se 
um thread em execução sofrer preempção ou exaurir seu quantum, volta ao estado pronto. Se 
um thread em execução começar a esperar por um manipulador de objeto, entra no estado de 
espera.  E,  também,  um  outro  thread  (com  direitos  de  acesso  suficientes)  ou  o  sistema  pode 
suspender  um  thread,  forçando‐o  a  entrar  no  estado  de  espera  até  que  o  thread  seja 
retomado. Quando o thread concluir sua espera, ou ele volta para o estado pronto ou entra no 
estado de transição. A pilha de núcleo de um thread no estado de transição foi paginada para 
fora da memória (por exemplo, porque não executou por um período de tempo e o sistema 
precisou de memória para outros propósitos), mas, para todos os efeitos, o thread está pronto 
para executar. O thread entra no estado pronto assim que o sistema paginar a pilha do núcleo 
do thread novamente para a memória. O sistema coloca um thread no estado desconhecido 
quando não está seguro do estado do thread (usualmente devido a um erro) (WIN_32, 2003; 
SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 675‐676)70, 71. 

3.3.4 Algoritmo de escalonamento de thread   
O  despachador  escalona  threads  com  base  na  prioridade  –  a  subseção  seguinte 
descreve  como  são  determinadas  as  prioridades  dos  threads.  Quando  um  thread  entra  no 
estado  pronto,  o  núcleo  o  coloca  na  fila  de  prontos  que  corresponde  à  sua  prioridade.  O 
Windows  XP  tem  32  níveis  de  prioridade  identificados  pelos  inteiros  de  0  a  31,  sendo  31  a 
prioridade  mais  alta  e  0  a  mais  baixa.  O  despachador  começa  com  a  fila  de  prontos  de 
prioridade  mais  alta  e  escalona  os  threads  dessa  fila  por  alternância  circular.  Um  thread 
permanece na fila de prontos enquanto estiver no estado pronto ou no estado em execução. 
Quando a fila estiver vazia, o despachador passa para a fila seguinte; continua fazendo isso até 
que ou todas as filas estejam vazias ou um thread de prioridade mais alta do que a do thread 
que  está  executando  correntemente  entre  no  seu  estado  pronto.  Nesse  último  caso,  o 
despachador  provoca  a  preempção  do  thread  de  prioridade  mais  baixa  e  executa  o  novo 
thread. Em seguida, o despachador executa o primeiro thread da fila de prontos não vazia de 

                                                            
70
 “WIN_32 thread”, MSDN Library, jul. 2003, msdn.microsoft.com/library/en‐us/wmisdk/wmi/win32_thread.asp. 
71
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 348‐349. 
prioridade  mais  alta  e  retorna  seu  procedimento  normal  de  escalonamento  (SCHEDULING, 
2003 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 676)72. 

Cada thread executa, por, no máximo, um quantum. No caso de preempção, os quanta 
de  threads  de  tempo  real  são  reajustados,  ao  passo  que  todos  os  outros  threads  terminam 
seus quanta quando readquirem um processador. Dar novos quanta aos threads de tempo real 
após a preempção permite que o Windows XP favoreça threads de tempo real que requerem 
alto nível de responsividade. O sistema devolve threads que sofreram preempção para a frente 
da  fila  de  prontos  apropriada  (SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud  DEITEL,  H.  M.; 
DEITEL,  P.  J.;  CHOFFNES,  D.  R.  ,  2005,  p.  676)73.  Note  que  threads  de  modo  usuário  podem 
evitar  isso  mascarando  certas  interrupções.  Eventos  como  um  thread  entrando  no  estado 
pronto, um thread saindo do estado de execução ou uma mudança na prioridade de um thread 
acionam a execução pelo sistema de rotinas de despachador – rotinas que executam no nível 
DPC/despacho. Elevando o IRQL para o IRQL DPC/despacho, threads de modo núcleo podem 
mascarar  escalonamento  e  eveitar  a  preempção.  Contuto,  threads  de  modo  usuário  ainda 
assim podem bloquear a execução de threads de sistema se suas prioridades forem mais altas 
(SOLOMON,  D.;  RUSSINOVICH,  M.,  2000  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.;  CHOFFNES,  D.  R.  , 
2005, p. 676)74. 

3.3.5 Determinação de prioridades de threads 
O Windows XP divide seus 32 níveis de prioridade (0‐31) em duas categorias. Threads 
de  tempo  real  (isto  é,  threads  que  devem  manter  um  alto  nível  de  responsividade  às 
requisições  do  usuário)  ocupam  os  16  níveis  superiores  de  prioridade  (16‐31),  e  threads 
dinâmicos ocupam os 16 níveis de prioridade mais baixos (0‐15). Somente o thread de página 
zero tem nível de prioridade 0. Esse thread usa ciclos sobressalentes de processador para zerar 
páginas livres da memória de modo que fiquem prontas para o uso (DEITEL, H. M.; DEITEL, P. 
J.; CHOFFNES, D. R. , 2005, p. 676). 

Cada thread tem uma prioridade básica que define o limite inferior que sua prioridade 
real  pode  ocupar.  A  prioridade  básica  de  um  thread  de  modo  usuário  é  determinada  pela 
classe de prioridade básica do seu processo e pelo nível de prioridade do thread. A classe de 
prioridade básica de um processo especifica uma estreita faixa que a prioridade básica de cada 
thread  de  um  processo  pode  ter.  Há  seis  classes  de  prioridade  básica:  ocioso,  abaixo  do 

                                                            
72
  “SCHEDULING  priorities”,  MSDN  Library,  fev.  2003,  msdn.microsoft.com/library/en‐
us/dllproc/base/scheduling_priorities.asp. 
73
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 356‐358. 
74
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 338‐347. 
normal,  normal,  acima  do  normal,  alto  e  tempo  real.  As  primeiras  cinco  dessas  classes  de 
prioridade (denominadas classes de prioridade dinâmica) abrangem níveis de prioridade de 0 
a  15;  são  chamadas  classes  de  prioridade  dinâmica  porque  as  prioridades  de  threads 
pertencentes  a  processos  dessas  classes  podem  ser  alteradas  dinamicamente  pelo  sistema 
operacional.  Os  threads  que  pertencem  a  processos  da  classe  de  prioridade  de  tempo  real 
têm  prioridades  entre  16  e  31;  a  prioridade  de  threads  de  tempo  real  é  estática.  Dentro  de 
cada classe de prioridade há diversos níveis de prioridade básicas: ocioso, mais baixo, abaixo 
do normal, normal, acima do normal, mais alto e de tempo crítico. Cada combinação de classe 
de  prioridade  básica  com  nível  de  prioridade  básica  mapeia  para  uma  prioridade  básica 
específica  (por  exemplo,  um  thread  de  nível  de  prioridade  básica  normal  e  uma  classe  de 
prioridade  normal  tem  prioridade  básica  7)  (SCHEDULING  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R. , 2005, p. 677)75. 

A  prioridade  de  um  thread  de  prioridade  dinâmica  pode  mudar.  Um  thread  recebe 
uma  elevação  de  prioridade  quando  sai  do  estado  de  espera,  tal  como  acontece  após  a 
conclusão de uma E/S ou depois que o thread obtém um manipulador para um recurso pelo 
qual está esperando. Similarmente, uma janela que recebe entrada (tal como de um teclado, 
mouse ou temporizador) ganha uma elevação de prioridade. O sistema também pode reduzir a 
prioridade  de  um  thread.  Quando  um  thread  executa  até  que  seu  quantum  expire,  sua 
prioridade  é  reduzida  de  uma  unidade.  Todavia,  a  prioridade  dinâmica  de  um  thread  nunca 
pode  cair  abaixo  de  sua  prioridade  básica  nem  subir  até  a  faixa  de  tempo  real  (PRIORITY 
BOOSTS apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 677)76. 

Finalmente,  para  reduzir  a  probabilidade  de  adiamento  indefinido  de  threads,  o 


despachador examina periodicamente (a cada poucos segundos) as listas de threads prontos e 
eleva a prioridade de threads dinâmicos que estão esperando há longo tempo. Esse esquema 
também ajuda a resolver o problema da inversão de prioridade. Inversão de prioridade ocorre 
quando  um  thread  de  alta  prioridade  é  impedido  de  obter  o  processador  por  um  thread  de 
prioridade  mais  baixa.  Por  exemplo,  um  thread  de  alta  prioridade  poderia  esperar  por  um 
recurso  retido  por  um  thread  de  baixa  prioridade.  Um  terceiro  thread  de  prioridade  média 
obtém  o  processador,  impedindo  que  o  thread  de  baixa  prioridade  execute.  Desse  modo,  o 
thread de média prioridade também está impedindo que o thread de alta prioridade execute – 
portanto,  inversão  de  prioridade.  O  despachador  eventualmente  elevará  a  prioridade  do 

                                                            
75
  “SCHEDULING  priorities”,  MSDN  Library,  msdn.microsoft.com/library/en‐
us/dllproc/base/scheduling_priorities.asp. 
76
 “PRIORITY BOOSTS”, MSDN Library, msdn.microsoft.com/library/en‐us/dllproc/base/priority_boosts.asp. 
thread  de  baixa  prioridade  para  que  ele  execute  e  termine  de  usar  o  recurso  (PRIORITY 
INVERSION apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 677)77. 

3.3.6 Escalonamento em multiprocessadores 
O  escalonamento  de  thread  em  multiprocessadores  amplia  o  algoritmo  de 
escalonamento  de  monoprocessadores  já  apresentado.  Todas  as  versões  do  Window  XP, 
exceto a Home Edition, provêem suporte para multiprocessadores. Contutdo, mesmo a Home 
Edition  provê  suporte  para  multiprocessamento  simétrico  (SMP)  usando  a  tecnologia  de 
hiperthreading  (HT)  da  Intel.  A  tecnologia  HT  permite  que  o  sistema  operacional  veja  um 
processador  físico  como  dois  processadores  virtuais.  Escalonamento  em  um  sistema  SMP  é 
similar  ao  escalonamento  em  um  sistema  monoprocessador.  Geralmente,  quando  um 
processador fica disponível, o despachador tenta escalonar o thread que está na frente da fila 
não  vazia  de  threads  prontos  de  prioridades  mais  altas.  Contudo,  o  sistema  também  tenta 
manter threads nos mesmos processadores para maximizar a quantidade de dados relevantes 
armazenados em caches L1 (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 677). 

Processos e threads podem especificar os processadores nos quais preferem executar. 
Um  processo  pode  especificar  uma  máscara  de  afinidade,  que  é  um  conjunto  de 
processadores nos quais seus threads têm permissão para executar. Um thread também pode 
especificar uma máscara de afinidade que deve ser um subconjunto da máscara de afinidade 
do seu processo (MULTIPLE apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 677)78. 
Similarmente,  um  job  também  pode  ter  uma  máscara  de  afinidade  que  cada  um  de  seus 
processos  associados  deve  estabelecer  como  sua  própria  máscara  de  afinidade.  Máscaras  de 
afinidade podem ser utilizadas para restringir processos de alta intensidade de computação a 
uns  poucos  processadores,  de  modo  que  aqueles  processos  não  interfiram  com  processos 
interativos mais críticos em relação ao tempo (DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 
2005, p. 677). 

Além  de  máscaras  de  afinidade,  cada  thread  armazena  seu  processador  ideal  e  seu 
último  processador.  Manipular  o  valor  do  processador  ideal  de  um  thread  permite  que 
desenvolvedores  possam  influenciar  se  threads  relacionados  devem  executar  em  paralelo 
(ajustando  processadores  ideais  de  threads  relacionados  a  processadores  diferentes)  ou  no 
mesmo  processador  para  compartilhar  dados  em  chache  (ajustando  os  processos  ideais  dos 
threads  ao  mesmo  processador).  Por  padrão,  o  Windows  XP  tenta  designar  processadores 
ideais diferentes a threads do mesmo processo. O despachador usa o último processador em 
                                                            
77
 “PRIORITY INVERSION”, MSDN Library, msdn.microsoft.com/library/en‐us/dllproc/base/priority_inversion.asp. 
78
  “MULTIPLE processors”, MSDN Library, msdn.microsoft.com/library/en‐us/dllproc/base/multiple_processors.asp. 
um esforço de escalonar um thread no mesmo processador no qual o thread foi executado da 
última vez. Essa estratégia aumenta a probabilidade de que os dados mantidos em cache pelo 
thread  durante  uma  execução  possam  ser  acessados  durante  a  próxima  execução  daquele 
thread  (SOLOMON,  D.;  RUSSINOVICH,  M.,  2000;  MULTIPLE  apud  DEITEL,  H.  M.;  DEITEL,  P.  J.; 
CHOFFNES, D. R. , 2005, p. 677)79, 80. 

Quando um processador fica disponível, o despachador escalona threads considerando 
a  prioridade  de  cada  um,  o  processador  ideal,  o  último  processador  e  há  quanto  tempo  um 
thread  está  esperando.  Conseqüentemente,  o  thread  que  está  na  frente  da  fila  não  vazia de 
threads prontos de prioridade mais alta pode não ser escalonado para o próximo processador 
disponível (mesmo que o processador esteja na máscara de afinidade do thread). Se o thread 
não estiver esperando há  muito  tempo e o processador que  estiver disponível não for o seu 
processador ideal nem o  último processador, o despachador pode escolher um outro  thread 
daquela fila de threads prontos que atenda a um ou a mais desses outros critérios (SOLOMON, 
D.; RUSSINOVICH, M., 2000 apud DEITEL, H. M.; DEITEL, P. J.; CHOFFNES, D. R. , 2005, p. 677)81. 

   

                                                            
79
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 371. 
80
  “MULTIPLE processors”, MSDN Library, msdn.microsoft.com/library/en‐us/dllproc/base/multiple_processors.asp. 
81
  SOLOMON, D.; RUSSINOVICH, M. Inside Windows 2000, 3 ed. Remond: Microsoft Press, 2000, p. 371‐373. 
CONCLUSÕES 
 

Diferentes  tipos  de  sistemas  exigem  diferentes  algoritmos  de  escalonamento 


de  processos.  Cada  algoritmo  deve  funcionar  de  modo  que  leve  ao  alcance  dos 
objetivos do sistema ao qual está vinculado. 

Os  algoritmos  devem  funcionar  de  forma  justa,  ou  seja,  devem  dar  chance  a 
todos os processos de receberem a UCP por uma quantidade de tempo o mais razoável 
possível.  Dependendo  do  tipo  de  processo,  cada  qual  poderá  necessitar  de  mais  ou 
menos  tempo  de  UCP.  Cabe  ao  escalonador  decidir  qual  processo  receberá  mais  ou 
menos UCP de acordo com o que achar mais justo. 

Assim, promover a alternância adequada de processos de modo que todos eles 
executem  seus  serviços  de  maneira  eficiente  àqueles  que  os  requisitaram,  fazem  do 
escalonador  de  processos  uma  importante  entidade  do  SO.  Sem  ele,  os  recursos 
seriam mal aproveitados, tempos de espera seriam acentuados e os usuários ficariam 
insatisfeitos. 

     
REFERÊNCIAS 
DEITEL,  Harvey  M.;  DEITEL,  Paul  J.;  CHOFFNES,  David  R.  Sistemas  operacionais.  3  ed. 
São Paulo: Pearson Prentice Hall, 2005. 

LAUDON,  Kenneth  C.;  LAUDON,  Jane  P.  Sistemas  de  informação  gerenciais: 
administrando a empresa digital. 5 ed. São Paulo: Pearson Prentice Hall, 2004. 

SILBERSCHATZ,  Abraham;  GALIN,  Peter;  GAGNE,  Greg.  Sistemas  operacionais: 


conceitos e aplicações. 5ª tiragem. Rio de Janeiro: Campus, 2000. 

TANENBAUM,  Andrew  S.  Sistemas  operacionais  modernos.  2  ed.  São  Paulo:  Pearson 
Prentice Hall, 2003. 

TANENBAUM,  Andrew  S.;  WOODHULL,  Albert  S.  Sistemas  operacionais:  projeto  e 


implementação. 2 ed. Porto Alegre: Bookman, 2000. 

Você também pode gostar