D e it e l D e it e l Choffnes D e it e i . D e it e i . C h o f f n f .s Pearson Education EMPRESA CIDADà D e it e l D e it e l C h o ffn es Sistemas H. M. Deitel P. J. Deitel D. R. Choffnes Tradução Aríete Simille Marques Revisão técnlccu Profa. Dra. Regina Borges de Araújo Professora adjunta do Departamento de Computação Universidade Federal de São Carlos - UFSCar PEARSON Prentice Hall São Paulo Brasil A rgentina Colôm bia Costa R ica Chile Espanha G uatem ala M éxico Peru Porto Rico Venezuela © 2005 by Pearson Education do Brasil © 2004 by Pearson Education, Inc. Tradução autorizada da edição original em inglês O perating System s,3rd Edition de Deitei, Harvey M.; Deitei, Paul J.; Choffnes,David R., publicada pela Pearson Education Inc., sob o selo Prentice Hall Todos os direitos reservados. N enhum a parte desta publicação poderá ser reproduzida ou transm itida de qualquer m odo ou por qualquer outro meio, eletrônico ou mecânico, incluindo fotocópia, gravação ou qualquer outro tipo de sistem a de arm azenam ento e transm issão de inform ação, sem prévia autorização, por escrito, da Pearson Education do Brasil. D iretor editorial: José Braga Gerente editorial: Roger Trim er Editora de desenvolvimento: Renatha Prado Gerente de produção: H eber Lisboa Editora de texto: M arileide Gomes Preparação: M ônica A guiar Revisão: Cecília M adarás, Lucrécia Freitas Capa: Eric Chaves, sobre o projeto original de Harvey M. Deitei, David R. Choffnes e Suzanne Behnke Editoração eletrônica: Figurativa Arte e Projeto Editorial Dados Internacionais de Catalogação na Publicação (CIP) (Câmara Brasileira do Livro, SP, Brasil) Deitei, H.M. Sistem as operacionais: terceira edição/H. M. Deitei, P.J. Deitei, D. R. Choffnes ; tradutora Aríete Sim illle M arques; revisão técnica Regina Borges de Araújo. Título o rig in a l: O perating System s, 3* Edition Bibliografia. São Paulo : Pearson Prentice Hall, 2005. ISBN 85-7605-011-0 1. Sistemas operacionais (Com putadores) I. Deitei, P.J. D. Choffnes, D.R. III. Título. 05-0032 CDD-005.43 índices para catálogo sistemático: 1. Sistem as operacionais : Com putadores : Processam ento de dados 2005 D ireitos exclusivos para a língua portuguesa cedidos à Pearson Education do Brasil, um a em presa do grupo Pearson Education Av. Erm ano M archetti, 1435 Cep: 05038-001 Lapa - São Paulo-SP Tel: (11) 3613-1222 — Fax: (11) 3611-0444 e-mail: vendas@ pearsoned.com 005.43 À memória^ de Edsger W. Vijkstra / Harvey M. Deitei Paul J. Deitei David R. Choffnes Aos meus cuws, BevevLy <mdJay Veddy, pelo amor, geKorosidaAe e uvspiraçdo. David SnMd.no 2.6.3 Linguagens de alto n ív el..................................... 49 2.6.4 Programação estruturada..................................... 50 2.6.5 Programação orientada a objeto......................... 50 2.7 Interfaces de programação de aplicação (A PIs)...................51 2.8 Compilação, ligação c carregamento..................................... 52 2.8.1 Com pilação............................................................ 52 2.8.2 Ligação.................................................................. 53 2.8.3 Carregamento........................................................55 2.9 Firmware....................................................................................57 2.10 Middleware................................................................................57 R esum o..................................................................................................... 58 Exercícios.................................................................................................. 60 Projetos sugeridos....................................................................................60 N otas......................................................................................................... 61 Prefacio...................................X I I I Parte-1 Introdução ac hardware,, software, e, sistemas operacionais........................ 1 1 Introdução aos sistemas operacionais................. 3 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 Introdução....................................................................................4 O que é um sistema operacional?..............................................4 O começo da história: décadas de 1940 e 1950........................5 A década de 1960.......................................................................6 A década de 1970....................................................................... 8 A década de 1980.......................................................................9 A história da Internet e da World Wide W eb...........................9 A década de 1990..................................................................... 11 2000 e afo ra...............................................................................13 Bases dc aplicação.................................................................... 14 Ambientes de sistemas operacionais......................................14 Componentes e objetivos do sistema operacional................ 16 1.12.1 Componentes centrais do sistema operacional............................................................ 16 1.12.2 Metas do sistema operacional.............................. 18 1.13 Arquiteturas de sistemas operacionais................................... 19 1.13.1 Arquitetura monolítica......................................... 19 1.13.2 Arquitetura em camadas...................................... 20 1.13.3 Arquitetura de micronúcleo................................. 21 1.13.4 Sistemas operacionais de rede e distribuídos.........................................................23 R esum o..................................................................................................... 24 Exercícios.................................................................................................27 Projetos sugeridos....................................................................................27 N otas......................................................................................................... 28 Parte, 2 Processos e, threads............................. €3 3 Conceito de,processos............................................ 65 3.1 Introdução................................................................................. 66 3.1.1 Definição de processo..........................................66 3.2 Estados de processo: ciclo de vida de um processo......................................................................... 67 3.3 Gerenciamento de processo.................................................... 68 3.3.1 Estados de processos e estados de transição............................................................ 68 3.3.2 Blocos de controle de processos (PCBs)/ Descritores de processo....................................... 69 3.3.3 Operações de processo........................................ 70 3.3.4 Suspender e retomar.............................................72 3.3.5 Chaveamento de contexto................................... 73 3.4 Interrupções.............................................................................. 74 3.4.1 Processamento de interrupções............................ 76 3.4.2 Classes de interrupção..........................................77 3.5 Comunicação interprocessos.................................................. 79 3.5.1 Sinais......................................................................79 3.5.2 Troca de m ensagens.............................................79 3.6 Estudo de caso: processos no Unix.........................................81 R esum o..................................................................................................... 83 Exercícios.................................................................................................. 84 Projetos sugeridos....................................................................................86 N otas......................................................................................................... 86 2 Conceitos de- hardware- e, software-,..................... 30 2.1 2.2 2.3 2.4 2.5 2.6 Introdução..................................................................................31 Evolução de dispositivos de hardware................................... 31 Componentes de hardware.......................................................32 2.3.1 Placas principais.....................................................32 2.3.2 Processadores........................................................33 2.3.3 Relógios..................................................................35 2.3.4 Hierarquia da memória.........................................35 2.3.5 Memória principal................................................ 37 2.3.6 Armazenamento secundário................................38 2.3.7 Barram entos..........................................................39 2.3.8 Acesso direto à memória (Direct Memory Access — D M A ).................................. 39 2.3.9 Dispositivos periféricos....................................... 40 Suporte de hardware para sistemas operacionais..................42 2.4.1 Processador............................................................ 42 2.4.2 Temporizadores e relógios.................................. 44 2.4.3 Autocarregamento (Bootstrapping)....................45 2.4.4 Plug and p la y ........................................................45 Caching e buffer........................................................................46 Visão geral do softw are...........................................................47 2.6.1 Linguagem de máquina e linguagem de montagem.........................................................47 2.6.2 Interpretadores e compiladores ......................... 48 4 Conceitos de, thread,.............................................. 88 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 Introdução..................................................................................89 Definição de thread.................................................................. 90 Motivação na criação dc threads.............................................91 Estados de threads: ciclo de vida de um thread.................... 92 Operações de thread................................................................. 94 Modelos dc th read ....................................................................95 4.6.1 Threads de usuário.................................................95 4.6.2 Threads de núcleo................................................ 96 4.6.3 Combinação de threads de usuário e de núcleo............................................................. 97 Considerações sobre implementações de threads.................99 4.7.1 Entrega de sinal de thread................................... 99 4.7.2 Término de threads............................................. 101 POSIX e P th read s..................................................................101 Threads Linux......................................................................... 102 StwiÁru) 4.10 4.11 Threads do Windows X P ....................................................... 104 Estudo de caso do Java Multithread, Parte I: introdução a threads Java...........................................................................106 R esum o................................................................................................... 109 Exercícios................................................................................................ 110 Projetos sugeridos.................................................................................. 111 N otas........................................................................................................111 5 Execução assíncrona, concorrente,..................... 113 5.1 5.2 Introdução................................................................................114 Exclusão mútua....................................................................... 114 5.2.1 Estudo de caso do Java multithread. Parte II: um relacionamento produtor/consumidor em Java.................................................................115 5.2.2 Seções críticas.....................................................121 5.2.3 Primitivas de exclusão mútua............................ 121 5.3 Implementação de primitivas de exclusão m útua....................................................................... 122 5.4 Soluções de software para problema de exclusão mútua...................................................................123 5.4.1 O algoritmo de Dekker.......................................123 5.4.2 Algoritmo de Peterson........................................131 5.4.3 Exclusão mútua de n threads: o algoritmo da padaria de Lam port............................................ 133 5.5 Soluções de hardware para o problema de exclusão mútua...................................................................137 5.5.1 Dcsabilitando interrupções..................................137 5.5.2 Instrução test-and-set......................................... 137 5.5.3 Instrução Sw ap....................................................139 5.6 Sem áforos................................................................................141 5.6.1 Exclusão mútua com semáforos........................141 5.6.2 Sincronização de threads com sem áforos.......142 5.6.3 Semáforos contadores........................................144 5.6.4 Implementação de semáforos............................ 144 R esum o................................................................................................... 145 Exercícios................................................................................................ 146 Projetos sugeridos.................................................................................. 148 Simulações sugeridas.............................................................................148 N otas........................................................................................................150 € Programação concorrente-.................................. 152 6.1 6.2 Introdução................................................................................153 Monitores................................................................................. 154 6.2.1 Variáveis condicionais......................................... 155 6.2.2 Alocação simples de recursos com monitores.....................................................155 6.2.3 Exemplo de monitor: buffer circular................ 156 6.2.4 Exemplo de monitor: leitores e escritores...... 159 6.3 Monitores J a v a ....................................................................... 161 6.4 Estudo de caso de Java multithread, Parte III: relacionamento produtor/consumidor em Java................... 162 6.5 Estudo de caso de Java multithread, Parte IV: buffer circular em Java........................................................... 167 R esum o................................................................................................... 175 Exercícios................................................................................................ 176 Projeto sugerido..................................................................................... 177 Simulação sugerida................................................................................177 N otas........................................................................................................177 7 Veadlock, e,adiamento indefinido................... 179 7.1 7.2 7.3 7.4 7.5 Introdução................................................................................180 Exemplos de dcadlocks......................................................... 180 7.2.1 Deadlock de tráfego.............................................180 7.2.2 Deadlock na alocação de recurso simples.......181 7.2.3 Deadlock cm sistemas de spooling.................. 182 7.2.4 Exemplo: o jantar dos filósofos.........................183 Problema relacionado: adiamento indefinido..................... 184 Conceitos de recurso...............................................................185 Quatro condições necessárias para deadlock.......................186 \Al 7.6 7.7 Soluções para o deadlock...................................................... 186 Prevenção de deadlock........................................................... 187 7.7.1 Negação da condição ‘de espera’ .................... 187 7.7.2 Negação da condição de ‘não-preempção’...... 188 7.7.3 Negação da condição de ‘espera circular’ ........189 7.8 Evitação de deadlock com o Algoritmo do Banqueiro de Dijkstra....................................................... 190 7.8.1 Exemplo de um estado seguro........................... 191 7.8.2 Exemplo de um estado inseguro........................192 7.8.3 Exemplo de transição de estado seguro para estado inseguro....................................................193 7.8.4 Alocação de recursos pelo Algoritmo do B anqueiro...................................................... 193 7.8.5 Deficiências do Algoritmo do Banqueiro.........194 7.9 Detecção de deadlock.............................................................194 7.9.1 Grafos de alocação de recursos..........................195 7.9.2 Redução de grafos de alocação de recursos.... 196 7.10 Recuperação de deadlock...................................................... 196 7.11 Estratégias de deadlock em sistemas atuais e futuros................................................................................... 198 R esum o................................................................................................... 199 Exercícios................................................................................................201 Projetos sugeridos................................................................................. 205 Simulações sugeridas............................................................................ 206 N otas....................................................................................................... 206 8 Escalonamento de,processador......................... 208 8.1 8.2 8.3 Introdução............................................................................... 209 Níveis de escalonamento...................................................... 209 Escalonamento preemptivo versus escalonamento não preemptivo.......................................................................211 8.4 Prioridades.............................................................................. 212 8.5. Objetivos de escalonamento.................................................. 212 8.6 Critérios de escalonamento................................................... 214 8.7 Algoritmos de escalonamento............................................... 215 8.7.1 Escalonamento primeiro-a-entrar-primeiroa-sair (FIFO)........................................................215 8.7.2 Escalonamento por altemância-circular (RR)......................................................................216 8.7.3 Escalonamento por processo-mais-curtoprimeiro (SPF).................................................... 218 8.7.4 Escalonamento por próxima-taxa-de-respostamais-alta (H R R N )..............................................218 8.7.5 Escalonamento por menor-tempo-de-execuçãorestante (SRT)..................................................... 219 8.7.6 Filas multiníveis de retom o...............................220 8.7.7 Escalonamento por fração ju s ta ....................... 222 8.8 Escalonamento por prazo...................................................... 224 8.9 Escalonamento de tempo real............................................... 225 8.10 Escalonamento de threads Java.............................................. 226 R esum o...................................................................................................228 Exercícios................................................................................................230 Projetos sugeridos.................................................................................232 Simulações sugeridas............................................................................ 232 N otas....................................................................................................... 233 Parte, 3 Memória, real e, virtual..... 235 9 Organização e,gerenciamento da, memória, real................................................ 237 9.1 9.2 9.3 9.4 9.5 9.6 Introdução............................................................................... 238 Organização da m em ória...................................................... 238 Gerenciamento de memória.................................................. 238 Hierarquia de m em ória..........................................................240 Estratégias de gerenciamento de m em ória......................... 241 Alocação de memória contígua e não contígua..................242 Sistm uis ojteratiotuiU m 9.7 Alocação de memória contígua em sistema monousuário.242 9.7.1 Sobreposições (overlays)................................... 243 9.7.2 Proteção em um sistema monousuário............ 244 9.7.3 Processamento em lote de fluxo único............ 245 9.8 Multiprogramação por partição fixa....................................246 9.9 Multiprogramação por partição variável............................. 250 9.9.1 Características da partição variável...................250 9.9.2 Estratégias de posicionamento de memória ...252 9.10 Multiprogramação com troca de memória (swapping).........................................................254 Resum o................................................................................................... 255 Exercícios................................................................................................257 Projetos sugeridos..................................................................................259 Simulações sugeridas............................................................................ 259 N otas....................................................................................................... 259 10 Organizarão da, HiewÁriA, t/irtual.................. 261 10.1 10.2 10.3 10.4 Introdução............................................................................... 262 Memória virtual: conceitos básicos..................................... 263 Mapeamento de bloco............................................................ 266 Paginação.................................................................................268 10.4.1 Tradução de endereço de paginação por mapeamento direto...................................... 271 10.4.2 Tradução de endereço de paginação por mapeamento associativo.............................272 10.4.3 Tradução de endereço de paginação por mapeamento dircto/associativo..................273 10.4.4 Tabelas de páginas multiníveis......................... 275 10.4.5 Tabelas de páginas invertidas............................277 10.4.6 Compartilhamento cm um sistema de paginação.......................................................279 10.5 Segmentação........................................................................... 281 10.5.1 Tradução de endereço de segmentação por mapeamento direto...................................... 283 10.5.2 Compartilhamento em um sistema de segmentação........................................................285 10.5.3 Proteção e controle de acesso em sistemas de segm entação.................................................. 286 10.6 Sistemas de segmentação/paginação .................................. 288 10.6.1 Tradução dinâmica de endereço em um sistema de segmentação/paginação..................289 10.6.2 Compartilhamento e proteção em um sistema de segmentação/paginação..................290 10.7 Estudo de caso: memória virtual da arquitetura Intel IA -32.............................................................................. 293 R esum o...................................................................................................297 Exercícios................................................................................................300 Projetos sugeridos..................................................................................302 N otas....................................................................................................... 302 11 QereKciamento de, memória, virtual.............. 305 11.1 11.2 11.3 11.4 11.5 11.6 Introdução............................................................................... 306 Localidade ............................................................................. 306 Paginação por dem anda......................................................... 307 Paginação antecipada............................................................. 309 Substituição de páginas..........................................................310 Estratégias de substituição de páginas.................................. 310 11.6.1 Substituição aleatória de páginas .................... 310 11.6.2 Estratégia de substituição de páginas FIFO (primeira a entrar, primeira a sair).................... 311 11.6.3 Anomalia F IF O ....................................................312 11.6.4 Substituição de página menos recentemente usada (M RU).......................................................313 11.6.5 Substituição de página menos freqiientemcnte usada (M FU ).......................................................314 11.6.6 Substituição de página não usada recentemente (NUR)...................................................................314 11.6.7 Modificações da FIFO: substituições de página ‘segunda chance’ e ‘relógio’ .............................316 11.6.8 Substituição de página longínqua.......................316 11.7 11.8 Modelo de conjunto de trabalho...........................................317 Substituição de página por freqüência de falta de página (FFP).........................................................321 11.9 Liberação de página............................................................... 322 11.10 Tamanho de página................................................................ 322 11.11 Comportamento do programa sob paginação..................... 324 11.12 Substituição de página local versus global..........................326 11.13 Estudo de caso: substituição de páginas no Linux...................................................................................326 R esum o................................................................................................... 328 Exercícios................................................................................................330 Projetos sugeridos..................................................................................332 Simulações sugeridas............................................................................ 333 N otas....................................................................................................... 333 Parte, 4 ArmAscesumcento secundário, arquivos e, bancos de, dados............................. 337 12 OtimizsuçÃo dodesempenho do disco.............. 339 12.1 12.2 12.3 Introdução................................................................................340 Evolução do armazenamento secundário.............................340 Características do armazenamento em disco de cabeçote m óvel....................................................................................... 340 12.4 Por que o escalonamento do disco é necessário.................. 343 12.5 Estratégias de escalonamento de disco................................. 344 12.5.1 Escalonamento de disco do tipo ‘primeira a chegar, primeira a ser atendida’ (FCFS)....... 344 12.5.2 Escalonamento de disco do tipo ‘tempo de busca mais curto primeiro’ (SSTF)..............346 12.5.3 Escalonamento de disco S C A N ....................... 347 12.5.4 Escalonamento de disco C -SC A N ................... 347 12.5.5 Escalonamento de disco FSCAN e SCAN de N-fases............................................................ 348 12.5.6 Escalonamento de disco LOOK eC -L O O K ........................................................... 349 12.6 Otimização rotacional............................................................ 351 12.6.1 Escalonamento SLTF..........................................351 12.6.2 Escalonamento SPTF e SATF...........................352 12.7. Considerações de sistem as..................................................... 353 12.8 Utilização de caches e buffers.............................................. 355 12.9 Outras técnicas de desempenho de disco.............................356 12.10 Arranjos redundantes de discos independentes................. 357 12.10.1 Visão geral do RA ID ..........................................358 12.10.2 Nível 0 (Striping)............................................... 360 12.10.3 Nível 1 (Espclhamento)..................................... 361 12.10.4 Nível 2 (Paridade Hamming ECC no nível do b it)...................................................................362 12.10.5 Nível 3 (paridade XOR ECC no nível do b it)...................................................................364 12.10.6 Nível 4 (paridade XOR ECC no nível de b lo c o )............................................................. 365 12.10.7 Nível 5 (paridade ECC XOR distribuída no nível de bloco)............................................... 366 R esum o................................................................................................... 368 Exercícios................................................................................................373 Projetos sugeridos..................................................................................374 Simulações sugeridas............................................................................ 374 N otas....................................................................................................... 374 13 Sistemas de arquivos e, de, bancos de dados.... 377 13.1 13.2 13.3 13.4 Introdução............................................................................... 378 Hierarquia de dados............................................................... 378 Arquivos...................................................................................379 Sistemas de arquivo..................................................................380 13.4.1 Diretórios............................................................. 381 13.4.2 M etadados........................................................... 384 StUKÁru) 13.4.3 M ontagem ............................................................385 13.5 Organização de arquivo......................................................... 387 13.6 Alocação de arquivos............................................................. 387 13.6.1 Alocação contígua de arquivos.......................... 388 13.6.2 Alocação de arquivo não contígua por lista encadeada............................................................ 388 13.6.3 Alocação de arquivo tabular não contígua......390 13.6.4 Alocação de arquivos não contígua indexada ............................................................. 392 13.7 Gerenciamento de espaço livre............................................. 393 13.8 Controle de acesso a arquivos.............................................. 396 13.8.1 Matriz de controle de acesso..............................396 13.8.2 Controle de acesso por classes de usuário....... 397 13.9 Técnicas de acesso a dados................................................... 397 13.10 Proteção da integridade dos dados....................................... 398 13.10.1 Cópia de segurança e recuperação...................398 13.10.2 Integridade de dados e sistemas de arquivos log-estruturados.................................................. 400 13.11 Servidores de arquivos e sistemas distribuídos...................402 13.12 Sistemas de bancos de dados.................................................403 13.12.1 Vantagens dos sistemas de bancos de dados ...403 13.12.2 Acesso a dados................................................... 404 13.12.3 Modelo de banco de dados relacionai............. 404 13.12.4 Sistemas operacionais e sistemas de bancos de dados.............................................406 R esum o...................................................................................................406 Exercícios................................................................................................410 Projetos sugeridos..................................................................................412 Simulações sugeridas............................................................................ 412 N otas....................................................................................................... 412 Parte^S Veseutpmko, processadores e,çjerwciaMterito de, mtdtiprocessaslor......................... 415 14 Desempenho eprojeto de,processador......... 417 14.1 14.2 Introdução............................................................................... 418 Tendências importantes que afetam as questões de desem penho.......................................................................418 14.3 Por que a monitoração e a avaliação do desempenho são necessárias................................................. 419 14.4 Medições de desempenho..................................................... 419 14.5 Técnicas de avaliação de desempenho.................................421 14.5.1 Rastreamento e traçado de perfil........................421 14.5.2 Cronometragens e microindicadores de desempenho (microbcnchmarks).................422 14.5.3 Avaliação específica de aplicação.................... 423 14.5.4 Modelos analíticos.............................................424 14.5.5 Indicadores de desempenho (benchmarks).....424 14.5.6 Programas sintéticos...........................................425 14.5.7 Simulação............................................................426 14.5.8 Monitoração de desempenho.............................427 14.6 Gargalos e saturação.............................................................. 427 14.7 Laços de retom o.....................................................................429 14.7.1 Retomo negativo..................................................429 14.7.2 Retomo positivo...................................................429 14.8 Técnicas de desempenho no projeto de processadores.....................................................................430 14.8.1 Computação com conjunto de instruções complexas (C ISC )..............................................430 14.8.2 Computação com conjunto de instruções reduzidas (RISC)................................................ 431 14.8.3 Processadores pós-R ISC................................... 433 14.8.4 Computação com instruções explicitamente paralelas (EPIC)......................................................................435 R esum o................................................................................................... 437 Exercícios................................................................................................438 üc Projetos sugeridos................................................................................. 440 Simulações sugeridas............................................................................ 440 N otas....................................................................................................... 441 15 QerwxiaMieHto de, UiultiprocessaAor............... 444 15.1 15.2 Introdução............................................................................... 445 Arquitetura de multiproccssador..........................................446 15.2.1 Classificação de arquiteturas seqüenciais e paralelas............................................................446 15.2.2 Esquemas de interconexão de processadores ..447 15.2.3 Sistemas fracamente acoplados versus sistemas fortemente acoplados......................... 452 15.3 Organização de sistemas operacionais multiprocessadores................................................................ 453 15.3.1 Mestre/escravo.................................................... 453 15.3.2 Núcleos separados..............................................454 15.3.3 Organização simétrica........................................ 454 15.4 Arquiteturas de acesso à mem ória....................................... 455 15.4.1 Acesso uniforme à memória.............................. 455 15.4.2 Acesso não uniforme à memória...................... 456 15.4.3 Arquitetura de memória somente de cache..... 457 15.4.4 Sem acesso à memória rem ota.......................... 458 15.5 Compartilhamento de memória em multiprocessadores ...459 15.5.1 Coerência de cache..............................................460 15.5.2 Replicação e migração de páginas....................461 15.5.3 Memória virtual compartilhada........................ 462 15.6 Escalonamento de multiprocessadores................................463 15.6.1 Escalonamento de multiprocessadores cegos ao jo b .........................................................464 15.6.2 Escalonamento de multiprocessadores ciente de j o b ........................................................465 15.7 Migração de processos...........................................................467 15.7.1 Fluxo de migração de processos.......................468 15.7.2 Conceitos de migração de processos................ 468 15.7.3 Estratégias de migração de processos............. 470 15.8 Balanceamento de carga........................................................471 15.8.1 Balanceamento estático de carga...................... 471 15.8.2 Balanceamento dinâmico de carga....................472 15.9 Exclusão mútua em multiprocessadores............................. 473 15.9.1 Travas giratórias.................................................. 475 15.9.2 Travas dormir/acordar....................................... 475 15.9.3 Travas de leitura/escrita..................................... 476 R esum o...................................................................................................477 Exercícios................................................................................................478 Projetos sugeridos................................................................................. 479 Simulações sugeridas............................................................................ 479 N otas....................................................................................................... 479 Parte, 6 CoMputação mó rede, e, distribuída,..... 485 16 Introdução às redes........................................... 487 16.1 16.2 16.3 16.4 16.5 16.6 16.7 Introdução............................................................................... 488 Topologia de re d e .................................................................. 488 Tipos de redes.........................................................................490 Pilha de protocolos T C P/IP.................................................... 491 Camada de aplicação............................................................... 492 16.5.1 Protocolo de Transferência de Hipertexto (H TTP)................................................................ 492 16.5.2 Protocolo de Transferência de Arquivos (FT P)....................................................................493 Camada de transporte............................................................493 16.6.1 Protocolo de Controle de Transmissão (TCP).............................................494 16.6.2 Protocolo de Datagrama do Usuário (U D P)..............................................494 Camada de re d e ......................................................................495 Sistemas operacionais * 16.7.1 Protocolo da Internet (IP)............................... ..496 16.7.2 Protocolo da Internet versão 6 (IP v6)........... ..496 16.8 Camada de enlace................................................................ ..497 16.8.1 Ethernet............................................................. ..497 16.8.2 Token ring......................................................... ..498 16.8.3 Interface de dados distribuídos por fibra (FDDI)............................................................... ..499 16.8.4 IE E E 8 0 2 .il (sem fio)..................................... ..499 16.9 Modelo cliente/servidor...................................................... ..500 R esum o................................................................................................ ..501 Exercícios............................................................................................. ,.503 Projetos sugeridos............................................................................... ,.503 Simulações sugeridas..........................................................................,.503 N otas.....................................................................................................,.504 17 Introdução cusvstemas distribuídos............... soe Introdução............................................................................. ,.507 Atributos de sistemas distribuídos..................................... ..507 17.2.1 Desempenho e escalabilidade......................... ..507 17.2.2 Conectividade e segurança............................. ,.508 17.2.3 Confiabilidade e tolerância a falh as.............. ,.508 ,.509 17.2.4 Transparência................................. 17.2.5 Sistemas operacionais de rede........................,.510 17.2.6 Sistemas operacionais distribuídos................ ,5 1 0 17.3 Comunicação em sistemas distribuídos............................ ,5 1 0 ,510 17.3.1 Middleware..................................... 17.3.2 Chamada a procedimento remoto (R P C )..... ,511 17.3.3 Invocação a método remoto (R M I)............... ,.512 17.3.4 CORBA (Common Object Request Brokcr Architccturc)....................................... .,.513 17.3.5 DCOM (Distributed Component Object M odel)..................................................,.513 17.3.6 Migração de processos em sistemas distribuídos...................................................... .,.514 17.4 Sincronização em sistemas distribuídos.......................... ,.514 17.5 Exclusão mútua em sistemas distribuídos....................... ,.515 17.5.1 Exclusão mútua sem memória compartilhada.................................................. ,.515 17.5.2 Algoritmo de exclusão mútua distribuída de Agrawala e Ricart........................................... .,515 17.6 Deadlock em sistemas distribuídos.................................... .,516 17.6.1 Deadlocks distribuídos.................................... .,516 17.6.2 Prevenção de deadlock.................................... .,517 17.6.3 Detecção de deadlock..................................... .,518 17.6.4 Um algoritmo distribuído para deadlock de recurso......................................................... .,519 17.7 Estudo de caso: O sistema operacional distribuído S prite................................................................ ,.520 17.8 Estudo de caso: O sistema operacional distribuído Amoeba............................................................. .,521 R esum o............................................................................................... .,522 Exercícios............................................................................................ .,524 N otas.................................................................................................... ,.525 17.1 17.2 18 Sistemas distribuídos e, serviços Web............. 18.1 18.2 18.3 18.4 18.5 527 Introdução............................................................................ .,528 Sistemas de arquivos distribuídos..................................... .,528 18.2.1 Conceitos de sistemas de arquivos distribuídos...................................................... .,528 18.2.2 Sistema de Arquivos de Rede (NFS)............ .,530 18.2.3 Sistema de Arquivo Andrcw (AFS).............. .,531 18.2.4 Sistema de Arquivo C oda.............................. .,533 18.2.5 Sistema de arquivo Sprite.............................. .,535 Sistemas multicomputadores............................................ .,537 Clustering (aglom eração).................................................. .,538 18.4.1 Tipos de clustering......................................... .,538 18.4.2 Benefícios do clustering................................. .,539 18.4.3 Exemplos de clustering.................................. .,539 Computação distribuída peer-to-peer................................ .,541 18.5.1 Aplicações cliente/servidor e peer-to-peer... .,541 18.5.2 Aplicações P2P centralizadas versus descentralizadas.................................................. 542 18.5.3 Descoberta e busca de p a r.................................. 543 18.5.4 JX TA ....................................................................544 18.6 Computação em grade........................................................... 545 18.7 Computação distribuída Java................................................ 546 18.7.1 Java Servlets e JavaServer Pages (JSP)........... 546 18.7.2 Jin i........................................................................ 548 18.7.3 JavaSpaces........................................................... 549 18.7.4 Java Management Extensions (JM X)................550 18.8 Serviços W eb...........................................................................551 18.8.1 A Plataforma .NET da M icrosoft...................... 552 18.8.2 Sun Microsystems e a plataforma Sun O N E ............................................................. 553 R esum o................................................................................................... 553 Exercícios................................................................................................555 Projetos sugeridos..................................................................................556 N otas....................................................................................................... 556 Partes 7 Segurança,......................................559 19 Segurança,............................................................ 561 19.1 19.2 Introdução............................................................................... 562 Criptografia............................................................................. 562 19.2.1 Criptografia por chave secreta............................ 564 19.2.2 Criptografia por chave pública...........................565 19.3 Autenticação........................................................................... 567 19.3.1 Autenticação básica............................................568 19.3.2 Biometria e cartões inteligentes......................... 569 19.3.3 Kerberos.............................................................. 570 19.3.4 Assinatura única................................................. 570 19.4 Controle de acesso.................................................................. 571 19.4.1 Direitos de acesso e domínios de proteção..........................................................571 19.4.2 Modelos c políticas de controle de acesso.......572 19.4.3 Mecanismos de controle de acesso ..................573 19.5 Ataques à segurança.............................................................. 575 19.5.1 Criptoanálise.......................................................575 19.5.2 Vírus e vermes.................................................... 575 19.5.3 Ataques de recusa de serviço (DoS).................577 19.5.4 Exploração de software....................................... 577 19.5.5 Invasão de sistema..............................................578 19.6 Prevenção de ataques e soluções de segurança...................579 19.6.1 Firewalls.............................................................. 579 19.6.2 Sistemas de detecção de intrusos(IDSs).......... 580 19.6.3 Software antivírus............................................... 581 19.6.4 Correções de segurança....................................... 582 19.6.5 Sistemas de arquivos seguros........................... 583 19.6.6 O Livro Laranja da Segurança.......................... 585 19.7 Comunicação segura.............................................................. 586 19.8 Protocolos de acordo de chave............................................... 586 19.8.1 Gerenciamento de chave..................................... 587 19.8.2 Assinaturas digitais............................................588 19.9 Infra-estrutura de chave pública, certificados e autoridades certificadoras......................................................589 19.10 Protocolos de comunicação segura...................................... 590 19.10.1 Camada segura de soquetes.................................590 19.10.2 Redes virtuais privadas (VPNs) e segurança IP (IPSec)............................................................ 591 19.10.3 Segurança sem fio................................................. 591 19.11 Esteganografia.........................................................................592 19.12 Segurança proprietária e de código-fonte aberto................. 593 19.13 Estudo de caso: segurança de sistemasU N IX ..................... 594 R esum o................................................................................................... 596 Exercícios................................................................................................597 Projetos sugeridos..................................................................................598 Simulação sugerida............................................................................... 598 N otas....................................................................................................... 598 SuuiÁrLo 21 EstuÁo de, auo: Windows XP........................... €63 Parte* 8 Estudos de*ccusos de*sUtemar O jW & C lO tU ltf. 603 20 Estudo de*caro: Líhm*k .................................... 605 20.1 20.2 20.3 xt Introdução.................................................................................606 H istória....................................................................................606 Visão geral do Linux.............................................................. 608 20.3.1 Desenvolvimento e comunidade........................ 608 20.3.2 Distribuições........................................................609 20.3.3 Interface com o usuário..................................... 609 20.3.4 Padrões................................................................ 609 20.4 Arquitetura do núcleo............................................................ 610 20.4.1 Plataformas de hardware.....................................611 20.4.2 Módulos de núcleo carregáveis........................ 612 20.5 Gerenciamento de processo.................................................. 613 20.5.1 Organização de processos e threads.................. 613 20.5.2. Escalonamento de processo...............................615 20.6 Gerenciamento de memória.................................................. 618 20.6.1 Organização de memória.....................................619 20.6.2 Alocação e desalocação de memória física.... 622 20.6.3 Substituição dc páginas..................................... 624 20.6.4 Troca de páginas (Swapping)........................... 625 20.7 Sistemas de arquivos.............................................................. 626 20.7.1 Sistema dc arquivo virtual...................................626 20.7.2 Caches de sistema de arquivo virtual.............. 628 20.7.3 Segundo sistema de arquivo estendido (ext2fs)................................................................ 630 20.7.4 Sistema proc file................................................. 633 20.8 Gerenciamento de entrada/saída...........................................634 20.8.1 Drivers de dispositivos........................................ 634 20.8.2 E/S por dispositivo de caractere....................... 636 20.8.3 E/S por dispositivo de bloco..............................637 20.8.4 E/S por dispositivos de rede..............................640 20.8.5 Modelo de dispositivo unificado...................... 640 20.8.6 Interrupções.........................................................642 20.9 Sincronização de núcleo........................................................643 20.9.1 Travas giratórias................................................... 643 20.9.2 Travas de leitor/escritor..................................... 644 20.9.3. Seqlocks.............................................................. 644 20.9.4 Semáforos de núcleo............................................645 20.10 Comunicação interprocessos................................................ 646 20.10.1 Sinais....................................................................646 20.10.2 Pipes.....................................................................647 20.10.3 Soquetes.............................................................. 648 20.10.4 Filas de mensagens.............................................648 20.10.5 Memória compartilhada...................................... 649 20.10.6 Semáforos de System V ...................................... 650 20.11 R edes....................................................................................... 650 20.11.1 Processamento de pacotes................................... 651 20.11.2 Estrutura netfilter e ganchos................................652 20.12 Escalabilidadc........................................................................... 652 20.12.1 Multiprocessamento simétrico (SMP)................653 20.12.2 Acesso não uniforme à memória (NUM A)...... 653 20.12.3 Outras características dc escalabilidadc............ 654 20.12.4 Linux embarcado.................................................. 654 20.13 Segurança.................................................................................655 20.13.1 Autenticação........................................................655 20.13.2 Métodos de controle de acesso............................655 20.13.3 Criptografia........................................................... 656 Exercícios................................................................................................657 N otas....................................................................................................... 658 21.1 21.2 21.3 21.4 21.5 Introdução............................................................................... 664 H istória....................................................................................664 Metas de projeto...................................................................... 666 Arquitetura do sistema............................................................ 666 Mecanismos de gerenciamento de sistem a...........................668 21.5.1 R egistro............................................................... 668 21.5.2 Gerenciador de objeto........................................ 669 21.5.3 Níveis de requisição de interrupção (IRQ Ls)............................................................... 670 21.5.4 Chamadas assíncronas de procedimento (APCs)................................................................. 671 21.5.5 Chamadas postergadas de procedimento (DPCs)................................................................. 672 21.5.6 Threads de sistem a..............................................672 21.6 Gerenciamento de processos e threads................................ 673 21.6.1 Organização dc processos e threads..................673 21.6.2 Escalonamento de threads.................................. 675 21.6.3 Sincronização de threads.................................... 678 21.7 Gerenciamento dc memória................................................... 681 21.7.1 Organização de memória.................................... 681 21.7.2 Alocação de memória..........................................683 21.7.3 Substituição de páginas.......................................686 21.8 Gerenciamento de sistemas de arquivos.............................. 687 21.8.1 Drivers de sistemas de arquivo......................... 688 21.8.2 N TFS....................................................................688 21.9 Gerenciamento de entrada/saída............................................692 21.9.1 Drivers de dispositivos........................................692 21.9.2 Processamento de entrada/saída.........................695 21.9.3 Tratamento de interrupções................................ 698 21.9.4 Gerenciamento de cache de arquivo.................. 699 21.10 Comunicação interprocessos................................................ 699 21.10.1 Pipes.....................................................................700 21.10.2 M ailslots.............................................................. 701 21.10.3 Memória compartilhada.................................... 701 21.10.4 Chamadas remotas e locais de procedimento...................................................... 701 21.10.5 Modelo de objeto componente (C O M ).............703 21.10.6 Arrastar e soltar e documentos compostos....... 704 21.11 Redes......................................................................................... 704 21.11.1 Entrada/Saída de rede.........................................705 21.11.2 Arquitetura de driver de rede.............................. 706 21.11.3 Protocolos de rede..............................................707 21.11.4 Serviços dc re d e ................................................... 708 21.11.5 .N ET.....................................................................709 21.12 Escalabilidade.........................................................................709 21.12.1 Multiprocessamento simétrico (SMP)............. 709 21.12.2 Windows XP Em barcado..................................710 21.13 Segurança................................................................................ 711 21.13.1 Autenticação........................................................711 21.13.2 Autorização.........................................................711 21.13.3 Firewall de conexão de Internet....................... 713 21.13.4 Outras características.......................................... 713 Exercícios................................................................................................713 N otas....................................................................................................... 715 G lossário.................................................................................................725 índice....................................................................................................... 752 Não viva, m ais aospedaços. Basta se, conectar... Edw ard M organ Forster Bem-vindo ao mundo dos sistemas operacionais. Este texto é indicado basicamente para utilização em cursos de sistemas operacionais de um ou dois semestres (segundo a definição recente de currículo da ACM/IEEE) oferecidos aos estudantes pelas universidades de ciência da computação. Projetistas de sistemas operacionais e programadores de sistemas também acharão o texto útil como referência. O texto apresenta estudos de casos extensivos sobre os dois sistemas operacionais mais importantes existentes hoje — o Linux e o Windows XP —, que representam dois paradigmas diferentes de projeto de sistemas — desenvolvimento de código-fonte aberto gratuito e desenvolvimento corporativo, licenciado, respectiva­ mente. O estudo de caso do Linux segue o desenvolvimento do núcleo versão 2.6. O estudo de caso do Windows XP destaca os componentes internos da versão atual do sistema operacional para computadores pessoais mais usado nos dias de hoje. Esses estudos de caso habilitam o leitor a comparar as semelhanças e as diferenças entre as filosofias de projeto e a implementação usadas em sistemas operacionais no mundo real. Tanto o Linux quanto o Windows XP são sistemas operacio­ nais maciços, complexos, os quais contêm milhões de linhas de código-fonte. Examinaremos os principais componentes de cada um desses sistemas. Os estudos de caso apresentam questões referentes a computadores pessoais, estações de trabalho, multiprocessadores, ambientes distribuídos e embarcados, incluindo uma discussão detalhada do motivo pelo qual o Linux e outros sistemas operacionais semelhantes ao UNIX tomaram-se proe­ minentes nas filosofias de código-fonte aberto e sistemas abertos de importantes corporações. Este Prefácio apresenta a abordagem de ensino que adotamos em Sistemas operacionais, 3/E e o conteúdo fundamental e os elementos de projeto do livro. Discutimos também o suporte complementar disponível com o texto. A seção mais à frente in­ titulada “Passeio pelo livro” dá uma visão geral da rica cobertura de sistemas operacionais oferecida por este livro. Sistemas operacionais, 3/E foi revisado por uma equipe de renomados acadêmicos e profissionais do setor; seus nomes e afiliações estão listados na seção Agradecimentos. Caso, durante a leitura deste livro, você tenha alguma pergunta, favor enviar um e-mail (em inglês) para o endereço [email protected], e responderemos o mais rápido possível. Visite periodicamente nosso site, no endereço www.deitel.com, e inscreva-se para receber o newsletter DeitePBuzz Online em www.deitel.com/newsletter/subscribe.html. Usamos o site e o newsletter para manter nossos leitores a par de todas as publicações e serviços Deitei (em inglês). Projeto do livro Sistemas operacionais, 3/E, além de apresentar um projeto visual completamente novo, inspirado no trabalho de Leonardo Da Vinci, define a ocorrência de termos fundamentais em negrito de modo a destacá-los. Características de, Sistemas operacionais, Terceira, edição Sistemas operacionais, 3/E inclui extensivo conteúdo novo. Além disso, revisamos e atualizamos grande parte do material da segunda edição. O foco em tecnologias e questões correntes da computação distribuída torna este livro exclusivo em comparação com seus concorrentes. Diversas novas seções foram adicionadas, as quais abordam sistemas embarcados, de tempo real e distribuídos. Dentre as características desta edição, destacamos que ela: • Segue todos os requisitos fundamentais das exigências do curso de sistemas operacionais da proposta de currículo CC2001 da ACM/IEEE. • Discute todos os tópicos opcionais de sistemas operacionais da CC2001, exceto shell scripting. • Provê uma introdução atualizada sobre hardware que inclui tecnologias de ponta e o impacto que elas causam sobre o projeto de sistemas operacionais. • Apresenta soluções de gerenciamento de processos, threads, memória e disco que refletem as necessidades das aplicações correntes. • Suplementa a extensiva cobertura de sistemas de propósito geral com conceitos relevantes para arquiteturas de tempo real, embarcadas e superescalares. • Destaca as principais técnicas de avaliação que habilitam análises comparativas efetivas entre componentes de siste­ mas operacionais. • Inclui um tratamento mais rico de conceitos de redes. • Aperfeiçoa o tratamento da segurança, incluindo as tendên­ cias atuais de mecanismos de autenticação, protocolos de segurança, pesquisa antivírus, métodos de controle de acesso e segurança sem fio. • Aperfeiçoa a cobertura da computação distribuída, reconhe­ cendo a tremenda influência da Internet e da World Wide Web sobre a computação e os sistemas operacionais. • Provê detalhes da onipresente arquitetura Intel®. • Provê muitos diagramas, tabelas, exemplos de códigos que funcionam, exemplos de pseudocódigo e algoritmos. • Inclui um novo capítulo sobre threads. • A sintaxe do pseudocódigo é semelhante à Java para capita­ lizar os conhecimentos de C/C++/Java— praticamente todos os estudantes da ciência da computação conhecem uma ou mais dessas linguagens. xU/ S titw u u o p e ra c iô K A Ís Provê tratamentos multithread em pseudocódigo e em Java que demonstram questões em programação concorrente — habilitando instrutores a cobrir o material do modo que preferirem. O tratamento Java é novo nesta edição e é opcional. Visite java.sun.com/j2se/downloads.html para obter a mais recente versão de Java. A página de download contém um link com as instruções de instalação (em inglês). Aperfeiçoa o tratamento do gerenciamento de multiprocessadores. Provê novas seções sobre escalonamento de thread e escalonamento de tempo real. Inclui uma discussão sobre RAID. Provê um estudo de caso sobre processos UNIX. Inclui seções atualizadíssimas sobre gerenciamento de memória e estratégias de escalonamento de disco. Aborda o importante tópico de sistemas de E/S em muitos capítulos — mais notavelmente nos capítulos 2, 12, 13 e capítulos de estudo de caso (20 e 21). Provê 730 perguntas e respostas de revisão (aproximada­ mente duas por seção) para retomo imediato. Inclui pesquisa extensiva com citações listadas na seção Notas, ao final de cada capítulo. Abordagem/ didática/ Este livro é dividido em oito partes, cada uma contendo um conjunto de capítulos relacionados. As partes são: 1. Introdução ao Hardware, Software e Sistemas operacio­ nais 2. Processos e threads 3. Memória real e virtual 4. Armazenamento secundário, arquivos e bancos de dados 5. Desempenho, processadores e gerenciamento de multiprocessador 6. Computação em rede e distribuída 7. Segurança 8. Estudo de casos As características pedagógicas do livro são descritas a se­ guir. Citações Cada capítulo começa com uma citação — algumas são engraçadas, outras filosóficas e ainda outras nos oferecem per­ cepções interessantes. Muitos leitores nos disseram que gostam de relacionar as citações com o material do capítulo. Você talvez aprecie mais essas citações após ler os capítulos. Objetivos Em seguida, a seção Objetivos apresenta o conteúdo do que você terá no capítulo todo e, ao final, você poderá verificar se alcançou seus objetivos. Seções e, exercícios da revisão Cada capítulo contém pequenas seções que abordam conceitos importantes de sistemas operacionais. A maioria das seções termina com dois exercícios de revisão e suas respectivas respostas. Esses exercícios servem para você testar seus conhecimentos, obter re­ tomo imediato e avaliar o seu grau de compreensão do material. Também o ajudam a se preparar para os exercícios do final do capítulo e para testes e exames. Alguns dos exercícios de revisão não podem ser resolvidos apenas com o material apresentado nas seções correspondentes dos capítulos; são oportunidades adicionais de ensino e aprendizagem. Termos-chave, Cada termo definido no livro aparece em negrito. Além disso, no final do livro há um glossário cumulativo em ordem alfabética. Esses recursos pedagógicos são ótimos para revisão e referência. figuras O texto contém mais de 300 gráficos, diagramas, exemplos e ilustrações que apóiam os conceitos apresentados no texto. Resumo Seções detalhadas de resumo ao final dos capítulos o ajudam a revisar os conceitos mais importantes apresentados em cada capítulo. Exercícios, projetos sugeridos & simulações sugeridas Cada capítulo inclui muitos exercícios de diferentes níveis de dificuldade — desde revisão de princípios básicos de sistemas operacionais até raciocínios complexos e projetos de pesquisa (são mais de 900 exercícios). Muitos instrutores de sistemas ope­ racionais gostam de designar projetos de final de curso, portanto, incluímos, ao final de Exercícios, em alguns capítulos, seções de Projetos sugeridos e Simulações sugeridas. Notas Este livro exigiu um extraordinário esforço de pesquisa. Há citações por toda a edição (são mais de 2.300); e cada uma delas aparece como um número sobrescrito no texto, que corresponde a uma entrada na seção Notas ao final do capítulo. Muitas dessas citações são sites da Web. Edições anteriores deste texto conti­ nham somente livros básicos e citações literárias; muitas vezes os leitores tinham dificuldade de localizar esses livros e artigos para pesquisar mais. Agora você pode acessar essas citações diretamente pela Web. Além do mais é fácil usar buscadores para localizar artigos adicionais sobre assuntos de interesse. Muitos periódicos de pesquisa são acessíveis on-line — alguns são gratuitos e outros estão disponíveis por meio de inscrição pessoal ou organizacional em associações profissionais. A Web é uma verdadeira mina de ouro de pesquisas que dão impulso à sua experiência de aprendizagem. indica Oferecemos um índice para ajudá-lo a localizar termos ou conceitos importantes rapidamente. Quadros especiais A segunda edição de Sistemas operacionais incluía um capítulo inteiro sobre modelagem analítica com teoria das filas e processos de Markov. Esta edição omite esse material por reconhecer que, na maior parte, sistemas operacionais não são um campo da matemá­ tica. Ao contrário, sua base é algo que denominamos “pensamento de sistemas” — sistemas operacionais são, em grande parte, um campo de resultados empíricos. Para esclarecer essas questões, incluímos nesta edição quatro tipos de quadros que apresentam um material que desafia, diverte e enriquece o leitor. M inieítudos de, casos Além dos estudos de casos detalhados dos sistemas operacio­ nais Linux e Windows XP, há ainda 14 miniestudos de casos que focalizam outros sistemas operacionais importantes de interesse da pesquisa histórica ou comercial. Alguns desses miniestudos de casos são Mach, CTSS e Multics, Sistemas UNIX, Sistemas operacionais de tempo real, Atlas, Sistemas operacionais de computadores de grande porte da IBM, A história do sistema operacional VM, MS-DOS, Supercomputadores, Symbian OS, OpenBSD, Macintosh, Linux Modo Usuário (UML) e OS/2. Reflexões sobre, sistem as operacionais Acadêmicos podem se dar ao luxo de estudar o que há de mais interessante sobre sistemas operacionais, especialmente algoritmos inteligentes, estruturas de dados e, vez ou outra, áreas que se pres­ tam muito bem à análise matemática. Profissionais da indústria têm de construir sistemas reais que funcionem e atendam aos exigen­ tes requisitos de custo, desempenho e confiabilidade dos clientes. Ambos os tipos de pensamentos têm uma profusão de assuntos interessantes. Há, porém, consideráveis coincidências, bem como diferenças significativas entre aquilo que os acadêmicos pensam e aquilo que os profissionais da indústria pensam. Este livro pro­ cura apresentar um tratamento equilibrado dos lados acadêmico e industrial da teoria e da prática de sistemas operacionais. O que é “reflexão sobre sistemas operacionais”? Mais de qua­ renta quadros “Reflexões sobre sistemas operacionais” exploram essa questão. Na verdade, alguns aspectos de sistemas operacionais se prestam à sofisticada análise matemática. Mas a grande experi­ ência do autor (HMD) na indústria da computação — são 42 anos, os quais incluem o trabalho (em uma posição de principiante) na pesquisa e desenvolvimento de importantes sistemas operacionais na IBM e no MIT, a autoria de duas edições anteriores deste livro e o ensino de sistemas operacionais na academia e na indústria dezenas de vezes — mostrou que esses sistemas são demasiada­ mente complexos para um tratamento matemático significativo no nível universitário ou de pós-graduação. Mesmo no nível de pós-graduação avançada, exceto em áreas limitadas de interesse, os sistemas operacionais desafiam a análise matemática. Se não há uma base matemática para avaliar aspectos de sistemas operacionais, como podemos considerá-los de modo produtivo? A resposta é o que denominamos de “reflexões sobre sistemas”, e o texto certamente aborda isso muito bem. Entretanto, os quadros “Reflexões sobre sistemas operacionais” representam o nosso esforço para capturar conceitos fundamentais que prevale­ cem no projeto e na implementação de sistemas operacionais. Os quadros “Reflexões sobre sistemas operacionais” são: Inovação; Valor relativo de recursos humanos e de computador; Desempenho; Mantenha a simplicidade; Arquitetura; Caching; Hardware e software legados; Princípio do privilégio mínimo; Proteção; Heurística; Afinal, os clientes querem aplicações; Estru­ turas de dados em sistemas operacionais; Assíncrona versus sin­ cronia; Concorrência; Paralelismo; Conformidade com padrões; Escalabilidade; Ocultação de informações; Espera, deadlock e adiamento indefinido; Sobrecarga; Previsibilidade; Justiça; In­ tensidade de gerenciamento de recursos versus valor relativo do recurso; Não há limitação para a capacidade de processamento, memória, armazenamento e largura de banda; A mudança é a regra e não a exceção; Recursos espaciais efragmentação; Virtualização; Resultados empíricos e heurística baseada na localidade; Alocação tardia; Permutas espaço-tempo; Saturação e gargalos; Compactação e descompactação; Redundância; Tolerância à falha; Sistemas de missão crítica; Criptografia e decriptação; Segurança; Cópias de segurança e recuperação; A Lei de Murphy e sistemas robustos; Degradação graciosa; Replicação de dados e coerência; Projeto de sistemas éticos. Estudos d&casos Os capítulos 20 e 21 abordam com profundidade os sistemas operacionais Linux e Windows XP, respectivamente. Esses estudos completos de caso foram cuidadosamente revisados por desenvolvedores-chave dos sistemas operacionais Linux e Windows XP. Os resumos de cada um desses casos representam a tabela de conteúdo do texto. Os estudos de caso verdadeiramente reforçam os conceitos-chave do texto — o texto apresenta os princípios; os estudos de caso mostram como esses princípios são aplicados na construção dos dois sistemas operacionais mais amplamente utilizados hoje. O estudo de caso do Linux considera o desenvol­ vimento da última versão do núcleo (v.2.6) e contém 262 citações. O estudo de caso do Windows XP reflete as últimas características do sistema operacional Windows e contém 485 citações. Passeio pelo livro Esta seção dá uma visão geral das oito partes e dos 21 capítulos de Sistemas operacionais, 3/E. Parte 1 — Introdução ao hardware, software e sistemas operacionais — inclui dois capítulos que introduzem a noção de sistemas operacionais, apresentam um histórico de sistemas operacionais e lançam as fundações dos conceitos de hardware e software que o leitor usará por todo o livro. Capítulo 1 — Introdução aos sistemas operacionais — de­ fine o termo “sistema operacional” e explica a necessidade de tais sistemas. O capítulo oferece uma perspectiva histórica de siste­ mas operacionais traçando seu desenvolvimento década por década durante a segunda metade do século XX. Consideramos o sistema de processamento em lote da década de 1950. Observamos a tendên­ cia em favor do paralelismo com o advento da multiprogramação — tanto a multiprogramação em sistemas em lote quanto em sis­ temas interativos de compartilhamento de tempo. Acompanhamos o desenvolvimento de sistemas operacionais fundamentais, entre eles CTTS, Multics, CP/CMS e Unix. O capítulo considera como pensavam os projetistas de sistemas operacionais em uma época em que os recursos de computação eram muito mais caros do que os recursos humanos (hoje vale o contrário). Acompanhamos a evolução das redes de computadores na década de 1970, da Internet e do conjunto de protocolos TCP/IP, e, ainda, observamos o início da revolução da computação pessoal. A computação amadurece na década de 1980 com o lançamento do computador pessoal da IBM e do Apple Macintosh — esse último popularizando a in­ terface gráfica de usuário (GUI). Vemos o início da computação distribuída e o desenvolvimento do modelo cliente/servidor. Na década de 1990, a utilização da Internet explode literalmente com a disponibilidade da World Wide Web. A Microsoft toma-se a líder mundial entre os fabricantes de software e lança seu sistema operacional Windows NT (o ancestral do sistema operacional Windows XT de hoje — assunto do Capítulo 21). A tecnologia de objeto toma-se o paradigma de desenvolvimento predominante com linguagens como a C++ e a popularização da linguagem Java. A rápida ascensão do movimento do software de código-fonte aberto leva ao fenomenal sucesso do sistema operacional Linux XJ/V SUtWiAS OjMTílciotUlti — assunto do Capítulo 20. Discutimos como os sistemas opera­ cionais proporcionam uma plataforma para o desenvolvimento de aplicações. São considerados os sistemas embarcados com ênfase na necessidade de extraordinária confiabilidade de sistemas de missão crítica e sistemas comerciais críticos. Consideramos os componentes centrais de sistemas operacionais e os principais objetivos dos sistemas operacionais. (O livro mantém um foco sobre questões de desempenho em praticamente todos os aspectos dos sistemas operacionais.) São apresentadas arquiteturas de sis­ temas operacionais, incluindo arquitetura monolítica, arquitetura em camadas, arquitetura de micronúcleo e sistemas operacionais de rede e distribuídos. Capítulo 2 — Conceitos de hardware e software — resume os recursos de hardware e software que os sistemas operacionais gerenciam. O capítulo comenta como as tendências no projeto de hardware — mais notavelmente os fenomenais aumentos da capacidade de processamento, capacidade de memória e largura de banda de comunicação — afetaram o projeto de sistemas ope­ racionais e vice-versa. Entre os componentes de hardware estão placas principais, processadores, relógios, memória principal, dispositivos de armazenamento secundário, barramentos, acesso direto à memória (DMA), dispositivos periféricos e muito mais — todos discutidos. Apresentamos tecnologias recentes e emergen­ tes de hardware, e discutimos suporte de hardware para sistemas operacionais, incluindo modos de execução de processador, ins­ truções privilegiadas, temporizadores, relógios, autocarregamento e plug-and-play. São consideradas técnicas de aperfeiçoamento do desempenho como caching e buffering. Entre os conceitos de software examinados estão compilação, ligação, carregamento, linguagens de máquina, linguagens de montagem, interpretadores, compiladores, linguagens de alto nível, programação estruturada, programação orientada a objeto e interfaces de programação de aplicação (APIs). O capítulo também explica o que é firmware e middleware. Parte 2 — Processos e threads — inclui seis capítulos que apresentam as noções de processos, threads, transições de estado de thread, interrupções, chaveamento de contexto, assincronismo, exclusão mútua, monitores, deadlock e adiamento indefinido e escalonamento de processador de processos e threads. Capítulo 3 — Conceitos de processos — começamos dis­ cutindo as primitivas do sistema operacional definindo a noção fundamental de processo. Consideramos o ciclo de vida de um processo enquanto ele transita entre estados de processos. É discutida a representação de um processo como um bloco de controle de processo ou descritor de processo com ênfase para a importância das estruturas de dados em sistemas operacionais. O capítulo sugere a necessidade de estruturas de processos em um sistema operacional e descreve operações que podem ser execu­ tadas sobre elas, tais como suspender e retomar. Apresentamos considerações sobre multiprogramação, incluindo suspensão da execução do processo e chaveamento de contexto. O capítulo discute interrupções — uma chave para a implementação bem-su­ cedida de qualquer ambiente multiprogramado. Discute, também, o processamento de interrupções e classes de interrupção, comu­ nicações interprocessos com sinais e passagem de mensagens. Concluímos com um estudo de caso de processos UNDC. Capítulo 4 — Conceitos de threads — estende a nossa discussão de conceitos de processos a uma unidade menor de execução de programas concorrentes: o thread. O capítulo define o que são threads e explica sua relação com processos. Discutimos o ciclo de vida de um thread e como eles transitam entre seus vários estados. Consideramos vários modelos de arquiteturas de thread, incluindo threads de usuário, threads de núcleo e threads combinados de usuário e núcleo. O capítulo apresenta considera­ ções de implementação de threads, abrangendo entrega de sinal de thread e extinção de thread. Discutimos o padrão POSDC e sua especificação de threads, Pthreads. O capítulo termina com a apresentação de implementações de threads no Linux, Windows XP e Java. A apresentação da implementação Java é acompanhada de um programa completo em Java com exemplos de resultados. [Nota: o código-fonte dos programas Java do livro está disponível para download no site deste livro em WWW.prenhall.com/deitel_bl'] Capítulo 5 — Execução assíncrona concorrente — discute as questões de concorrência encontradas em sistemas multipro­ gramação. O capítulo apresenta o problema da exclusão mútua e do modo como os threads devem gerenciar o acesso a recursos compartilhados. Uma característica deste capítulo é o Estudo de caso de Java multithread: um relacionamento produtor/consumidor em Java — que utiliza um programa completo em Java e diversos resultados para ilustrar de maneira bastante compreensível o que acontece quando threads concorrentes acessam dados comparti­ lhados sem sincronização. Esse exemplo mostra claramente que tal programa concorrente às vezes funcionará muito bem e às vezes produzirá resultados errôneos. Mostramos como resolver esse problema com um programa Java multithread no Capítulo 6. Apresentamos o conceito de seção crítica no código do programa. Diversos mecanismos de software que protegem o acesso às se­ ções críticas são apresentados como soluções para o problema da exclusão mútua, entre eles o Algoritmo de Dekker, o Algoritmo de Peterson e a exclusão mútua de N-threads com o Algoritmo da Padaria de Lamport. O capítulo também discute mecanismos de hardware que facilitam a implementação de algoritmos de exclusão mútua; entre eles estão a desabilitação de interrupções, a instrução test-and-set e a instrução swap. Finalmente são apresentados semá­ foros como mecanismos de alto nível para implementar exclusão mútua e sincronização de thread; são considerados semáforos binários e semáforos contadores. Capítulo 6 — Programação concorrente — explica a no­ ção de monitores (construções de exclusão mútua de alto nível) e, então, passa a resolver problemas clássicos de programação concorrente, usando primeiramente monitores em pseudocódigo e, então, programas completos em Java com amostras de resultados. As soluções de monitores são fornecidas em uma sintaxe de pseu­ docódigo semelhante à C/C-H-/Java. Explicamos como monitores impõem a ocultação de informações e discutimos quais são as diferenças entre as variáveis de condição do monitor e as variá­ veis “convencionais”. O capítulo ilustra como um simples monitor pode ser usado para controlar acesso a um recurso que requer utilização exclusiva. Então discutimos dois problemas clássicos na programação concorrente — o buffer circular e o problema de leitores-escritores; implementamos soluções para cada um deles com monitores em pseudocódigo. Explicamos monitores Java e discutimos as diferenças entre monitores Java e os descritos pela literatura clássica. O capítulo dá continuidade ao nosso estudo de caso de multiprogramação Java, implementando uma relação produtor/consumidor e um buffer circular em Java. O estudante pode usar esse último programa como uma base para implementar uma solução para o problema dos leitores-escritores em Java. Capítulo 7 — Deadlock e adiamento indefinido — introduz duas consequências desastrosas da espera: deadlock e adiamento indefinido. A principal preocupação é que os sistemas que geren­ ciam entidades de espera devem ser cuidadosamente projetados para evitar esses problemas. São apresentados diversos exemplos de deadlock, incluindo um deadlock de tráfego, o clássico dea­ dlock da ponte de pista única, um deadlock de recurso simples em sistemas de spooling e um deadlock no encantador problema do Jantar dos Filósofos de Dijkstra. São considerados conceitos de recursos-chave, como preempção, compartilhamento, reentrância e reusabilidade serial. O capítulo define deadlock formalmente e discute prevenção, evitação, detecção e recuperação de deadlock (quase sempre dolorosa). São explicadas as quatro condições necessárias para deadlock, a saber: as condições de “exclusão mútua”, “de espera”, de “não preempção” e de “espera circu­ lar”. Examinamos os métodos de Havender para prevenção de deadlock pela negação individual de qualquer uma das últimas três condições. A evitação de deadlock habilita uma alocação de recursos mais flexível do que a prevenção de deadlock. O capítulo explica a evitação de deadlock com o Algoritmo do Banqueiro de Dijkstra, mostrando exemplos de um estado seguro, de um estado inseguro e de uma transição de estado seguro para estado inseguro. São discutidos os pontos fracos do Algoritmo do Banqueiro. Explicamos, ainda, detecção de deadlock com a técnica de redução de grafos de alocação de recursos. O capí­ tulo termina com uma discussão de estratégias de deadlock nos sistemas correntes e em sistemas futuros. Capítulo 8 — Escalonamento de processador — discute conceitos e algoritmos relacionados à alocação de tempo de pro­ cessador a processos e threads. São considerados níveis, objetivos e critérios de escalonamento. Além disso, são comparadas aborda­ gens de escalonamento preemptivo e não preemptivo. Explicamos como definir cuidadosamente prioridades e quanta (alocações de tempo de processador de tamanho finito) em algoritmos de escalo­ namento. São considerados diversos algoritmos de escalonamento clássicos e correntes, incluindo primeiro a entrar primeiro a sair (F1FO), alternância circular (RR), processo mais curto primeiro (SPF), próxima taxa de resposta mais alta (HRRN), menor tempo de execução restante (SRT), filas múltiplas de retomo e escalona­ mento por fração justa. Cada algoritmo é avaliado usando unidades de medidas, como rendimento, tempo médio de resposta e a variância de tempos de resposta. Discutimos o escalonamento de threads Java, escalonamento de tempo real não crítico, escalonamento de tempo real crítico e escalonamento por prazo. Parte 3 — Memória real e virtual — composta de três capí­ tulos que discutem organização de memória e gerenciamento de memória em sistemas de memória real e virtual. Capítulo 9 — Organização e gerenciamento da memória real — apresenta uma discussão histórica do modo como siste­ mas operacionais de memória real organizavam e gerenciavam recursos de memória física. Os esquemas passaram de simples a complexos e, por fim, passaram a buscar a utilização ótima dos recursos relativamente preciosos da memória principal. Revisa­ mos a hierarquia de memória que consiste de cache(s), memória primária e armazenamento secundário. Então discutimos três tipos de estratégias de gerenciamento de memória, a saber: busca, posicionamento e substituição. Apresentamos esquemas de alocação de memória contígua e não contígua. É considerada alocação de memória contígua monousuário com a discussão sobre sobreposições (overlays), proteção e processamento em lote de fluxo único. Traçamos a evolução das organizações de memória na multiprogramação — desde multiprogramação por partição fixa até multiprogramação por partição variável —, consideran­ do questões como fragmentação interna e externa de memória e apresentando compactação e coalescência de memória como um meio de reduzir fragmentação. O capítulo discute as estratégias de posicionamento primeiro que couber, o que melhor couber, o que pior couber e termina com uma discussão de multiprogramação com troca de memória. Capítulo 10— Organização da memória virtual— descreve conceitos fundamentais de memória virtual e as capacidades de hardware que suportam memória virtual. O capítulo apresenta motivos da necessidade de memória virtual e descreve imple­ mentações típicas. São explicadas as principais abordagens da organização da memória virtual — paginação e segmentação —, e seus méritos relativos são analisados. Discutimos sistemas de paginação focalizando tradução de endereços de paginação por mapeamento direto, tradução de endereço de paginação por mapeamento associativo, tradução de endereço de paginação por mapeamento direto/associativo, tabelas de páginas multiníveis, tabelas de páginas invertidas e compartilhamento em sistemas de paginação. O capítulo investiga sistemas de segmentação foca­ lizando tradução de endereço de segmentação por mapeamento direto, compartilhamento em um sistema de segmentação, proteção e controle de acesso em sistemas de segmentação. Examinamos, também, sistemas híbridos de paginação/segmentação consideran­ do tradução dinâmica de endereços, compartilhamento e proteção nesses sistemas. O capítulo termina examinando a popular arqui­ tetura de implementação de memória virtual IA-32 Intel. Capítulo 11 — Gerenciamento de memória virtual — dá continuidade à discussão da memória virtual analisando como sistemas operacionais tentam otimizar o desempenho da memória virtual. Porque os sistemas de paginação passaram a predominar, focalizamos em detalhes o gerenciamento de páginas, mais es­ pecificamente estratégias de substituição de páginas. O capítulo considera um dos resultados empíricos mais importantes na área de sistemas operacionais, ou seja, o fenômeno da localidade, e consi­ deramos os resultados a partir de perspectivas temporais e também espaciais. Discutimos quando as páginas devem ser trazidas para a memória examinando tanto a paginação por demanda quanto a paginação antecipada. Quando a memória disponível fica escas­ sa, páginas que chegam devem substituir páginas que já estão na memória — a estratégia de substituição de páginas de um sistema operacional pode causar um impacto enorme sobre o desempenho. São examinadas muitas estratégias de substituição de páginas, incluindo aleatória, primeira a chegar, primeira a sair (FIFO e Anomalia de Belady), menos recentemente usada (MRU), menos freqüentemente usada (MFU), não usada recentemente (NUR), segunda chance e relógio, página longínqua e freqüência de falta de página (FFP). O modelo clássico de conjunto de trabalho de Denning para o comportamento de programa é considerado, bem como o modo como várias estratégias de substituição de páginas tentam cumprir seus objetivos. O capítulo discute a possibilidade de liberação voluntária de páginas. Examinamos cuidadosamente os argumentos em favor de páginas grandes e páginas pequenas e como programas se comportam sob paginação. O capítulo discute substituição de páginas no Linux e conclui com uma discussão entre as estratégias de substituição de páginas global e local. Parte 4 — Armazenamento secundário, arquivos e ban­ cos de dados — inclui dois capítulos que apresentam técnicas que sistemas operacionais empregam para gerenciar dados em armazenamento secundário. São discutidos a otimização do de­ sempenho do disco rígido e os sistemas de arquivos e de banco de dados. Discussões referentes a sistemas de E/S são distribuídas por todo o livro, mais especificamente nos capítulos 2, 12 e 13 e, nos casos do Linux e do Windows XP, nos capítulos 20 e 21, respectivamente. Capítulo 12 — Otimização do desempenho do disco — focaliza as características do armazenamento em disco de cabeçote móvel e como o sistema operacional pode otimizar o seu desempenho. O capítulo discute a evolução dos dispositivos xm S U tw u is o jte ra c io fu iti de armazenamento secundário e examina as características do armazenamento em disco de cabeçote móvel. Transcorrido meio século de explosivo desenvolvimento técnico, os dispositivos de armazenamento de cabeçote móvel continuam firmes. Definimos por que o escalonamento de disco é necessário e demonstramos por que precisamos dele para conseguir alto desempenho de dis­ positivos de disco de cabeçote móvel. Apresentamos a evolução das estratégias de escalonamento de disco, incluindo estratégias de otimização de busca, entre as quais primeira a chegar, primeira a ser atendida (FCFS), tempo de busca mais curto primeiro (SSTF), SCAN, C-SCAN, FSCAN, SCAN de fases, LOOK, C-LOOK e VSCAN (apresentada nos exercícios) e estratégias de otimização rotacional, incluindo SLTF, SPTF e SATF. São discutidas outras técnicas de desempenho de sistemas de discos, tais como caching, buffering, desfragmentação, compressão de dados e bloqueio. Uma das adições mais importantes desta terceira edição é o tratamento extensivo de sistemas RAID neste capítulo. RAID (Arranjo re­ dundante de discos independentes) é um conjunto de tecnologias que habilitam sistemas de discos a conseguir maior desempenho e tolerância a falhas. O capítulo apresenta vários “níveis” funda­ mentais de RAID, entre eles nível 0 (striping), nível 1 (espelhamento), nível 2 (paridade Hamming ECC no nível do bit), nível 3 (paridade XOR ECC no nível do bit), nível 4 (paridade XOR ECC no nível do bloco). Capítulo 13 — Sistemas de arquivos e de bancos de dados — discute como sistemas operacionais organizam e gerenciam coletâneas de dados denominados arquivos e bancos de dados. Explicamos conceitos fundamentais, incluindo hierarquia de dados, arquivos, sistemas de arquivos, diretórios, ligações, metadados e montagem. O capítulo apresenta várias organizações de arquivos, tais como seqüencial, direta, seqüencial indexada e particionada. São examinadas técnicas de alocação de arquivos, entre elas: alo­ cação contígua de arquivos, alocação de arquivos não contígua por lista encadeada, alocação de arquivos tabular não contígua e alocação de arquivos não contígua indexada. Explicamos controle de acesso a arquivos por classes de usuários e matrizes de controle de acesso. São discutidas técnicas de acesso a dados no contexto dos métodos básicos de acesso, métodos de acesso de fila, buffer antecipatório e arquivos mapeados em memória. Explicamos, ainda, técnicas para garantir a integridade dos dados, entre elas: proteção, cópia de segurança, recuperação, registro, transações atômicas, reversão, comprometimento, pontos de verificação, sombreamento de página e utilização de sistemas de arquivos log-estruturados. O capítulo também apresenta sistemas de ban­ cos de dados e analisa suas vantagens, acesso a dados, modelo de banco de dados relacionai e serviços de sistema operacional que suportam sistemas de bancos de dados. Parte 5 — Desempenho, processadores e gerenciamento de multiprocessador — contém dois capítulos que discutem monitoração de desempenho, técnicas de medição e avaliação e focaliza o extraordinário desempenho que pode ser conseguido com sistemas que empregam vários processadores. Capítulo 14 — Desempenho e projeto de processador — focaliza um dos mais proeminentes objetivos dos projetistas de sistemas operacionais — o desempenho do sistema — e dis­ cute o importante papel de tipos específicos de processador no cumprimento desses objetivos. O capítulo faz um levantamento de medidas de desempenho considerando questões como medi­ ções absolutas de desempenho, facilidade de utilização, tempo de retomo, tempo de resposta, tempo de reação do sistema, variância dos tempos de resposta, rendimento, carga de trabalho, capacidade e utilização. Discutimos as técnicas de avaliação de desempenho, entre elas: rastreamento e traçado de perfil, cronometragens e microparâmetros de desempenho, avaliação específica de aplicação, modelos analíticos, indicadores de desempenho, programas sinté­ ticos, simulação e monitoração de desempenho. São considerados gargalos e saturação. Demonstramos como sistemas se ajustam dinamicamente a retomo positivo e negativo. O desempenho de um sistema depende intensamente do desempenho do seu processador que, por sua vez, é intensamente influenciado pela arquitetura do seu conjunto de instruções. O capítulo examina arquiteturas fundamentais, incluindo computação com conjunto de instruções complexas (CISC), computação com conjunto reduzido de instruções (RISC) e vários tipos de processadores pós-RISC. O capítulo termina com uma discussão da computação com instruções explicitamente paralelas (EPIC). Capítulo 15 — Gerenciamento de multiprocessador — faz uma apresentação detalhada dos aspectos de hardware e software do multiprocessamento. Um modo de construir sistemas de com­ putação de capacidades cada vez maiores é empregar vários pro­ cessadores e possivelmente um número maciço deles. A discussão começa com um miniestudo de caso sobre supercomputadores; no site do livro há também uma biografia sobre Seymour Cray (no site do livro), o pai da supercomputação. Investigamos a arquitetura de multiprocessador, considerando questões como: a classificação de arquiteturas seqüenciais e paralelas, esquemas de interconexão de processadores e sistemas fracamente acoplados versus sistemas fortemente acoplados. Examinamos as organi­ zações de sistemas operacionais, entre as quais: organizações mestre/escravo, de núcleos separados e simétrica. Explicamos arquiteturas de acesso à memória, incluindo acesso uniforme à memória (UMA), acesso não uniforme à memória (NUMA), arquitetura de memória somente de cache (COMA) e sem acesso à memória remota (NORMA). O capítulo discute compartilha­ mento de memória em multiprocessadores considerando ques­ tões de coerência de cache, replicação e migração de página e memória virtual compartilhada. Continuamos a discussão sobre escalonamento de processador, iniciada no Capítulo 8, apresen­ tando escalonamento cego ao job e escalonamento ciente de job. Consideramos a migração de processos e, além disso, examina­ mos questões de fluxo de migração de processos e estratégias de migração de processos. Discutimos balanceamento de carga de multiprocessador, analisando estratégias de balanceamento de cargas estático e dinâmico. O capítulo explica, ainda, como impor exclusão mútua em multiprocessadores com travas giratórias, travas dormir/acordar e travas de leitura/escrita. Parte 6 — Computação em rede e distribuída Capítulo 16 — Introdução às redes — introduz computação em rede lançando a fundação para os dois capítulos seguintes, que tratam da computação distribuída. O capítulo discute topologias de redes, incluindo barramentos, anéis, malhas, malhas totalmente conectadas, estrelas e árvores; além disso, explicamos os desafios singulares apresentados pelas redes sem fio. Consideramos redes locais (LANs) e redes de longa distância (WANs) e apresentamos um importante tratamento da pilha de protocolos TCP/IP. São exa­ minados protocolos de camadas de aplicação, entre eles: o Protocolo de Transferência de Hipertexto (HTTP) e o Protocolo de Trans­ ferência de Arquivos (FTP). Explicamos protocolos de camada de transporte, incluindo o Protocolo de Controle de Transmissão (TCP) e o Protocolo de Datagrama do Usuário (UDP). Na camada de rede, o capítulo explora o Protocolo da Internet (IP) e sua versão mais recente — o Protocolo da Internet versão 6 (IPv6). O capítulo discute protocolos de camada de enlace, entre eles: Ethernet, Token Ring, Interface de Dados Distribuídos por Fibra (FDDI) e IEEE 802.11 (sem fio). O capítulo termina com uma discussão do modelo cliente/servidor e de sistemas de «-camadas. Capítulo 17 - Introdução a sistemas distribuídos — apre­ senta sistemas operacionais distribuídos e discute os atributos de sistemas distribuídos, incluindo desempenho, escalabilidade, conectividade, segurança, confiabilidade, tolerância a falhas e transparência. Analisamos as semelhanças e as diferenças entre sistemas operacionais em rede e sistemas operacionais distribuídos. São discutidos a comunicação em sistemas distribuídos e o papel crucial desempenhado pelas tecnologias de “middleware”, tais como: chamada de procedimento remoto (RPC), invocação de método remoto (RMI), CORBA (Common Object Request Broker Architecture) e DCOM (Modelo de Objeto Componente Distri­ buído) da Microsoft. O capítulo considera migração de processo, sincronização e exclusão mútua em sistemas distribuídos, exami­ nando exclusão mútua sem memória compartilhada e o algoritmo de exclusão mútua de Agrawala e Ricart. Discutimos deadlock em sistemas distribuídos focalizando prevenção e detecção de deadlock. O capítulo termina com estudos de casos dos sistemas operacionais distribuídos Sprite e Amoeba. Capítulo 18 — Sistemas distribuídos e serviços Web — dá continuidade ao estudo de sistemas distribuídos, focali­ zando sistemas de arquivos distribuídos, clustering, computação peer-to-peer, computação em grade, computação distribuída em Java e serviços Web. O capítulo começa considerando algumas características, tais como: transparência, escalabilidade, segu­ rança, tolerância a falhas e consistência. Apresentamos, também, estudos de casos sobre sistemas de arquivos distribuídos impor­ tantes, como o Sistema de Arquivos de Rede (NFS), o Sistema de Arquivos Andrew (AFS), o Sistema de Arquivos Coda e o Sistema de Arquivos Sprite. Discutimos clustering, considerando clusters de alto desempenho, clusters de alta disponibilidade e clusters de balanceamento de carga; investigamos vários exemplos de clusters, tais como: clusters Beowulf baseados no Linux e clusters baseados no Windows. Exploramos a computação distribuída peer-to-peer (P2P), considerando a relação entre aplicações P2P e cliente/servidor, aplicações P2P centralizadas versus descen­ tralizadas, descoberta e busca de par. Examinamos o Project JXTA da Sun Microsystems e consideramos como o JXTA cria uma estrutura para construir aplicações P2P. O capítulo consi­ dera computação em grade e como ela possibilita soluções de problemas que exigem uma quantidade verdadeiramente maciça de computação, utilizando capacidade de processamento ociosa disponível em computadores pessoais e em computadores de empresas no mundo inteiro. Discutimos tecnologias de computa­ ção distribuída Java, incluindo Java servlets e Java Server Pages (JPS), Jini, JavaSpaces e Java Management Extension (JMX). O capítulo termina fazendo um levantamento da excitante nova tecnologia de serviços Web e explorando duas importantes plataformas de serviços Web — .NET Platform da Microsoft e plataforma SunONE da Sun Microsystems. Parte 7 - Segurança — com posta de um capítulo. Capítulo 19 - Segurança— Apresenta uma introdução geral às técnicas de segurança de computadores e redes que os sistemas operacionais podem usar para prover ambientes de computação seguros. O capítulo descreve criptografia de chave secreta e de cha­ ve pública, além dos populares esquemas de chave pública RSA e PGP (Pretty Good Privacy). Consideramos a autenticação: proteção por senha, salpicamento de senha, biometria, cartões inteligentes, Kerberos e assinatura única. Discutimos controle de acesso, ex­ plorando questões de direitos de acesso, domínios de proteção, modelos de controle de acesso, políticas de controle de acesso e mecanismos de controle de acesso, como matrizes de controle de acesso, listas de controle de acesso e listas de capacidades. O ca­ pítulo apresenta, ainda, a grande variedade de ataques à segurança que já foi tentada, incluindo criptoanálise, vírus, vermes, ataques de recusa de serviço (DoS), exploração de software e invasão de sistema. Fazemos um levantamento da prevenção de ataques e de soluções de segurança, como firewalls e sistemas de detecção de intrusos (IDSs), software antivírus, correções de segurança e sistemas de arquivos seguros. Discutimos o sistema de classifi­ cação Orange Book Security do Governo Federal dos Estados Unidos e apresentamos um miniestudo de caso sobre o OpenBSD, discutivelmente o sistema operacional mais seguro disponível. O capítulo explora comunicação segura e considera os requisitos para uma transação bem-sucedida e segura — privacidade, integridade, autenticação, autorização e não-rejeição. Protocolos de acordo de chave — o processo pelo qual duas partes trocam chaves secretas entre si por um meio inseguro — são discutidos. Explicamos as­ sinaturas digitais — uma tecnologia que é imensamente crucial para o futuro do comércio eletrônico — e sua implementação. O capítulo trata detalhadamente a infra-estrutura de chaves públicas, incluindo certificados digitais e autoridades certificadoras. São considerados vários protocolos de comunicação segura, como Secure Sockets Layer (SSL), Virtual Private Networks (VPVs), IP Security (IPsec) e segurança sem fio. Discutimos a intrigante tecnologia da esteganografia — a prática de ocultar informação dentro de outra informação. A esteganografia pode ocultar mensa­ gens secretas em mensagens transmitidas publicamente; também pode proteger direitos de propriedade intelectual com marcasd’água digitais, por exemplo. O capítulo estuda as semelhanças e as diferenças entre soluções de segurança proprietárias e de código-fonte aberto e termina com um estudo de caso sobre a segurança de sistemas UNIX. Parte 8 — Estudos de casos de sistemas operacionais — composta de dois capítulos que apresentam estudos de casos detalhados do núcleo Linux 2.6 e do sistema operacional Windo­ ws XP. Os estudos de caso seguem a estrutura do livro, o que é conveniente para o estudante compreender os tópicos discutidos anteriormente no livro. Capítulo 20 — Estudo de caso: Linux — apresenta um estudo detalhado do Linux 2.6. Esse extenso estudo de caso foi escrito e atualizado durante o desenvolvimento da liberação dessa versão (seguindo o desenvolvimento do núcleo versão 2.5 e com a revisão cuidadosa do material pelos principais desenvolvedores do núcleo Linux). O capítulo discute a história, a comunidade e as distribuições de software que criaram o sistema operacional de código-fonte aberto mais popular do mundo. O capítulo examina os componentes do núcleo do sistema operacional Linux, dando atenção particular à sua implementação no contexto dos conceitos estudados em capítulos anteriores. São analisados e explicados a arquitetura do núcleo, gerenciamento de processo (processos, threads, escalonamento), organização e gerenciamento de memória, sistemas de arquivo (sistema de arquivo virtual, caches de sistema de arquivo virtual, ext2fs e proc fs), gerenciamento de E/S (drivers de dispositivos, E/S de dispositivo de caractere, E/S de dispositivo de bloco, E/S de dispositivo de rede, modelo de dispositivo uni­ ficado, interrupções), sincronização (travas giratórias, travas de leitura/escrita, seqlocks e semáforos de núcleo), BPC (sinais, pipes, soquetes, filas de mensagens, memória compartilhada e semáforos do System V), redes (processamento de pacotes, estrutura netfilter e ganchos), escalabilidade (multiprocessamento simétrico, acesso não uniforme à memória, outros aspectos da escalabilidade, Linux embarcado) e segurança. XX S U tw u is o jte ra c io fu iti Capítulo 21 — Estudo de Caso: Windows XP — comple­ menta o estudo de caso do Linux examinando os componentes internos do mais popular sistema operacional comercial — o Windows XP. Esse estudo de caso examina os componentes centrais do sistema operacional Windows XP e como eles inte­ ragem para prover serviços aos usuários. Discutimos a história dos sistemas operacionais Windows, incluindo notas biográficas sobre Bill Gates e David Cutler — que estão no site do livro. O capítulo apresenta as metas de projeto do Windows XP e faz uma revisão da arquitetura do sistema, considerando, entre outros tó­ picos, Camada de Abstração de Hardware (HAL), o micronúcleo, o executivo, os subsistemas ambientais, bibliotecas de ligações dinâmicas (DDLs) e serviços do sistema. Discutimos mecanismos de gerenciamento de sistema, incluindo registro, gerenciador de objeto, níveis de requisição de interrupções (IRQLs), chamadas assíncronas de procedimento (APCs), chamadas postergadas de procedimento (DPCs) e threads de sistema. Examinamos orga­ nização de processo e thread, considerando blocos de controle, armazenamento local de threads (TLS), criação e extinção de processos, jobs, filtros, fibras e reservatórios de threads. Explica­ mos escalonamento de threads e, ainda, consideramos estados de threads, o algoritmo de escalonamento de threads, a determinação de prioridades de threads e escalonamento de multiprocessador. Investigamos sincronização de threads, examinando objetos despachadores, objetos eventos, objetos mutex, objetos semá­ foros, objetos temporizadores, travas de modo núcleo e outras ferramentas de sincronização. São explicados gerenciamento e os conceitos de organização de memória, alocação de memória e substituição de páginas. Exploramos gerenciamento de sistemas de arquivos discutindo drivers de sistemas de arquivos e tópicos NTFS, incluindo Tabela Mestra de Arquivos (MFT), fluxos de dados, compressão de arquivos, criptografia de arquivos, arquivos esparsos, pontos de reanálise e volumes montados. Estudamos gerenciamento de entrada/saída explicando drivers de disposi­ tivos, Plug-and-Play, gerenciamento de energia, o Modelo de Driver do Windows (WDM), processamento de entrada/saída, pacotes de requisição de E/S, técnicas de transferência de dados, controle de interrupções e gerenciamento de cache de arquivo. Consideramos mecanismos de comunicação interprocessos, incluindo pipes (anônimos e nomeados), mailslots, memória compartilhada e chamadas de procedimentos locais e remotas. O Modelo de Objeto Componente (COM) da Microsoft é revisto. Explicamos a operação arrastar e soltar e documentos compos­ tos. Discutimos capacidades de redes, incluindo entrada/saída de rede, arquitetura de driver de rede, protocolos de rede (IPX, SPX, NetBEUI, NetBIOS sobre TCP/IP, WinHTTP, WinINet e Winsock 2). São discutidos tópicos de serviços de rede, tais como: Active Directory, Lightweight Directory Access Protocol (LDAP) e Remote Access Service (RAS). Damos uma visão geral da nova tecnologia .NET da Microsoft que está substituindo DCOM. Examinamos escalabilidade considerando multiprocessamento simétrico (SMP) e Windows XP Embedded. O capítulo termina com uma discussão de tópicos de segurança, incluindo autenti­ cação, autorização, Internet Connection Firewall (ICF) e outras características de segurança. Ufa! Bom, com isso terminamos o nosso Passeio pelo livro. Há muita coisa aqui para estudantes e profissionais de sistemas operacionais. CoMjMUtiôii/ Web site O livro também possui um site em www.prenhall.com/deitel_br, contendo código-fonte dos programas em Java e manual de solução (em inglês), transparências em PowerPoint, biografias, curiosida­ des, leitura recomendada e recursos da Web. Agradecincentos Um dos grandes prazeres de escrever um livro didático é agradecer o esforço de muitas pessoas cujos nomes podem não aparecer na capa, mas cujo trabalho árduo, cooperação, amizade e compreensão foram cruciais para a produção do livro. Muitos de nossos colegas na Deitei & Associates, Inc. devotaram longas horas a este livro e a seu material complementar: Jeff Listfield, Su Zhang, Abbey Deitei, Barbara Deitei e Christi Kelsey. Gostaríamos de incluir uma nota especial de agradecimento a Ben Wiedermann, por organizar o trabalho de revisão do material na segunda edição deste livro. Ele revisou e atualizou grande parte da redação c dos diagramas existentes. Também organizou e liderou uma equipe de estagiários da Deitei que pesquisaram os mais recentes desenvolvimentos de sistemas operacionais para inclusão nesta nova edição. Atualmente Ben está estudando para obter o título de doutor em Ciência da Computação na University of Texas, Austin. Gostaríamos também de agradecer aos participantes da Deitei & Associates, Inc., College Intemship Program (Programa de Esta­ giários Universitários), que trabalharam no conteúdo deste livro e de seu pacote complementar: Jonathan Goldstein (Comell Univer­ sity), Lucas Ballard (Johns Hopkins University), Tim Christensen (Boston College), John Paul Casiello (Northeastem University), Mira Meycrovich (estudante de doutorado na Brown University), Andrew Yang (Camegie Mellon University), Kathryn Ruigh (Bos­ ton College), Chris Gould (University of Massachusetts at Lowel), Marc Manara (Harvard University), Jim 0 ’Leary (Rennsselaer Polytechnic Institute), Gene Pang (Comell University) e Rand Xu (Harvard University). Gostaríamos de agradecer a Howard Berkowitz (anteriormente da Coporation for Open Systems International) pela co-autoria do Capítulo 16, Computação distribuída, na segunda edição deste texto. Seu trabalho foi a base do nosso tratamento ampliado, aper­ feiçoado e atualizado da computação em rede e distribuída dos capítulos 16 a 18 de Sistemas operacionais, Terceira edição. Foi uma felicidade trabalhar neste projeto com a talentosa e dedicada equipe de profissionais de edição da Prentice Hall. Agra­ decemos especialmente o extraordinário esforço da nossa editora de Ciência da Computação, Kate Hargett, e de sua chefe e nossa mentora nesta publicação — Mareia Horton, diretora editorial da Divisão de Engenharia e Ciência da Computação da Prentice Hall. Vince 0 ’Brian, Tom Manshreck, John Lovell e Chirag Thakkar realizaram um trabalho maravilhoso no gerenciamento da pro­ dução do livro. Sarah Parker gerenciou a publicação do pacote complementar do livro. Gostaríamos de agradecer à equipe de projeto que criou um visual e uma atmosfera completamente novas para Sistemas ope­ racionais, 3/E — Carolc Anson, Paul Belfanti, Geoffrey Cassar e John Root. Gostaríamos também de agradecer à talentosa equipe de criação da Artworks, citando Kathryn Anderson, Jay McElroy, Ronda Whitson, Patrícia Bums, Matt Haas, Xiaohong Zhu, Dan Missildine, Chad Baker, Sean Hogan, Audrey Simonetti, Mark Landis, Royce Copenheaver, Stacy Smith, Scott Wieber, Pam Taylor, Anna Whalen, Cathy, Shelly, Ken Mooney, Tim Nguyen, Carl Smith, Jo Thompson, Helenita Zeigler e Russ Crenshaw. Os agradecimentos mais importantes são para os milhares de autores citados nas seções de Leitura recomendada, no site deste livro, e Notas que aparecem no fim de cada capítulo; seus escri­ tos, artigos e livros de pesquisa proporcionaram a diversidade de material interessante, que toma a área de sistemas operacionais tão fascinante. Gostaríamos de agradecer os esforços dos revisores de nossa terceira edição e agradecer especialmente a Carole Snyder e Jeniffer Capello, da Prentice Hall, que gerenciaram esse extraordiná­ rio trabalho de revisão. Mantendo o cronograma, esses revisores esmiuçaram o texto dando inúmeras sugestões para aperfeiçoar a exatidão e a completude da apresentação. É um privilégio poder contar com profissionais tão talentosos e atarefados. Revisores da, edição original e*tc inglês TigranAivazian, Veritas Software, Ltd. Jens Axboe, SUSE Labs Dibyendu Baksi, Scientific Technologies Corporation Columbus Brown, IBM Fabian Bustamante, Northwestern University Brian Catlin, Azius Developer Training Stuart Cedrone, Hewlett-Packard Randy Chow, University of Florida Alan Cox, Red Hat UK Matthew Dobson, Independent Consultant Ulrich Drepper, Red Hat, Inc. Alessio Gaspar, University of South Florida, Lakeland Campus Allison Gehrke, Colorado Technical University Michael Green, Central Texas College Rob Green, Columbia Data Products, Inc. James Huddleston, Independent Consultant Scott Kaplan, Amherst College Salahuddin Khan, Microsoft Robert Love, MontaVista Software, Inc. Barry Margolin, Levei 3 Communications Cliff Mather, Hewlett-Packard Jeanna Matthews, Comell University/Clarkson University Manish Mehta, Syntel, índia, Ltd. Dejan Milojicic, Hewlett-Packard Euripides Montagne, University of Central Florida Andrew Morton, Diego, Inc. Gary Newell, Northern Kentucky University Bill OTarrell, IBM Mike Panetta, Robotic Sciences, IncVNetplanner Systems, Inc. Rohan Phillips, Microsoft Atui Prakash, University of Michigan Bina Ramamurthy, SUNY Buffalo Eric Raymond, Thyrsus Enterprises Jeffrey Richter, Wintellect Sven Schreiber, Platon Data Technology WennieWei Shu, University of New México David Solomon, David Solomon Expert Seminars Brandon Taylor, Sun Microsystems Bob Toxen, Fly-By-Day Consulting, Inc. Joshua Uziel, Sun Microsystems Carlos Valcarcel, EinTech, Inc. Melinda Ward, Hewlett-Packard GerardWeatherby, Charles Consulting, LLC. /Rensselaer at Hartford Xiang Xu, RSA Security, Inc. Sobre* os autores Dr. Harvey M. Deitei, chairman e diretor de estratégia da Deitei & Associates, Inc., tem 42 anos de experiência na área de computação, incluindo extensiva experiência industrial e acadê­ mica. Dr. Deitei estudou sistemas operacionais no Massachusetts Institute of Technology, onde recebeu seus títulos de Bacharel em Ciências e Mestre em Ciências. Recebeu o título de Doutor da Boston University. Enquanto se preparava para sua pós-graduação e para o título de Mestre no MIT, trabalhou nos projetos pioneiros de sistemas operacionais de memória virtual da IBM (OS/360 e TSS/360) e do MIT (Multics), os quais desenvolveram técnicas que agora são amplamente implementadas em sistemas como: UNIX, Linux e Windows XP. Foi professor de sistemas operacionais du­ rante 20 anos, na academia e na indústria. Cumpriu mandato como chairman do Departamento de Ciência da Computação, no Boston College, antes de fundar a Deitei & Associates, Inc., com seu filho Paul J. Deitei. Ele e Paul são co-autores de dezenas de livros e pacotes multimídia e continuam escrevendo muitos outros mais. Com traduções publicadas em japonês, alemão, russo, espanhol, chinês tradicional, chinês simplificado, coreano, francês, polo­ nês, italiano, português, grego, urdu e turco, os textos dos Deiteis conquistaram renome internacional. Dr. Deitei tem participado de seminários profissionais em grandes corporações, organizações governamentais e militares. Paul J. Deitei, CEO e diretor técnico da Deitei & Associates, Inc., formou-se na Sloan School of Management do Massachusetts Institute of Technology, onde estudou tecnologia da informação e sistemas operacionais. Por meio da Deitei & Associates, Inc., ele tem ministrado centenas de cursos para empresas da Fortune 500, para o meio acadêmico e para clientes do governo e militares e muitas outras organizações. Dá conferências no Boston Chapter da Association for Computing Machinery. Ele e seu pai, Dr. Har­ vey M. Deitei, são os autores dos livros didáticos de Ciência da Computação campeões de vendas no mundo inteiro. David R. ChofFnes formou-se no Amherst College, onde estudou Física e Francês enquanto seguia tópicos avançados em Ciência da Computação. Entre seus interesses de pesquisa estão as áreas de sistemas operacionais, arquitetura de computadores, biologia computacional e computação molecular. David contribui para outras publicações da Deitei, entre elas Simply Java™ Programming e Simply Visual Basic® .NET. dutrocLiçCIO CLO kardwcírc; software esistew ai operacionais Inteligência,... í a, capaMÁaÁe, de, criar objetos artificia is, M pedcdnceM te,ferramentas para, construirferram entas. H enri Bergson O s próximos capítulos definem o termo sistema operacional, apresentam a história desses sistemas e lançam os fundamentos dos conceitos de hardware e software. À medida que você estudar essa história, notará uma ênfase constante na melhoria do desempenho e no aumento da intensidade do gerenciamento de recursos na obtenção dessa melhoria. Você verá a capacidade do hardware crescer extraordinariamente enquanto os custos declinam com igual intensidade. Você verá o surgimento de dois sistemas operacionais preponderantes, o Linux e o Windows XP, um construído com a abordagem de fonte aberto (Linux), outro com a abordagem de fonte proprietário (Windows XP). Aqui, você estudará as principais arquiteturas de sistemas operacionais; o hardware que esses sistemas gerenciam para os usuários; e o hardware que suporta funções de sistemas operacionais. Além disso, você tomará contato com suas primeiras técnicas de aperfeiçoamento de desempenho - um processo que continuará por todo o livro. rrega/consigo o espírito como W erner Karl Heisenberg C aü M o 1 ÜKtrücÍKÇ;ao aos sistemas dj>tracroKdis Não tswtis ntaU m aneira^fra^ntentada. Conecte'-& ... Edward M organ Forster E fu u tn á a éfcucer o trabalho corretam ertb. EfuÁciay éfajcer o trabalho que, dev& serfeito . Zig Ziglar Nadaopermaneces, senão a, m udança,. Heráclito Abre-te^, sésamo! A História de Ali Babá Este capítulo apresenta: • O que é um sistema operacional. • Um breve histórico sobre os sistemas operacionais. • Um breve histórico sobre a Internet e a World Wide Web. • Os componentes centrais do sistema operacional. • As metas dos sistemas operacionais. • Arquiteturas do sistema operacional. 4 S U tw u is o jte ra à o fu iti 1.1 Introdução Bem -vindo ao m undo dos sistemas operacionais. D urante as últim as décadas a com putação se desenvolveu a um a velocidade sem precedentes. A capacidade do com putador continua a aum entar a taxas fenom enais, enquanto o custo declina extraordinariam ente. Hoje, os usuários de com putadores têm estações de trabalho de m esa que executam bilhões de instruções por segundo (BIPS), e supercom putadores que executam m ais de um trilhão de instruções por segundo já foram construídos,1*2 núm eros que há alguns anos eram inconcebíveis. Processadores estão ficando tão baratos e poderosos que os com putadores podem ser empregados em quase todas as situações de nossas vidas. Com com putadores pessoais, podem os editar documentos, jogar, ouvir música, assistir a vídeos e gerenciar nossas finanças. Equipamentos portáteis, incluindo laptops, assistentes pessoais digitais (PDAs), telefones celulares e aparelhos MP3, em todos eles os com putadores são os com ponentes principais. Arquiteturas de rede com e sem fio estão aum entando nossa interconectividade, permitindo que usuários se com uniquem instantaneam ente a distâncias imensas. A Internet e a World W ide Web revolucionaram os negócios criando dem anda para redes de com putadores de grande porte e capacidade que processam números enormes de transações por segundo. As redes de com putadores se tom aram tão poderosas que são usadas para executar pesquisas com plexas e projetos de simulação, como modelar o clim a da Terra, em ular a inteligência humana e construir animações em 3D que parecem reais. Essa capacidade de com putação poderosa e onipresente está modificando os papéis e responsabilidades dos sistemas operacionais. N este livro revem os os princípios dos sistem as operacionais, discutim os os últim os avanços na com putação que estão redefinindo os sistemas operacionais e investigamos a estrutura e as responsabilidades dos sistemas operacionais. C onsiderações de projeto com o desem penho, tolerância a falhas, segurança, m odularidade e custo são exploradas detalhadam ente. Também abordam os questões m ais recentes do projeto de sistem as operacionais que surgem do rápido crescim ento da com putação distribuída possibilitada pela Internet e pela World Wide Web. Dedicam os muito esforço para criar o que esperam os ser um a experiência informativa, interessante e desafiadora para você. Ao ler este livro, você talvez queira consultar o nosso site em www.deitel.com para atualizações e inform ações adicionais sobre cada tópico. Se quiser falar conosco, envie um e-mail para [email protected]. 1.2 O &unv sisteuuv ojteraciotuil? N a década de 1960 a definição de um sistem a operacional com o o software que controla o hardware estava de acordo com aquela realidade, contudo, desde então, o panoram a dos sistem as de com putador evoluiu significativamente, exigindo um a descrição mais rica. H oje o hardw are executa um a grande variedade de aplicações de software. Para aum entar a utilização do hardware, as aplicações são projetadas para ser executadas concorrentem ente. Se elas não forem cuidadosam ente program adas poderão interferir umas nas outras. Isso resultou na existência de um a cam ada de software, denom inada sistema operacional, que separa as aplicações do hardware que elas acessam e fornece serviços que perm item que cada aplicação seja executada com segurança e efetivamente. Sistem a operacional é um software que habilita as aplicações a interagir com o hardw are de um computador. O software que contém os com ponentes centrais do sistem a operacional é denom inado núcleo. Sistemas operacionais podem ser encontrados em dispositivos que vão de telefones celulares e autom óveis a com putadores pessoais e com putadores de grande porte (m ainfram es). N a m aioria dos sistemas operacionais um usuário requisita ao com putador que realize uma ação (por exemplo, executar um a aplicação ou im prim ir um docum ento), e o sistem a operacional gerencia o software e o hardware para produzir o resultado desejado. Para grande parte dos usuários, o sistem a operacional é um a ‘caixa-preta’ entre as aplicações e o hardw are sobre o qual funcionam e que assegura o resultado correto dadas as entradas adequadas. Sistem as operacionais são, prim ordialm ente, gerenciadores de recursos — gerenciam hardware com o processadores, memória, dispositivos de entrada/saída e dispositivos de com unicação. Também devem gerenciar aplicações e outras abstrações de software que, diferentem ente do hardware, não são objetos físicos. N as seções seguintes apresentam os um a breve história dos sistem as operacionais desde o sistem a sim ples, em lote (batch), de um único usuário da década de 1950, até as plataform as com plexas de hoje: m ultiprocessadoras, distribuídas e multiusuário. Rwiiãtr 1. (V/F) Sistem as operacionais som ente gerenciam hardware. 2. Q uais são as finalidades prim árias de um sistem a operacional? Capítulo 1 Introdução aos sistema* operacionais 5 1) Falso. Sistemas operacionais gerenciam aplicações e outras abstrações de software, como máquinas virtuais. 2) As finalidades primárias de um sistema operacional são habilitar aplicações a interagir com um hardware de computador e gerenciar os recursos de hardware e software de um sistema. 13 O começo d a história: décadas d& 1940 &1950 Sistemas operacionais evoluiram nos últimos 60 anos, passando por diversas fases ou gerações distintas que correspondem aproxim adam ente às décadas (veja o quadro “Reflexões sobre Sistemas Operacionais, Inovação”).3N a década de 1940, os prim eiros com putadores digitais eletrônicos não tinham sistemas operacionais.4,5*6 As máquinas daquela época eram tão primitivas que os program adores muitas vezes subm etiam seus program as a linguagem de máquina, um bit por vez, em filas de chaves m ecânicas. Com a introdução das perfuradoras de cartão, esses mesmos program as foram subm etidos a cartões perfurados. Assim , linguagens de m ontagem (assembly) — que usavam abreviaturas parecidas com palavras em inglês para representar as operações básicas do com putador — foram desenvolvidas para acelerar o processo de programação. Os Laboratórios de Pesquisa da General M otors implementaram o primeiro sistema operacional no início da década de 50 para seu com putador IBM 7 0 L 7 Sistemas da década de 1950 geralmente executavam somente um job por vez, por meio de técnicas que tomavam mais suave a transição entre jobs para obter um a utilização m áxima do sistema do computador.8 O job (serviço) era composto de um conjunto de instruções de programas correspondentes a um a tarefa computacional particular, como folha de pagamento ou estoque. Jobs normalmente eram executados sem entradas do usuário durante minutos, horas ou dias. Esses primeiros computadores eram denominados sistemas de processamento em lote de fluxo único porque programas e dados eram submetidos em grupos ou lotes carregando-os consecutivamente em uma fita ou disco. Um processador de fluxo de job lia os comandos em linguagem de controle (que definiam cada job) e facilitava a configuração do job seguinte. Quando o job em questão terminava, a leitora de fluxo de job lia os comandos em linguagem de controle para o próximo job e executava as tarefas de preparo apropriadas para facilitar a transição para o job seguinte. Embora os sistemas operacionais da década de 1950 reduzissem os tempos de transição entre jobs, era muito comum solicitar aos programadores que controlassem diretamente recursos do sistema como memória e dispositivos de entrada/saída, o que se mostrava um trabalho lento, difícil e tedioso. E mais, os primeiros sistemas exigiam que um programa inteiro fosse carregado na memória para poder ser executado, limitando os programadores a criar programas pequenos com capacidades reduzidas.9 Revíião' 1. Por que foram desenvolvidas linguagens de montagem (assem bly)? 2. O que lim itava tam anho e capacidades dos program as da década de 50? R e ip o ifa i: 1) L inguagens de m ontagem foram desenvolvidas para acelerar o processo de program ação. H abilitavam os program adores a especificar com andos sob a form a de abreviações parecidas com palavras em inglês utilizadas pelos seres humanos para trabalhar com m aior facilidade do que com instruções em linguagem de máquina. 2) O program a inteiro tinha de ser carregado na m em ória para ser executado. Com o era relativam ente cara, a quantidade de m em ória disponível naqueles com putadores era pequena. R ô4 -[ e x õ e s ç o b r c o IttOUtlÇÂO Inovação é um desafio funda­ mental para projetistas de sistemas operacionais. Caso queiramos fazer os investimentos maciços exigidos para p ro d u z ir novos s is te m a s operacionais ou novas versões de sistemas operacionais existentes, devemos avaliar constantem ente novas tecnologias, novas aplicações de computação e comunicações e novos modos de pensar sobre como os sistemas devem ser construídos. Fornecemos milhares de referên­ cias e centenas de recursos da W eb para que você possa ler mais sobre os tópicos de seu interesse. Você deve pensar em se associar a organizações profissionais como a ACM (www.acm.org), o IEEE (www.ieee.org) e o USENIX (www.usenix.org), que pu­ blicam periódicos sobre as últimas pesquisas e esforços de desenvol­ vim ento no campo da computação. Deve também acessar a Web freqüentemente para se colocar a par de desenvolvimentos importantes na área. Há sempre um alto grau de risco na inovação, mas as recom­ pensas podem ser substanciais. 6 S U tw u is o jte ra à o tu u t 1.4 A década, de, 1960 Os sistemas da década de 1960 também eram sistemas de processamento em lote, mas usavam os recursos do computador mais eficientemente executando diversos jobs ao mesmo tempo. Entre esses sistemas estavam muitos dispositivos periféricos como leitoras de cartão, perfuradoras de cartão, impressoras, unidades de fita e unidades de disco. Um job qualquer raramente utilizava todos os recursos do sistem a eficientemente. Um jo b típico usaria o processador durante um certo período de tempo antes de executar um a operação de entrada/saída (E/S) em um dos dispositivos periféricos do sistema. Nesse ponto o processador ficava ocioso enquanto o job esperava a operação de E/S terminar. Os sistem as da década de 1960 m elhoraram a utilização de recursos perm itindo que um job usasse o processador, enquanto outros utilizavam os dispositivos periféricos. N a verdade, executar uma m istura de diferentes jobs — alguns que utilizavam principal mente o processador (denominados jobs orientados a processador ou jobs orientados à computação) e outros que usavam principalm ente dispositivos periféricos (denom inados jobs orientados a E/S)— parecia ser a m elhor m aneira de otim izar a utilização de recursos. Com essas observações em mente, projetistas de sistemas operacionais desenvolveram sistem as de multiprogramação que gerenciavam diversos jobs ao m esm o tem po.10- " • 12 Em um am biente de m ultiprogram ação, o sistem a operacional com uta rapidam ente o processador de jo b em job m antendo vários deles em andam ento e, ao m esm o tempo, os dispositivos periféricos tam bém em uso. O grau de multiprogramação de um sistem a (também cham ado de nível de multiprogramação) indica quantos jo b s podem ser gerenciados ao mesmo tempo. Assim, os sistem as operacionais evoluíram do gerenciam ento de um job para o gerenciam ento de diversos jobs ao m esm o tempo. Em sistemas de com putação multiprogramados, o com partilhamento de recursos é uma das metas principais. Quando recursos são compartilhados por um conjunto de processos, e cada processo mantém controle exclusivo sobre certos recursos a ele alocados, um determ inado processo pode ficar esperando por um recurso que nunca se tom ará disponível. Se isso ocorrer, esse processo não conseguirá term inar sua tarefa e o usuário talvez tenha de reiniciá-lo, perdendo todo o trabalho que o processo tinha executado até aquele ponto. No Capítulo 7, “Deadlock e adiamento indefinido” , discutiremos com o os sistemas operacionais podem lidar com tais problemas. N orm alm ente os usuários da década de 1960 não estavam presentes no local onde o com putador estava instalado quando seus jobs eram executados. Esses eram subm etidos em cartões perfurados ou fitas de com putador e perm aneciam em mesas de entrada até que o operador do sistem a (um ser hum ano) pudesse carregá-los no com putador para execução. M uitas vezes o jo b de um usuário ficava parado durante horas ou até dias antes de poder ser processado. O m enor erro em um program a, até mesmo um a vírgula ou um ponto que faltasse, ‘bom bardeava’ o job, quando então o usuário (muitas vezes frustrado) corrigiría o erro, subm etería novam ente o job e mais um a vez esperaria por horas ou dias pela próxim a tentativa de execução. O desenvolvim ento de softwares naquele am biente era penosam ente lento. Em 1964, a IBM anunciou sua fam ília de com putadores System /360 ( ‘360’ refere-se a todos os pontos existentes em uma bússola para exprim ir sua aplicabilidade universal).13*14*15*16Os vários m odelos de com putadores 360 foram projetados para ser com patíveis com o hardware, para usar o sistem a operacional O S/360 e para oferecer m aior capacidade de com putação à m edida que o usuário ia subindo na série.17 Com o passar dos anos, a IBM desenvolveu sua arquitetura 360 passando para a série 37018*19 e, m ais recentem ente, para a série 39020 e para a zSeries.21 Foram desenvolvidos sistem as operacionais m ais avançados para atender a diversos usuários interativos ao mesmo tempo. Usuários interativos com unicam -se com seus jo b s durante a execução. N a década de 1960, os usuários interagiam com o com putador via ‘term inais burros’ (dispositivos que forneciam um a interface de usuário, mas nenhum a capacidade de processam ento) on-line (ligados diretam ente ao com putador via conexão ativa). Com o o usuário estava presente e interagindo com o sistem a do com putador, esse precisava responder rapidam ente às solicitações daquele; não fosse assim, sua produtividade podería ser prejudicada. Com o discutirem os no quadro “Reflexões sobre sistem as operacionais, Valor relativo de recursos humanos e de com putador” , a m elhoria da produtividade tom ou-se um objetivo im portante para os com putadores, porque recursos humanos são extremamente caros em com paração aos de computador. Foram desenvolvidos sistem as de tempo compartilhado para apoiar usuários interativos sim ultâneos.22 M uitos dos sistem as de tem po com partilhado da década de 1960 eram m ultim odais que suportavam processam ento em lote, bem com o aplicações de tempo real (sistemas de controle de processo industrial).23 Sistemas de tempo real tentam dar um a resposta dentro de um certo prazo lim itado. Por exemplo, um a m edição realizada em um a refinaria de petróleo indicando que as tem peraturas estão m uito altas exige atenção im ediata para evitar uma explosão. É com um que os recursos de um sistem a de tempo real sejam extrem am ente subutilizados — é mais im portante que tais sistem as dêem um a resposta rápida do que usem seus recursos eficientemente. Executar tanto jobs em lote quanto de tem po real significava que os sistem as operacionais tinham de distinguir entre tipos de usuários e fornecer a cada um deles um nível apropriado de serviço. Jobs de processam ento em lote podiam sofrer atrasos razoáveis, enquanto aplicações interativas dem andavam um nível m ais alto de serviço e sistemas de tempo real exigiam níveis de serviços extrem am ente altos. Entre os mais im portantes esforços de desenvolvim ento de sistem as de tem po com partilhado desse período estão o CTTS (Compatible Time-Sharing System , sistem a com patível de tem po com partilhado)24,25 desenvolvido pelo MIT, o TSS {Time Sharing System , sistem a de tempo com partilhado)26 desenvolvido pela IBM , o sistem a Multics27desenvolvido Capítulo 1 Introdução aos sistema* operacionais 7 pelo MIT, G E e Bell Laboratories para ser o sucessor do CTTS, e o C P /C M S (Control Program/Conversational M onitor System , program a de controle/sistem a m onitor conversacional) que eventualm ente evoluiu para o sistem a operacional V M ( Virtual M achine, m áquina virtual) da IBM , desenvolvido pelo Cam bridge Scientific C enter da IBM .28 29 Esses sistemas foram projetados para executar tarefas básicas de com putação interativa para indivíduos, mas seu real valor provou ser a m aneira com o com partilhavam program as e dados e dem onstravam a im portância da com putação interativa em am bientes de desenvolvim ento de programas. Os projetistas do sistem a M ultics foram os primeiros a usar o termo processo para descrever um program a em execução no contexto dos sistemas operacionais. Em muitos casos, os usuários submetiam jobs contendo vários processos que podiam ser executados sim ultaneam ente. No Capítulo 3, “Conceito de processos” , discutirem os com o sistem as operacionais de m ultiprogram ação gerenciam vários processos ao mesmo tempo. Em geral, processos concorrentes são executados independentemente, mas sistemas de multiprogramação habilitam vários processos a cooperar para executar uma tarefa comum. No Capítulo 5, “Execução assíncrona concorrente”, e no Capítulo 6, “Programação concorrente”, discutiremos como os processos coordenam e sincronizam atividades e com o os sistemas operacionais suportam essa capacidade. M ostramos muitos exemplos de programas concorrentes, alguns expressos genericamente em pseudocódigo e outros na popular linguagem de programação J a v a ^ . O tempo de retorno - o tem po entre a submissão de um jo b e o retom o de seus resultados - foi reduzido para m inutos ou até segundos. O program ador não precisava mais esperar horas ou dias para corrigir os erros mais sim ples. Podia entrar com o program a, fazer a com pilação, receber um a lista de erros de sintaxe, corrigi-los im ediatam ente, recom pilar e continuar esse ciclo até o program a estar livre de erros de sintaxe. Então ele podia ser executado, depurado, corrigido e concluído com econom ias de tempo semelhantes. O valor dos sistemas de tempo com partilhado no suporte do desenvolvim ento de program as foi dem onstrado quando o MIT, a G E e o Bell L aboratories usaram o sistem a CTSS para desenvolver um sucessor próprio, o M ultics. Esse program a foi notável por ter sido o prim eiro grande sistem a operacional escrito prim ariam ente em um a linguagem de alto nível (EPL - estruturada segundo o m odelo PL/1 da IBM ), e não em linguagem de montagem (assembly). Os projetistas do UNIX aprenderam com essa experiência; criaram a linguagem de alto nível C especificam ente para im plem entar o UNIX. Uma família de sistemas operacionais baseados no UNIX, entre eles o Linux e o UNIX Berkeley Software Distribution (BSD), evoluiu do sistem a original criado por Dennis Ritchie e Ken Thom pson no Bell Laboratories no final da década de 1960 (veja no site deste livro: “Biografia — Ken Thom pson e D ennis Ritchie”). TSS, M ultics e CP/CM S, todos incorporavam memória virtual, que discutirem os detalhadam ente no Capítulo 10, “Organização da m em ória virtual” , e Capítulo 11, “G erenciam ento de m em ória virtual” . Em sistem as com m em ória R e fle x õ e s o ^ e s ô tÀ o w â à ç , Valor reiaturo de recursos kumasios e de coutfxttaÁor Em 1965, programadores razoa­ velm ente experientes ganhavam cerca de US$ 4 por hora. A taxa de aluguel de tempo de computa­ dor em computadores de grande porte (cuja capacidade era m uito menor do que a das máquinas de mesa de hoje) era normalmente de US$ 500 ou mais por hora — e isso em dólares de 1965 que, devido à inflação, seriam comparáveis a mi­ lhares de dólares em moeda atual! Hoje, você pode comprar um com­ putador de mesa topo de linha, de enorme capacidade, pelo custo do aluguel de uma hora de computador de grande porte, de capacidade bem menor, 40 anos atrás! Enquanto o custo de computação despencou, o custo de homem-hora subiu até um ponto que, atualmente, os recur­ sos humanos são muito, mas muito mais caros do que os recursos de computação. Hardware, sistemas operacio­ nais e programas de aplicação para computadores são todos projetados para alavancar o tempo das pessoas, para melhorar eficiência e produti­ vidade. Um exemplo clássico disso foi o advento de sistemas de tempo compartilhado na década de 1960. Esses sistem as interativos (com tem pos de resposta quase im e­ diatos) m uitas vezes habilitavam os programadores a se tornarem muito mais produtivos do que era possível com os tempos de resposta de sistemas de processamento em lotes que chegavam a horas e até dias. Um outro exemplo clássico foi a criação da interface gráfica com o usuário (GUI) originalmente de­ senvolvida pelo Paio Alto Research Center (PARC) da Xerox na década de 1970. Com recursos de compu­ tação mais baratos e poderosos, e com o custo relativo de homemhora su b in d o ra p id a m e n te em comparação ao de computação, os projetistas de sistemas operacionais devem fornecer capacidades que favoreçam o ser humano sobre a máquina, exatamente o oposto do que faziam os primeiros sistemas operacionais. 8 S U tw u is o jte ra à o tu u t virtual, os program as conseguem endereçar m ais localizações de m em ória do que as realm ente providas na memória principal, tam bém cham ada m em ória real ou m em ória física.30’31 (M em ória real é discutida no Capítulo 9, “Organização e gerenciam ento da m em ória real”)- Sistem as de m em ória virtual ajudam a livrar os program adores de grande parte da carga do gerenciam ento da m emória, liberando-os para se concentrarem no desenvolvim ento de aplicações. D esde que carregados na m em ória principal, os program as podiam ser executados rapidam ente; todavia, a m em ória principal era dem asiadam ente cara para conter grandes núm eros de program as de um a vez. A ntes da década de 1960, os jobs eram , em grande parte, carregados na m em ória usando cartões perfurados ou fitas, um trabalho tedioso e dem orado durante o qual o sistem a não podia ser utilizado para executar jobs. Os sistem as da década de 1960 incorporavam dispositivos que reduziam o tem po ocioso, arm azenando grandes quantidades de dados regraváveis em m eios m agnéticos de arm azenam ento relativam ente baratos com o fitas, discos e tam bores. Em bora discos rígidos perm itissem acesso relativam ente rápido a program as e dados em com paração com fitas, eram significativamente m ais lentos do que a memória principal. No Capítulo 12, “O tim ização do desem penho de discos” , discutim os com o sistem as operacionais podem gerenciar requisições de entrada/saída do disco para m elhorar o desem penho. No Capítulo 13, “ Sistem as de arquivos e de bancos de dados” , discutim os com o os sistem as operacionais organizam dados em coleções cham adas arquivos e gerenciam espaço em dispositivos de arm azenam ento com o discos. D iscutim os tam bém com o os sistem as operacionais protegem dados contra o acesso por usuários não autorizados e evitam que se percam quando ocorrem falhas de sistem a ou outros eventos catastróficos. Revuão' 1. Com o a com putação interativa e a m elhoria que causou no tempo de retom o aum entaram a produtividade do program ador? 2. Q uais foram os novos conceitos incorporados pelo TTS, M ultics e CP/CM S? Por que foram tão úteis para os program adores? ReipoÜcn: 1) O tempo entre a submissão de um job e o retom o de seus resultados foi reduzido de horas ou dias para minutos ou até segundos, o que habilitava os programadores a entrar, editar e com pilar programas interativamente até eliminar seus erros de sintaxe e, assim, usar um ciclo similar para testar e depurar seus programas. 2) TSS, Multics e CP/CMS incorporavam memória virtual. A memória virtual permite às apücações acesso a mais memória do que estaria fisicamente disponível no sistema, o que, por sua vez, habilita os programadores a desenvolver aplicações maiores, mais poderosas. Além disso, sistemas de memória virtual liberam o programador de grande parte da carga do gerenciamento da memória. 1.5 AeU ccuU(U l970 Os sistemas da década de 1970 eram primordialmente multimodais de multiprogramação que suportavam processamento em lote, tem po com partilhado e aplicações de tempo real. A com putação estava em seus estágios incipientes, favorecida por desenvolvim entos anteriores e contínuos da tecnologia de m ultiprocessadores.32 Os sistem as experim entais de tempo com partilhado da década de 1960 evoluíram para produtos com erciais sólidos na década de 1970. Com unicações entre sistem as de com putadores por todos os Estados U nidos aum entaram quando os padrões de com unicações T C P/IP do D epartam ento de D efesa passaram a ser am plam ente usados — especialm ente em am bientes de com putação m ilitares e universitários.33,34’35A com unicação em redes locais (LANs) ficou prática e econôm ica com o padrão Ethernet desenvolvido no Paio Alto Research C enter (PARC) da X erox.36,37No Capítulo 16, “ Introdução às redes”, discutirem os TCP/IP, Ethernet e conceitos fundam entais de redes. Os problem as de segurança aum entaram com o crescim ento dos volum es de inform ação transm itidos por linhas de com unicações vulneráveis (veja no site deste livro: “Curiosidades — A braham Lincoln e o Cuidado com a Tecnologia”). A criptografia foi alvo de m uita atenção — tom ou-se necessário criptografar dados proprietários ou privados de modo que, m esm o que corressem riscos, não teriam nenhum valor senão para aqueles a quem eram destinados. No Capítulo 19, “Segurança” , discutirem os com o os sistemas operacionais protegem inform ações vulneráveis contra acesso não autorizado. Durante a década de 1970 os sistemas operacionais passaram a incluir capacidades de redes e de segurança, e seu desempenho continuou a m elhorar para atender às dem andas com erciais. A revolução da com putação pessoal com eçou no final da década de 1970 com sistem as com o o A pple II, e explodiu na década de 1980. R c v U ã fy 1. Q uais foram os desenvolvim entos da d écada de 1970 que m elhoraram a com unicação entre sistem as de com putadores? Capítulo 1 Introdução aos sistema* operacionais 9 2. Qual foi o novo problem a introduzido pelo crescim ento da com unicação entre com putadores? Com o esse problem a foi abordado? Reipoitãi: 1) Os padrões TCP/IP do DoD (D epartam ento de D efesa dos Estados Unidos) passaram a ser am plam ente usados em redes de com unicações — inicialm ente em am bientes de com putação m ilitares e universitários. E, tam bém , o PARC, da Xerox, desenvolveu o padrão Ethernet, que tomava práticas e econômicas as redes locais (LANs) de velocidade relativamente altas. 2) A com unicação entre com putadores introduziu problem as de segurança, porque os dados eram enviados por linhas de com unicação vulneráveis. Em pregou-se a criptografia para que os dados ficassem ilegíveis para todos, exceto para quem deveria recebê-los. 1.6 A década d& 1980 Os anos 80 representaram a década do com putador pessoal e da estação de trabalho.38A tecnologia do microprocessador evoluiu até o ponto em que era possível construir com putadores de m esa avançados (denominados estações de trabalho) tão poderosos quanto os de grande porte de um a década atrás. O Personal Com puter da IBM lançado em 1982 e o com putador pessoal Apple M acintosh, em 1984, possibilitaram que indivíduos e pequenas empresas tivessem seus próprios computadores dedicados. Podiam -se utilizar recursos de com unicação para transm itir dados rápida e econom icam ente entre sistemas. Em vez de se levar dados a um com putador central, de grande porte, para processam ento, a com putação era distribuída aos lugares onde necessário. Softwares com o program as de planilhas de cálculo, editores de texto, pacotes de bancos de dados e pacotes gráficos ajudavam a dar im pulso à revolução da com putação pessoal, criando dem anda entre as em presas que podiam usar esses produtos para aum entar sua produtividade. A prender e usar com putadores pessoais provou ser algo relativam ente fácil, em parte por causa das interfaces gráficas com o usuário (GUI) que utilizavam sím bolos gráficos com o janelas, ícones e m enus para facilitar a interação do usuário com os program as. O Paio Alto Research Center (PARC) da Xerox desenvolveu o mouse e a GUI (para m ais inform ações sobre a origem do mouse, consulte o site deste livro: “Biografia — Doug Engelbart”); o lançam ento do com putador pessoal M acintosh da A pple em 1984 popularizou o seu uso. Nos com putadores M acintosh, a GUI estava em butida no sistema operacional, de m odo que o aspecto e a sensação de todas as aplicações seriam sim ilares.39 U m a vez fam iliarizado com a GUI do M acintosh, o usuário podia aprender a usar as aplicações mais rapidamente. À m edida que os custos da tecnologia declinavam, a transferência de inform ações entre com putadores interconectados em rede tom ou-se mais econôm ica e prática. Proliferavam aplicações de correio eletrônico, transferência de arquivos e acesso a bancos de dados remotos. A Computação Distribuída (ou seja, usar vários com putadores independentes para desem penhar um a tarefa com um ) proliferou com o m odelo cliente/servidor. Clientes são com putadores de usuários que requisitam vários serviços; servidores são com putadores que executam os serviços requisitados. M uitas vezes os servidores são dedicados a um tipo de tarefa, com o renderizar gráficos, gerenciar bancos de dados ou servir páginas Web. O cam po da engenharia de software continuou a evoluir, com um grande im pulso partindo do governo dos Estados Unidos que visava ao controle mais rígido dos projetos de software do D epartam ento de Defesa.40 Entre as metas da iniciativa estavam a reutilização de códigos e a construção de protótipos para que desenvolvedores e usuários pudessem sugerir modificações desde o início do processo de projeto de software.41 Revíião' 1. Qual aspecto dos com putadores pessoais, popularizado pelo A pple M acintosh, os tom ava especialm ente fáceis de aprender e usar? 2. (V/F) Um servidor não pode ser um cliente. 1) Interfaces Gráficas com o U suário (GUIs) facilitavam o uso do com putador pessoal proporcionando um a interface uniform e, fácil de usar, para cada aplicação, o que habilitava os usuários a aprender a nova aplicação m ais rapidamente. 2) Falso. U m com putador pode ser cliente e servidor. Por exemplo, um servidor Web pode ser ambos, cliente e servidor. Quando usuários requisitam um a página Web, ele é um servidor; se então, com o servidor, ele requisitar inform ações de um sistem a de banco de dados, irá se tom ar um cliente do sistem a de banco de dados. 1.7 A história d a Internet &d a World Wid& Web N o final da década de 60, a ARPA - Advanced Research Projects Agency do D epartam ento de D efesa dos Estados Unidos levou adiante os esquem as para interligar em rede os sistem as centrais de com putadores de cerca de uma dúzia de 10 S U tw u is o jte ra c io fu iti universidades e instituições de pesquisas apoiadas financeiramente por essa agência. Eles seriam conectados por linhas de com unicações que operavam a um a taxa, então impressionante, de 56 quilobits por segundo (Kbps) — 1 Kbps é igual a mil bits por segundo — em um a época em que a m aioria das pessoas (das poucas que podiam ) estavam se conectando a com putadores por linhas telefônicas a um a taxa de 110 bits por segundo. Harvey M. Deitei (HM D) recorda vividamente a agitação daquela conferência. Pesquisadores de Harvard falavam em com unicar-se com o ‘supercom putador’ Univac 1108 da U niversidade de Utah, do outro lado do país, para processar a m assa de cálculos relacionada às suas pesquisas sobre com putação gráfica. A pesquisa acadêm ica estava prestes a dar um salto gigantesco para a frente. Logo após essa conferência, a ARPA partiu para im plem entar o que rapidam ente ficou conhecido com o ARPAnet — a avó da Internet de hoje. Em bora a ARPAnet habilitasse os pesquisadores a interligar seus com putadores em rede, seu principal benefício provou ser a capacidade de com unicação fácil e rápida via o que hoje conhecem os com o correio eletrônico (e-mail). E isso vale até mesmo para a Internet atual, com e-mail, m ensagem instantânea (instant m essaging) e transferência de arquivos, facilitando as com unicações entre centenas de m ilhões de pessoas no m undo inteiro e crescendo rapidamente. A ARPAnet foi projetada para operar sem controle centralizado, o que significava que, se um a parte da rede falhasse, as partes que continuavam funcionando ainda poderíam encam inhar pacotes de dados de transm issores a receptores por cam inhos alternativos. Os protocolos (conjunto de regras) para com unicação pela ARPAnet ficaram conhecidos com o Transmission Control Protocol/Intemet Protocol (TCP/IP). O TCP/IP era usado para gerenciar com unicação entre aplicações. Os protocolos garantiam que m ensagens fossem encam inhadas (roteadas) adequadam ente entre transm issores e receptores e que essas m ensagens chegassem intactas. O advento do TCP/IP promoveu o crescim ento da com putação em todo o mundo. Inicialmente a utilização da Internet limitava-se às universidades e instituições de pesquisa; mais tarde os militares adotaram a tecnologia. Eventualmente o governo decidiu perm itir o acesso à Internet para propósitos com erciais. Essa decisão causou um a certa preocupação entre as com unidades de pesquisa e m ilitares — achava-se que os tem pos de resposta seriam prejudicados quando ‘a N et’ ficasse saturada de usuários. N a verdade, ocorreu o contrário. A com unidade de negócios rapidam ente com preendeu que podia usar a Internet para ajustar suas operações e oferecer novos e m elhores serviços a seus clientes. Em presas gastaram enorm es quantidades de dinheiro para desenvolver e prom over sua presença na Internet, o que gerou intensa concorrência entre em presas de telecom unicações, fornecedores de hardw are e fornecedores de software para atender à crescente dem anda de infra-estrutura. O resultado é que a largura de banda (a capacidade de transm issão de inform ações das linhas de com unicações) da Internet aum entou trem endam ente, e os custos de hardw are e com unicações despencaram. A World Wide Web (WWW) perm ite que usuários de com putador localizem e vejam docum entos m ultim ídia (docum entos com texto, gráficos, animação, áudio ou vídeo) sobre praticam ente qualquer assunto. Em bora a Internet tenha sido desenvolvida há m ais de três décadas, a introdução da World W ide Web (W W W ) é um evento relativam ente recente. Em 1989, Tim Bem ers-Lee, do CERN (European C enter for N uclear Research), com eçou a desenvolver uma tecnologia de com partilham ento de inform ações via docum entos de texto interconectados (hyperlinked) (veja no site deste livro: “Biografia — Tim B em ers-Lee”). Para im plem entar essa nova tecnologia, B em ers-Lee criou a HyperText Markup Language (HTML). Também im plem entou o HyperText TVansfer Protocol (HTTP) para form ar a espinha dorsal das com unicações desse novo sistem a de inform ações de hipertexto, que ele batizou de World W ide Web. Certam ente os historiadores colocarão a Internet e a World Wide Web na lista das criações m ais im portantes e profundas da humanidade. No passado, a m aioria das aplicações era executada em com putadores ‘autônom os’ (com putadores que não estavam conectados uns aos outros). As aplicações de hoje podem ser escritas para se com unicarem entre as centenas de m ilhares de com putadores do m undo inteiro. A Internet e a World W ide Web fundem tecnologias de com putação e de com unicações acelerando e simplificando nosso trabalho. Tom am as inform ações instantânea e convenientemente acessíveis a um grande núm ero de pessoas. H abilitam indivíduos e pequenas em presas a conseguir exposição mundial. Estão m udando a m aneira com o fazemos negócios e conduzim os nossas vidas pessoais. E estão m udando nosso m odo de pensar sobre a construção de sistemas operacionais. Os sistem as operacionais de hoje oferecem G U Is que habilitam os usuários a ‘acessar o m undo’ pela Internet e pela W eb de m aneira transparente, com o se estivessem acessando o sistem a local. Os sistem as operacionais da década de 1980 preocupavam -se prim ariam ente com gerenciar recursos no com putador local. Os sistem as operacionais distribuídos de hoje podem utilizar recursos em com putadores do m undo inteiro. Isso cria m uitos desafios interessantes que discutirem os por todo o livro, especialm ente nos capítulos 16 a 19, que exam inam redes, com putação distribuída e segurança. Revíião' 1. Qual a diferença entre ARPAnet e as redes de com putadores tradicionais? Qual era o seu benefício prim ário? 2. Quais foram as criações desenvolvidas por Bemers-Lee que facilitaram o compartilhamento de dados pela Internet? Capítulo 1 Introdução aos sistemas operacionais 11 Reípoitài: 1) A ARPAnet era descentralizada, portanto a rede continuava habilitada a passar inform ações m esm o que partes dela falhassem. O benefício prim ário da ARPAnet era sua capacidade de com unicação rápida e fácil via e-mail. 2) B em ers-Lee desenvolveu a H TM L e o HTTP, que possibilitaram a World W ide Web. 1.8 A década de, 1990 O desem penho do hardw are continuou a m elhorar exponencialm ente nos anos 90.42 No final da década, um com putador pessoal típico podia executar diversas centenas de m ilhões de instruções por segundo (M IPS) e arm azenar m ais de um gigabyte de inform ações em um disco rígido; alguns supercom putadores podiam executar mais de um trilhão de operações por segundo.43 Capacidades de processam ento e de arm azenam ento baratas habilitavam os usuários a executar programas com plexos em com putadores pessoais e possibilitavam que em presas de pequeno a m édio portes usassem essas máquinas econôm icas para os serviços (jobs) extensivos de banco de dados e processam ento, antes delegados a sistem as de com putadores de grande porte. A queda dos custos da tecnologia tam bém levou a um aum ento no núm ero de com putadores dom ésticos usados tanto para trabalho quanto para entretenim ento. A criação da W orld W ide Web na década de 1990 levou a um a explosão na popularidade da com putação distribuída. Originalm ente, os sistemas operacionais executavam gerenciam ento isolado de recursos em um único computador. Com a criação da World W ide Web e as conexões de Internet cada vez m ais velozes, a com putação distribuída tom ou-se trivial nos com putadores pessoais. Usuários podiam requisitar dados arm azenados em lugares remotos ou requisitar a execução de program as em processadores distantes. Grandes organizações podiam usar m ultiprocessadores distribuídos (redes de com putadores contendo m ais de um processador) para aum entar a escala de recursos e m elhorar a eficiência.44 N o entanto, aplicações distribuídas ainda estavam lim itadas pelo fato de a com unicação pela rede ocorrer em velocidades relativamente lentas com paradas a velocidades de processam ento interno de com putadores individuais. Com putação distribuída será discutida detalhadam ente no Capítulo 17, “ Introdução a sistemas distribuídos”, e Capítulo 18, “Sistem as distribuídos e serviços Web” . À m edida que crescia a dem anda por conexões com a Internet, o suporte a sistem as operacionais para tarefas de rede tom ava-se um padrão. Usuários dom ésticos e em em presas aumentavam sua produtividade acessando recursos de redes de com putadores. Todavia, o aum ento da conectividade levou a um a proliferação de am eaças à segurança dos computadores. Projetistas de sistem as operacionais desenvolveram técnicas para proteger com putadores contra esses ataques danosos. A crescente sofisticação de tais am eaças à segurança continuou a desafiar a capacidade de contra-ataque da indústria de com putadores. A M icrosoft Corporation tom ou-se dom inante na década de 1990. Em 1981, essa em presa lançou a prim eira versão do seu sistem a operacional DOS para o com putador pessoal da IBM . Em m eados da década de 1980, a M icrosoft desenvolveu o sistem a operacional W indows, um a interface gráfica com o usuário sobreposta ao sistem a operacional DOS. A M icrosoft lançou o W indows 3.0 em 1990; essa nova versão apresentava um a interface am igável com o usuário e grande funcionalidade. O sistem a operacional W indows tom ou-se incrivelmente popular após o lançam ento em 1993 do W indows 3.1, cujos sucessores W indows 95 e W indows 98 praticam ente dom inaram o m ercado de sistem as operacionais para com putadores de m esa no final da década de 1990. Esses sistem as operacionais, que tomavam em prestado muitos conceitos popularizados pelos prim eiros sistemas operacionais M acintosh (como ícones, menus e janelas), habilitavam os usuários a executar m últiplas aplicações concorrentes com facilidade. A M icrosoft tam bém entrou no m ercado de sistemas operacionais corporativos com o lançam ento do W indows N T em 1993, que rapidam ente tom ou-se o sistem a operacional preferido para estações de trabalho corporativas.45 O W indows XP, baseado no sistema operacional Windows NT, é discutido no Capítulo 21, “Estudo de caso: W indows XP” . Tecnologia/ de/ objeto A tecnologia de objeto tom ou-se popular em muitas áreas da com putação à m edida que aum entava constantem ente o número de aplicações escritas em linguagens de programação orientadas a objeto com o a C++ ou a Java. Conceitos de objeto tam bém facilitavam novas abordagens da com putação. Cada objeto de software encapsula um conjunto de atributos e um conjunto de ações, o que perm ite que as aplicações sejam construídas com com ponentes que possam ser reutilizados em muitas aplicações, reduzindo o tem po de desenvolvim ento de software. Nos sistemas operacionais orientados a objetos (SO O O ), objetos representam com ponentes do sistem a operacional e recursos do sistem a.46 Conceitos de orientação a objetos com o herança e interfaces foram explorados para criar sistem as operacionais modulares m ais fáceis de m anter e am pliar do que os construídos com técnicas anteriores. A m odularidade facilita o suporte dos sistemas operacionais para arquiteturas novas e diferentes. A dem anda por integração de objetos por meio de várias plataform as e linguagens levou ao suporte a objetos em linguagens de program ação com o a Java da Sun e a .NET da M icrosoft (por exem plo, Visual Basic.NET, Visual C++N ET e C#). 11 S U tw u is o p e ra c io tu ià Movimento do soJhvture^Uvre^ Um outro m ovim ento da com unidade de com putação (particularm ente na área de sistem as operacionais) durante a década de 1990 foi o m ovim ento em direção ao software de fonte aberto. A m aioria dos softwares é criada escrevendo-se o código-fonte em um a linguagem de program ação de alto nível. Contudo, a m aioria dos softw ares com erciais é vendida com o código-objeto (tam bém cham ado código de m áquina ou binários) - o código-fonte com pilado que os com putadores podem entender. O código-fonte não é incluído, o que perm ite aos fabricantes ocultarem inform ações proprietárias e técnicas de programação. Todavia, softwares de fonte aberto ficaram cada vez m ais com uns na década de 1990. Esse tipo de software é distribuído com o código-fonte, perm itindo que os indivíduos examinem e modifiquem o software antes de com pilá-lo e executá-lo. Por exemplo, o sistem a operacional Linux e o servidor Web Apache, am bos softw ares de fonte aberto, foram descarregados e instalados por m ilhões de usuários durante a década de 1990, e o número dessas operações cresce rapidam ente no novo milênio.47 O Linux, criado por Linus Torvalds (veja no site deste livro: “Biografia — Linus Torvald”), é discutido no Capítulo 20, “Estudo de caso: Linux” . N a década de 1980, Richard Stallman, um desenvolvedor de software do MIT, lançou um projeto para recriar e am pliar a m aioria das ferram entas do sistem a operacional UNIX da AT&T e disponibilizar o código sem nenhum custo. Stallman (veja no site deste livro: “Biografia — Richard Stallm an”) fundou a Free Software Foundation e criou o projeto GNU — um a abreviatura que significa “GNU Não é UNIX” — porque discordava do conceito de vender perm issão para utilizar software.48 E le acreditava que dar aos usuários a liberdade de modificar e distribuir software levaria a m elhores softwares, orientados pelas necessidades dos usuários, e não pelo lucro pessoal ou corporativo. Q uando Linus Torvald criou a versão original do sistema operacional Linux, empregou muitas das ferramentas publicadas gratuitamente pelo GNU sob a General Public License (GPL). A GPL, publicada on-line em www.gnu.org/licenses/gpl.html, especifica que qualquer um pode modificar e redistribuir software livrem ente sob sua licença, contanto que as modificações sejam claram ente indicadas e que qualquer derivado do software tam bém seja distribuído pela GPL.49 Em bora a m aioria dos softwares licenciados pela GPL seja gratuita, a G PL requer apenas que seu software seja livre no sentido de que os usuários tenham liberdade para modificar e redistribuir o software livremente. Portanto, fabricantes podem cobrar um a taxa para fornecer software licenciado pela G PL e seu código-fonte, mas não podem im pedir que usuários finais os modifiquem e redistribuam. No final da década de 1990 foi fundada a Open Source Iniciative (OSI) para proteger o software de fonte aberto e prom over os benefícios da program ação de código-fonte aberto (ver www.opensource.org). O software de fonte aberto facilita o aperfeiçoam ento de produtos de softw are por perm itir que qualquer um da com unidade dos desenvolvedores teste, depure e aperfeiçoe aplicações, o que aum enta a chance de descobrir e corrigir problem as im perceptíveis que, caso contrário, poderíam caracterizar riscos de segurança ou erros lógicos. A lém disso, indivíduos e corporações podem modificar o fonte e criar software personalizado que atenda às necessidades de um am biente particular. M uitos fabricantes de software livre mantêm sua lucratividade cobrando suporte técnico de indivíduos e corporações e personalizando seus produtos.50 Em bora a m aioria dos sistem as da década de 1990 ainda executem sistem as operacionais proprietários — com o sistemas operacionais de com putadores de grande porte da IBM , sistem as UNIX, M acintosh da A pple e W indows da M icrosoft — , sistem as operacionais de fonte aberto com o Linux, FreeBSD e OpenBSD tom aram -se concorrentes viáveis. No futuro, eles indubitavelm ente continuarão a ganhar terreno sobre as soluções proprietárias com o resultado do m elhoram ento do produto. N a década de 1990 os sistemas operacionais ficaram cada vez mais am igáveis ao usuário. As capacidades de GUI que a A pple inseriu no seu sistem a operacional M acintosh na década de 1980 tom aram -se m ais sofisticadas na década de 1990. Capacidades do tipo plug-and-play’ (ligar-e-usar) foram em butidas em sistemas operacionais, habilitando os usuários a adicionar e rem over com ponentes de software dinam icam ente sem ter de reconfigurar manualm ente o sistem a operacional. Sistemas operacionais tam bém m antêm perfis de usuários — o que atende às necessidades de autenticação e habilita a personalização da interface do sistem a operacional por usuário. Revuão' 1. Com o a tecnologia orientada a objeto afetou os sistem as operacionais? 2. Cite alguns dos benefícios do desenvolvim ento de software livre. 1) Projetistas de sistem as operacionais podiam reutilizar objetos ao desenvolverem novos com ponentes. O aum ento da m odularidade devido à tecnologia orientada a objeto facilitou o suporte do sistem a operacional para arquiteturas novas e diferentes. 2) Software livre pode ser visto e modificado por qualquer um que pertença à com unidade de desenvolvimento. Porque essas pessoas testam , depuram e usam constantem ente o software, há m aior chance de se descobrir e corrigir erros. Além disso, o software livre habilita usuários e organizações a modificar um program a para atender às suas necessidades particulares. Capítulo 1 Introdução aos sistemas operacionais 13 1.9 2000 &afora N esta década o middleware, um software que liga duas aplicações (muitas vezes por um a rede), tom ou-se vital, à m edida que aplicações são publicadas na World W ide Web e os consum idores as usam via conexões de Internet de alta velocidade e preços acessíveis por linhas de televisão a cabo e linhas digitais de assinantes (DSL — Digital Subscriber Lines). O middleware é com um em aplicações Web nas quais um servidor Web — a aplicação que envia dados ao navegador (browser) do usuário — deve gerar conteúdo que satisfaça os requisitos de um usuário com a ajuda de um banco de dados. O m iddleware age com o um courier passando m ensagens entre o servidor Web e o banco de dados, simplificando a com unicação entre várias arquiteturas diferentes. Serviços Web com preendem um conjunto de padrões relacionados que podem habilitar quaisquer duas aplicações de com putador a se com unicarem e trocar dados via Internet. Um serviço Web com unica-se com um a rede para fornecer um conjunto específico de operações que outras aplicações podem invocar. Os dados são passados de um lado para outro por meio de protocolos padronizados com o o HTTP, o m esm o protocolo usado para transferir páginas Web com uns. Serviços Web operam usando padrões abertos, baseados em texto que habilitam a com unicação entre com ponentes escritos em linguagens diferentes e sobre plataform as diferentes. São peças de software prontas para o uso na Internet. Serviços Web ajudarão a dar im pulso ao m ovim ento em direção à verdadeira com putação distribuída. Por exemplo, a Amazon.com perm ite que desenvolvedores estabeleçam lojas on-line que pesquisam os bancos de dados de produtos da em presa e m ostram inform ações detalhadas de produto viaA m azon.com Web Services (www.amazon.com/gp/aws/landing.html). A m áquina de busca Google tam bém pode ser integrada a outras aplicações por meio das APIs Web do Google (www.google.com/ apis),habilitando assim o acesso aos bilhões de sites Web fornecidos pelo Google para essas aplicações. Discutirem os serviços Web m ais detalhadam ente no Capítulo 18, “Sistem as distribuídos e serviços Web” . M ultiprocessadores e arquiteturas de rede estão criando num erosas oportunidades de pesquisa e desenvolvim ento de novas técnicas de projeto de hardware e software. Linguagens de programação seqüencial que especificam uma com putação por vez agora são com plem entadas por linguagens de program ação concorrente com o a Java, que habilitam a especificação de com putações paralelas; na Java, as unidades de com putação paralela são especificadas via threads. D iscutiremos threads e a técnica de m ultithreads no Capítulo 4, “Conceitos de thread” . Um núm ero cada vez m aior de sistem as exibem paralelismo maciço, ou seja, possuem grandes quantidades de processadores de m odo que muitas partes independentes das com putações podem ser executadas em paralelo. Esse é um conceito de com putação drasticam ente diferente da com putação seqüencial dos últimos 60 anos; há problemas significativos e desafiadores no desenvolvim ento de software apropriado para lidar com tal paralelism o. Discutirem os arquiteturas de com putação paralela no Capítulo 15, “Gerenciam ento de m ultiprocessador” . Sistemas operacionais estão padronizando interfaces com o usuário e de aplicação para que se tom em m ais fáceis de usar e suportem um núm ero m aior de programas. A M icrosoft já fundiu as linhas de consum idor e profissional de seu sistem a operacional W indows no W indows XP. No seu próxim o sistem a operacional (de codinom e Longhom ) a em presa planeja integrar os form atos de diferentes tipos de arquivos perm itindo, por exemplo, que os usuários pesquisem todos os arquivos dos seus sistemas (documentos, planilhas de cálculo, e-m ails etc.) que contenham certas palavras-chave. O Longhom incluirá também uma interface com o usuário aperfeiçoada, em 3D, melhor segurança e suporte para DVDs.51*52 Sistemas de fonte aberto com o o Linux serão mais am plam ente usados e em pregarão APIs (Application Programming Interfaces), com o a POSEX (Portable Operating System Interface ) para m elhorar a com patibilidade com outros sistemas operacionais baseados no UNIX. A com putação em dispositivos móveis, com o telefones celulares e PDAs, irá se tornar m ais com um à m edida que for equipada com processadores cada vez m ais poderosos. Hoje, tais dispositivos são usados para funções com o e-mail, navegação na Web e im agem digital. A plicações intensivas em recursos com o vídeo full-motion proliferarão nesses dispositivos. Com o os recursos de dispositivos móveis são lim itados pelo seu pequeno tam anho, a com putação distribuída desem penhará um papel ainda maior, à m edida que PDAs e telefones celulares requisitarem quantidades cada vez m aiores de dados e de capacidade de processam ento de com putadores remotos. Revuão' 1. Q uais tecnologias podem ser usadas para transpor a lacuna entre sistem as operacionais diferentes? Com o essas tecnologias possibilitariam a execução da m esm a aplicação em várias plataform as? 2. Por que a com putação distribuída é útil para com putações executadas por dispositivos móveis? 1) M áquinas virtuais e em uladores de sistemas operacionais transpõem a lacuna entre sistemas operacionais diferentes. Aplicações podem ser escritas um a vez para utilizar a funcionalidade da m áquina virtual ou emulador. M áquinas virtuais ou em uladores podem ser im plem entados para ocultar, das aplicações, a representação da plataform a básica. 2) Com putação 14 S is te m a s o p e ra c io n a is distribuída perm ite que um dispositivo móvel delegue tarefas a outras máquinas com m ais recursos. O dispositivo móvel, que tem recursos e tem po de batería lim itados, pode requisitar dados e capacidade de processam ento por um a rede. 1.10 Bases apUca/fio Quando o Personal Com puter da IBM (quase sempre cham ado de ‘P C ’) surgiu em 1981, im ediatam ente deu origem a uma imensa indústria de software na qual fornecedores independentes de software (Independem Software Vendors - IS Vs) conseguiam com ercializar pacotes para o IBM PC que podiam ser executados no sistem a operacional M S-DOS (a versão da IBM era cham ada DOS). Sistemas operacionais liberam os desenvolvedores de softwares de aplicação da obrigação de lidar com os detalhes com plicados da manipulação do hardware de com putador para gerenciar memória, executar entrada/saída, lidar com linhas de com unicação e assim por diante. O sistema operacional oferece um a série de chamadas a interfaces de programação de aplicativos (API) que os program adores de aplicações usam para realizar m anipulações detalhadas de hardware e outras operações. A API fornece chamadas ao sistema pelas quais um program a usuário instrui o sistem a operacional a trabalhar; o desenvolvedor de aplicações tem de saber, sim plesm ente, que rotinas cham ar para executar as tarefas específicas (Figura l .l ) . Note que, na Figura l . l , a área acim a da linha tracejada, o espaço do usuário, indica com ponentes de software que não fazem parte do sistem a operacional e não podem acessar diretamente os recursos físicos do sistema. A área abaixo da linha tracejada, o espaço do núcleo, indica com ponentes de software que fazem parte do sistema operacional e têm acesso irrestrito aos recursos do sistema. Usam os essa convenção frequentem ente em nossos diagram as para indicar o privilégio que esses com ponentes de software gozam na execução. Se um a aplicação tentar usar mal os recursos do sistem a ou tentar usar recursos que não lhe são perm itidos, o sistema operacional deve intervir para evitar que a aplicação danifique o sistem a ou interfira em outras aplicações de usuário. Se um sistema operacional apresentar um am biente propício ao desenvolvim ento rápido e fácil de aplicações, ele e o hardw are terão m ais probabilidade de sucesso no mercado. O am biente de desenvolvim ento de aplicações criado pelo M S-DOS incentivou o desenvolvim ento de dezenas de m ilhares de pacotes de software de aplicação, o que, por sua vez, incentivou usuários a com prar IBM PCs e com patíveis. O W indows podia muito bem ter um a base de aplicações de cem mil aplicações. U m a vez que uma base de aplicação (isto é, a com binação do hardw are com o am biente do sistem a operacional no qual a aplicação é desenvolvida) seja am plam ente estabelecida, tom a-se extrem am ente difícil solicitar aos usuários e desenvolvedores de softw are que convertam para um am biente de desenvolvim ento de aplicações com pletam ente novo proporcionado por um sistema operacional radicalmente diferente. Assim, é provável que as novas arquiteturas que evoluirão nos próximos anos irão colocar todos os esforços no suporte às principais bases de aplicação existentes. 1.11 Ambientes de sistemas operasionais Este livro focaliza conceitos de sistem as operacionais relacionados a com putadores de uso geral com uma gam a de recursos, entre eles quantidades consideráveis de m em ória principal, altas velocidades de processam ento, discos de alta capacidade, vários dispositivos periféricos e assim por diante. Tais equipam entos são usados norm alm ente com o com putadores pessoais ou estações de trabalho. Fujurfc 1.1 Interação entre> aplicações &o sistema, operacional. Capítulo 1 Introdução aos sistemas operacionais 15 M uitos dos conceitos que se aplicam aos com putadores de uso geral tam bém se aplicam aos servidores Web e de bancos de dados mais avançados que contêm hardware de alto desempenho. Sistemas operacionais destinados a am bientes avançados devem ser projetados para suportar m em órias principais de grande porte, hardw are de uso específico e grandes números de processos. Discutirem os essas considerações no Capítulo 15, “Gerenciam ento de m ultiprocessador” . Sistemas embarcados proporcionam um desafio diferente ao projeto de sistemas operacionais. São caracterizados por um pequeno conjunto de recursos especializados que fornecem funcionalidade a dispositivos com o telefones celulares e PDAs. Em am bientes em barcados, o gerenciam ento eficiente de recursos é a chave para a construção de um sistem a operacional de sucesso. A capacidade de armazenam ento freqüentem ente é lim itada, portanto o sistem a operacional deve fornecer serviços usando um a quantidade m ínim a de código. Considerações com o gerenciam ento de energia (batería) e a necessidade de interfaces am igáveis com o usuário criam outros desafios para o projeto de sistem as operacionais em barcados. Sistemas de tem po real exigem que tarefas sejam realizadas em um período de tem po particular (quase sem pre curto). Por exemplo, o recurso de piloto autom ático de um a aeronave deve ajustar constantem ente velocidade, altitude e direção. Essas ações não podem esperar indefinidam ente — e às vezes não podem esperar de jeito nenhum — que outras tarefas não essenciais sejam concluídas. Sistemas operacionais de tempo real devem assegurar que processos respondam imediatamente a eventos críticos. Sistemas operacionais de tempo real não crítico garantem que tarefas de tempo real sejam executadas com alta prioridade, mas não garantem quais dessas tarefas serão concluídas a tempo, e nem se serão concluídas. Sistem as de tempo real crítico garantem que todas as suas tarefas sejam concluídas a tempo. D iscutirem os com o o Linux e o W indows XP lidam com aplicações de tem po real nos capítulos 20 e 21, respectivamente. Esses sistemas são encontrados em m uitos am bientes, incluindo robótica, aviação e outras aplicações de controle de sistema. M uitas vezes são usados em sistemas de missão crítica nos quais o sistem a não cum pre seus objetivos (ou seja, a m issão) se qualquer de suas tarefas não for concluída com sucesso e a tempo. Em sistem as de m issão crítica com o os de controle de tráfego aéreo, m onitoração de reatores nucleares e com ando e controle militar, vidas hum anas podem correr riscos. Sistemas críticos de negócios, com o servidores Web e bancos de dados, devem atingir seus objetivos consistentemente. No e-business isso pode significar a garantia de tem pos de resposta rápidos a usuários que estão com prando produtos pela Internet; em grandes corporações, pode significar habilitar funcionários a com partilhar inform ações eficientem ente e garantir que inform ações im portantes estejam protegidas de problem as com o falta de energia elétrica e falhas de discos. Diferentem ente dos sistemas de missão crítica, a em presa não fracassará necessariam ente se um sistem a crítico de negócios não atingir sempre seus objetivos. Alguns sistemas operacionais devem gerenciar hardware que podem ou não existir fisicamente na máquina. Uma máquina virtual (VM) é um a abstração em software de um com putador executado freqüentem ente com o um a aplicação de usuário sobre o sistem a operacional nativo.53 O sistem a operacional de uma m áquina virtual gerencia os recursos providos pela m áquina virtual. U m a das aplicações das máquinas virtuais é perm itir que várias instâncias de um sistema operacional sejam executadas sim ultaneam ente. O utra é a em ulação - usar softw are e hardw are que im itam a funcionalidade de hardware ou software que não estão presentes no sistema. M áquinas virtuais fazem interface com o hardw are de um sistem a via sistem a operacional; outros program as de usuário podem interagir com elas. U m a V M pode criar com ponentes de software que representem com ponentes físicos — com o processadores, m em ória, canais de com unicação, discos e relógios (Figura 1.2)54— , o que perm ite que vários usuários com partilhem hardw are na ilusão de que estão sendo atendidos por um a m áquina dedicada. Proporcionando essa ilusão, as m áquinas virtuais prom ovem a portabilidade, a capacidade do software ser executado em várias plataform as. A JVM (Java Virtual M achine, m áquina virtual Java) é um a das m ais am plam ente usadas. A JV M é a fundação da plataform a Java e perm ite que as aplicações Java sejam executadas em qualquer JVM da versão correta, independentem ente da plataform a na qual ela esteja instalada. A em presa VM w are Software tam bém fornece máquinas virtuais, particularm ente para a arquitetura Intel, habilitando os proprietários de computadores baseados no Intel x-86 a executar sistemas operacionais com o Linux e W indows sim ultaneam ente em um só com putador (cada m áquina virtual aparece na sua própria janela).55 M áquinas virtuais tendem a ser menos eficientes do que máquinas reais porque acessam o hardw are indiretam ente (ou sim ulam hardware que, na verdade, não está conectado ao com putador). A cesso indireto ou sim ulado ao hardware aum enta o núm ero de instruções de software requeridas para realizar cada ação do hardware.56 R evü ã o ' 1. Um m onitor de tem peratura em um a usina nuclear seria provavelmente descrito com o que tipo de sistem a? Por quê? 2. Descreva as vantagens e desvantagens das m áquinas virtuais. R e ifjo itã i: 1) Um sistem a de tem po real crítico m onitoraria a tem peratura em um a usina nuclear para garantir que ela estivesse sempre na faixa apropriada e notificaria os operadores em tempo real (ou seja, instantaneam ente), caso houvesse problemas. 16 S is te m a s o p e ra c io n a is Camada de hardware virtual Software Camada de hardware físico F igura/1.2 Diagrama d&um a mágulna virtual. 2) M áquinas virtuais promovem a portabilidade habilitando o softw are a ser executado em várias plataform as, mas tendem a ser menos eficientes do que máquinas reais, porque devem executar instruções de software que sim ulem operações de hardware. 1.12 Componentes e, objetivos do sistema, operacional Sistemas de com putadores evoluíram dos prim eiros que não continham nenhum sistem a operacional para máquinas de m ultiprogram ação, daí para m áquinas de tem po com partilhado, depois para com putadores pessoais e, por fim, para sistem as verdadeiram ente distribuídos. À m edida que a dem anda por novas características e m elhor eficiência cresciam e o hardware mudava, os sistem as operacionais evoluíram para cum prir novos papéis. Esta seção descreve vários com ponentes centrais e explica os diversos objetivos dos sistem as operacionais. 1.12.1 ContfMftmtes centrais do sistenub opercuiõKal Um usuário interage com o sistem a operacional via um a ou m ais aplicações de usuário e, muitas vezes, por m eio de uma aplicação especial denom inada Shell ou interpretador de com andos.57 A m aioria dos interpretadores de com ando atuais é im plem entada com o interfaces de texto que habilitam o usuário a em itir com andos por meio de um teclado, ou com o GUIs que perm item que o usuário ‘aponte-e-clique’ e ‘arraste-e-solte’ ícones para requisitar serviços do sistem a operacional (por exemplo, para abrir um a aplicação). O M icrosoft W indows X P fornece um a GUI por m eio da qual os usuários podem dar com andos; o usuário pode abrir altem ativam ente um a jan ela de com andos que aceite com andos digitados. O software que contém os com ponentes centrais do sistema operacional cham a-se núcleo (kemel). Entre os componentes centrais do sistem a operacional estão: • escalonador de processo, que d eterm in a quando e p o r qu an to tem po um p rocesso é executado em um processador. • gerenciador de memória, que determ ina quando e com o a m em ória é alocada aos processos e o que fazer quando a m em ória principal estiver cheia. • gerenciador de E/S, q u e aten d e às so lic ita ç õ e s de e n tra d a /sa íd a de e p ara d isp o sitiv o s de hard w are, respectivamente. • gerenciador de comunicação interprocessos (IPC), que perm ite que os processos se com uniquem uns com os outros. • gerenciador de sistema de arquivos, que organiza coleções nom eadas de dados em dispositivos de armazenamento e fornece um a interface para acessar os dados nesses dispositivos. Capítulo 1 Introdução aos sistemas operacionais 17 Q uase todos os sistem as operacionais suportam um am biente de m ultiprogram ação no qual várias aplicações podem ser executadas concorrentem ente. U m a das responsabilidades m ais fundam entais de um sistem a operacional é determ inar qual processador executa um processo e durante quanto tem po esse processo é executado. Um program a pode conter diversos elem entos que com partilhem dados e que possam ser executados concorrentem ente. Por exem plo, um navegador Web pode conter com ponentes isolados para ler a H TM L de um a página Web, recuperar a m ídia da página (ou seja, im agens, texto e vídeo) e exibir a página apresentando seu conteúdo na ja n ela do navegador. Esses com ponentes de program a, executados independentem ente, m as que realizam seu trabalho em um espaço de m em ória com um, são cham ados threads (fluxos de execução). Tais com ponentes são discutidos no Capítulo 4, “Conceitos de thread” . N orm alm ente muitos processos com petem para usar o processador. O escalonador de processos pode basear suas decisões em diversos critérios, com o a im portância de um processo, o tempo estim ado de execução ou há quanto tempo está esperando para obter acesso ao processador. Discutirem os escalonam ento do processador no Capítulo 8, “Escalonam ento de processador” . O gerenciador de m em ória aloca m em ória para o sistem a operacional e para os processos. Com o intuito de garantir que os processos não interfiram no sistem a operacional ou uns nos outros, o gerenciador de m em ória im pede que cada processador acesse m em ória que não lhe tenha sido alocada. Q uase todos os sistem as operacionais de hoje suportam m em ória virtual, com o discutido nos capítulos 10 e 11. U m a outra função central do sistem a operacional é gerenciar os dispositivos de entrada/saída (E/S) do com putador. D ispositivos de entrada abrangem teclados, m ouses, m icrofones e scanners; entre os dispositivos de saída estão m onitores, im pressoras e alto-falantes. D ispositivos de arm azenam ento (por exem plo, discos rígidos, discos óticos regraváveis e fitas) e placas de rede funcionam com o dispositivos de entrada e saída. Q uando um processo quer acessar um dispositivo de E/S, deve em itir um a cham ada ao sistem a operacional. A quela cham ada é subsequentem ente m anuseada por um driver de dispositivo, que é um com ponente de softw are que interage diretam ente com o hardw are e em geral contém com andos e outras instruções específicas do dispositivo para realizar as operações de entrada/saída requisitadas. A m aioria dos sistemas de com putador pode arm azenar dados persistentem ente (isto é, após o com putador ter sido desligado). Com o a m em ória principal geralm ente é relativam ente pequena e perde seus dados quando a fonte de energia é desligada, são usados dispositivos secundários de arm azenam ento persistente, m ais com um ente discos rígidos. E/S por disco — um a das form as mais com uns de E/S — ocorre quando um processo requisita acesso a inform ações que estão em um dispositivo de disco. Entretanto, o arm azenam ento secundário é m uito m ais lento do que processadores e m em ória principal. O com ponente escalonador de disco de um sistem a operacional é responsável pela reordenação das requisições de E/S por disco para m axim izar o desem penho e m inim izar a quantidade de tem po que um processo espera pelas E/S por disco. Sistem as de arranjo redundante de discos independentes (R edundant A rray o f Independent D isks - RA ID ) tentam reduzir o tem po que um processo espera pela E/S por disco, utilizando vários discos ao m esm o tem po para atender às requisições de E/S. D iscutirem os algoritm os de escalonam ento de discos e sistem as RA ID no C apítulo 12, “O tim ização do desem penho de discos” . Sistemas operacionais usam sistem as de arquivo para organizar e acessar eficientem ente coleções nomeadas de dados, denom inadas arquivos e localizadas em dispositivos de armazenam ento. Conceitos de sistem as de arquivo são abordados no Capítulo 13, “Sistem as de arquivos e de bancos de dados” . Com freqüência, os processos (ou threads) cooperam para cumprir uma meta comum. Assim, muitos sistemas operacionais proporcionam com unicação entre processos (IPC) e mecanismos de sincronização para simplificar essas programações concorrentes. Comunicação entre processos habilita os processos a se comunicarem via mensagens enviadas entre eles (e entre threads); sincronização fornece estruturas que podem ser usadas para assegurar que processos (e threads) compartilhem dados adequadamente. Processos e threads são discutidos nos capítulos 3 a 8. R e r tiã o ' 1. Q uais com ponentes de sistem a operacional realizam cada um a das seguintes operações? a. Escrever no disco. b. D eterm inar qual processo será executado em seguida. c. D eterm inar em que lugar da m em ória um novo processo deve ser colocado. d. O rganizar arquivos em um disco. e. H abilitar um processo a enviar dados para outro. 2. Por que é arriscado perm itir que usuários executem livrem ente operações de leitura e escrita para qualquer região do disco? 18 S is te m a s o j^ e ra c io tu iis Reípoitài: 1) a) gerenciador de E/S; b) escalonador de processador; c) gerenciador de m emória; d) gerenciador de sistem a de arquivo; e) gerenciador de com unicação entre processos (IPC). 2) É arriscado porque os usuários poderíam , acidentalm ente ou com m á intenção, sobrescrever dados críticos (por exemplo, arquivos do sistem a operacional) ou ler inform ações vulneráveis (como docum entos confidenciais) sem autorização. 1.12.2 M etas do sistem a, operacional Usuários passaram a esperar certas características dos sistem as operacionais como: • eficiência • robustez • escalabilidade • extensibilidade • portabilidade • segurança • interatividade • usabilidade U m sistema operacional eficiente alcança alto rendimento e baixo tem po de retom o. O rendim ento m ede a quantidade de trabalho que um processador pode concluir em um certo período de tempo. Lem bre-se de que um dos papéis de um sistem a operacional é fornecer serviços a muitas aplicações. Um sistem a operacional eficiente m inim iza o tempo gasto oferecendo esses serviços (veja o quadro “Reflexões sobre sistem as operacionais, D esem penho”). Um sistema operacional robusto é tolerante a falhas e confiável — o sistem a não falhará devido a erros isolados de aplicações ou de hardware e, se falhar, ele o fará graciosam ente (isto é, m inim izando perda de trabalho e evitando danos ao hardw are do sistema). D eterm inado sistem a operacional fornecerá serviços a cada aplicação, a m enos que o hardware no qual se confie falhe. Um sistema operacional escalável é capaz de usar recursos à m edida que são acrescentados. Se um sistem a operacional não for escalável, rapidam ente chegará a um ponto em que recursos adicionais não serão utilizados totalmente. Um sistem a operacional escalável pode ajustar im ediatam ente seu grau de m ultiprogram ação. Escalabilidade é um atributo particularm ente im portante dos sistem as multiprocessadores — à m edida que são adicionados processadores ao sistema, R â f-le x õ & ço W ô Uma das m etas mais impor­ tantes de um sistema operacional é m axim izar o dese m p e nh o do sistema. Somos todos conscientes do desempenho em nossas vidas diárias. Medimos a quilometragem por litro de nosso carro, registramos vários recordes de velocidade, pro­ fessores dão notas a estudantes, funcionários recebem avaliações de desempenho de seus emprega­ dores, o desempenho de um exe­ cutivo corporativo é medido pelos lucros da empresa, o desempenho dos políticos é medido por freqüentes pesquisas de opinião com seus eleitores e assim por diante. Alto desempenho é essencial para sistemas operacionais. Toda­ o o & t a c \o \a a via, o desempenho muitas vezes está 'nos olhos de quem o vê ' — há muitos modos de classificar o desempenho de um sistema ope­ racional. Para sistemas de processa­ mento em lote, o rendimento é uma medida importante; para sistemas interativos de tempo compartilhado, os tempos de resposta rápidos são mais importantes. Por todo este livro apresenta­ mos muitas técnicas de melhoria de desempenho. Por exemplo, o C apítulo 8, "E scalon am e nto de processador", discute a alocação de tem po de processador a processos para melhorar o desempenho do sistem a m edido com o interativi­ dade e re n d im e n to . O Capítulo \$ 11, "G erenciam ento de memória virtual", examina alocação de me­ mória a processos para reduzir seus tem pos de execução. O Capítulo 12, "Otimização do desempenho do disco", focaliza a melhoria do desempenho do disco pela reordenação das requisições de E/S. No Capítulo 14, "Desempenho e pro­ jeto de processador", discutimos a avaliação de sistemas segundo diversos critérios im portantes de desempenho. Os capítulos 20 e 21 abordam questões de desempenho nos sistemas operacionais Linux e W indows XP, respectivamente. Capítulo 1 Introdução aos sistemas operacionais 19 idealm ente a capacidade de processam ento deve crescer proporcionalm ente ao núm ero de processos, em bora, na prática, isso não aconteça. M ultiprocessam ento é discutido no Capítulo 15, “G erenciam ento de m ultiprocessador” . U m sistema operacional extensível adapta-se bem a novas tecnologias e fornece capacidades de estender o sistem a operacional para executar tarefas que vão além de seu projeto original. Um sistema operacional portável é projetado de m odo tal que possa operar em muitas configurações de hardware. Portabilidade de aplicações tam bém é im portante porque desenvolver aplicações custa caro; a m esm a aplicação deve rodar em uma variedade de configurações de hardware para reduzir custos de desenvolvim ento. O sistem a operacional é crucial para conseguir esse tipo de portabilidade. U m sistema operacional seguro impede que usuários e software acessem serviços e recursos sem autorização. Proteção refere-se aos m ecanism os que im plem entam a política de segurança do sistema. Um sistema operacional interativo permite que aplicações respondam rapidamente às ações do usuário ou a eventos. Um sistema operacional utilizável é aquele que tem o potencial de atender a um a base significativa de usuários. Esses sistemas operacionais geralmente fornecem uma interface com o usuário fácil de usar. Sistemas operacionais com o Linux, Windows XP e MacOS X são caracterizados com o utilizáveis porque cada um suporta um grande conjunto de aplicações e fornece as interfaces-padrão com o usuário. Muitos sistemas operacionais experimentais e acadêmicos não suportam um grande número de aplicações nem fornecem interfaces amigáveis com o usuário e, portanto, não são considerados utilizáveis. R evu ã e 1. Q uais metas dos sistemas operacionais correspondem a cada um a das seguintes características? a. Usuários não podem acessar serviços nem inform ações sem autorização adequada. b. O sistem a operacional é executado sobre uma variedade de configurações de hardware. c. O d esem p en h o do sistem a au m en ta c o n tin u am en te q u an d o a c re sce n tad o s m em ó ria e p ro cessad o res adicionais. d. O sistem a operacional suporta dispositivos que não estavam disponíveis na época em que foi projetado. e. Falhas de hardw are não causam necessariam ente falha de sistema. 2. Com o o suporte do driver de dispositivo contribui para a extensibilidade de um sistema operacional? R e ip a itã i: 1) a) segurança; b) portabilidade; c) escalabilidade; d) extensibilidade; e) robustez. 2) Drivers de dispositivo habilitam desenvolvedores a adicionar suporte para hardw are que não existia na época em que o sistem a foi projetado. A cada novo tipo de dispositivo adicionado a um sistema, deve ser instalado um driver de dispositivo correspondente. 1.13 Arquiteturas d&sistemas operacionais Os sistem as operacionais de hoje tendem a ser com plexos, porque prestam muitos serviços e suportam um a variedade de recursos de hardw are e software (veja os quadros “Reflexões sobre sistemas operacionais, M antenha a sim plicidade” e “curiosidades”). Arquiteturas de sistemas operacionais podem ajudar projetistas a gerenciar essa com plexidade organizando com ponentes de sistem a e especificando o privilégio com que cada com ponente é executado. No projeto m onolítico, todos os com ponentes do sistema operacional estão no núcleo; no projeto de micronúcleo somente estão incluídos os componentes essenciais. Nas seções seguintes fazem os um apanhado de diversas arquiteturas im portantes (veja o quadro “Reflexões sobre sistem as operacionais, A rquitetura”). 1.13.1 Arquitetura, utOKoLUxca, O sistema operacional monolítico é a arquitetura de sistema operacional mais antiga e m ais comum. C ada componente do sistem a operacional é contido no núcleo e pode com unicar-se diretam ente com qualquer outro (sim plesm ente usando chamadas à função). O núcleo normalmente é executado com acesso irrestrito ao sistema de computador (Figura l .3). OS/360, VM S e Linux são caracterizados, em sentido amplo, com o sistem as operacionais m onolíticos.58A intercom unicação direta entre com ponentes é que tom a os sistem as operacionais monolíticos altam ente eficientes. Entretanto, porque os núcleos m onolíticos agrupam com ponentes todos juntos, é difícil isolar a fonte de problemas e de outros erros. Além disso, com o todo o código é executado com acesso irrestrito ao sistema, sistemas de núcleo m onolítico são particularm ente suscetíveis a danos provocados por códigos sujeitos a erros ou m al-intencionados. Revíião' 1. Qual a característica que define um sistem a operacional monolítico? 20 S is te m a s o p e ra c io n a is Aplicações Espaço do usuário Espaço do núcleo GM = Gerenciador de memória EP = Escalonador de processador CEP = Comunicação entre processos SA = Sistema de arquivos E/S = Gerenciador de Entrada/Saída GR = Gerenciador de rede Figuras 13 \ Arquitetura, de, sistema, operacional de, núcleo monolítico. 2. Por que sistem as operacionais m onolíticos tendem a ser eficientes? Qual a principal fragilidade dos núcleos m onolíticos? 1) Em um sistem a operacional m onolítico todos os com ponentes do sistem a operacional são contidos no núcleo. 2) Núcleos m onolíticos tendem a ser eficientes porque poucas cham adas atravessam do espaço do usuário para o espaço do núcleo. Com o todos os códigos de sistem as operacionais em núcleos monolíticos operam com acesso irrestrito ao software e hardw are do com putador, esses sistem as são particularm ente suscetíveis a danos provocados por códigos sujeitos a erros. 1.13.2 Arquitetura, m v cantadas À m edida que os sistem as operacionais tom aram -se m aiores e m ais com plexos, projetos puram ente monolíticos m ostraram -se intratáveis. A abordagem em camadas do sistem a operacional tenta resolver essa questão agrupando em camadas com ponentes que realizam tarefas sim ilares. Cada cam ada com unica-se exclusivam ente com as camadas im ediatam ente acim a e abaixo dela. Cam adas de nível m ais baixo prestam serviços às de nível m ais alto usando uma interface que oculta sua im plementação. R e f l e x õ e s g o \ s & o ^ e s < x c \o w < x \G A A tm tm ka, a, siM pU dcU cU Projetar, implementar, testar, de­ purar e manter sistemas complexos é caro. Freqüentemente projetistas de sistemas operacionais escolherão a mais simples de diversas aborda­ gens para resolver determ inado problema. Porém, às vezes, uma abordagem mais complexa pode render benefícios de desempenho ou outras melhorias que compen­ sam. Compromissos entre simpli­ cidade e desempenho são comuns na computação. Uma busca linear simples de um array é trivial para programar, mas é executada lenta­ mente em comparação a uma busca binária mais elegante e complicada. Estruturas de árvores podem ser mais complexas para trabalhar do que arrays, mas facilitam e tornam mais velozes a execução de certos tipos de inserção e supressão. Nós sempre consideramos abordagens alternativas para a solução de pro­ blemas de sistemas operacionais e desenvolvimento de estratégias de gerenciamento de recursos. À medida que ler essas discussões, você verá os compromissos entre simplicidade e complexidade. Ao ler essas soluções, talvez você opte por certas alternativas. Os sistemas com os quais trabalhará no futuro poderão demandar abordagens diferentes. Nossa filosofia é apresentar os prós e os contras das abordagens populares para ajudá-lo a preparar-se para seus próprios julgamentos quando neces­ sário em sua área de atuação. Capítulo 1 Introdução aos sistemas operacionais 21 Sistemas operacionais em camadas são mais modulares do que os monolíticos, porque a im plem entação de cada camada pode ser modificada sem exigir nenhum a modificação nas outras. Um sistem a m odular tem com ponentes autocontidos que podem ser reutilizados por todo o sistema. Cada com ponente oculta o m odo com o realiza sua tarefa e apresenta um a interface-padrão que os outros com ponentes podem usar para requisitar seus serviços. A m odularidade im põe estrutura e consistência ao sistem a operacional — muitas vezes sim plificando validação, depuração e modificação. Entretanto, em um a abordagem de cam adas, a requisição de um processo de usuário pode precisar passar por m uitas camadas antes de ser atendida. Com o é preciso invocar m étodos adicionais para passar dados de um a cam ada para a seguinte, o desem penho se degrada em com paração ao do núcleo monolítico, que pode requerer apenas um a única cham ada para atender a uma requisição similar. Além disso, com o todas as cam adas têm acesso irrestrito ao sistema, núcleos em cam adas tam bém são suscetíveis a danos causados por códigos sujeitos a erros ou m al-intencionados. O sistem a operacional TH E é um dos prim eiros exemplos de um sistem a operacional em cam adas (Figura 1.4).59 M uitos dos sistem as operacionais atuais, incluindo o W indows X P e o Linux, im plem entam um certo nível de camadas. R evu ã o ' 1. D e que m odo os sistem as operacionais em cam adas são m ais m odulares do que os sistem as operacionais m onolíticos? 2. Por que sistem as operacionais em cam adas tendem a ser menos eficientes do que os m onolíticos? Reipoitãi: 1) Em sistem as operacionais em camadas a im plem entação e a interface são separadas para cada camada, o que permite que cada um a seja testada e depurada separadam ente. Também habilita os projetistas a m udar a im plem entação de cada cam ada sem precisar modificar as outras camadas. 2) Em sistemas operacionais em camadas, podem ser necessárias diversas cham adas para se com unicar entre as cam adas, ao passo que essa sobrecarga não existe em núcleos monolíticos. 1.13.3 Arquitetura, ndcronÁcle# U m a arquitetura de sistema operacional de micronúcleo fornece somente um núm ero pequeno de serviços na tentativa de m anter o núcleo pequeno e escalável. Entre esses serviços estão, norm alm ente, gerenciam ento de m em ória de baixo nível, com unicação entre processos e sincronização básica de processos para habilitar a cooperação entre eles. Nos projetos de m icronúcleo, a m aioria dos com ponentes do sistem a operacional — com o gerenciam ento de processo, rede, sistemas de arquivo e gerenciam ento de dispositivos — é executada fora do núcleo com um nível de privilégio mais baixo (Figura | 5) 60,61.62,63 M icronúcleos exibem um alto grau de modularidade, o que os tom a extensíveis, portáveis e escaláveis.64 E mais, com o o m icronúcleo não depende de cada com ponente para ser executado, um ou mais dos com ponentes podem falhar sem causar tam bém a falha do sistem a operacional. Entretanto, essa m odularidade ocorre à custa de um m aior nível de com unicação entre m ódulos, o que pode degradar o desem penho do sistema. Em bora poucos dos sistemas operacionais populares atuais adotem o projeto de m icronúcleo, o Linux e o W indows XP, por exemplo, contêm com ponentes m odulares.65 Usuário Espaço do usuário X Aplicações do usuário Camada 4 I \ Espaço do núcleo Gerenciamento de E/S Camada 3 i \ X Interpretador de mensagem Camada 2 x Camada 1 Camada 0 I Gerenciamento de memória \ ' Alocação de processador e escalonamento de processo F igura/1.d- Camadas do sistema, operacional THE. ^ X) Q Q. $ 0) CD S is te m a s o j^ e ra c io tu iis 22 K^ A r q u ite tu r a s Exatamente com o arquitetos usam abordagens diferentes para projetar edifícios, projetistas de sistemas operacionais empregam d ife re n te s abordagens a rq u ite ­ tô n ica s para p ro je ta r s is te m a s o p e ra cio n a is. Às vezes essas abordagens são puras, no sentido de que somente uma abordagem arquitetônica é usada em todo o sistema. Em outras situações são utilizadas abordagens híbridas, que misturam as vantagens de diversos estilos arquitetônicos. A abordagem que o projetista escolher terá conseqüências monumentais sobre a implementação inicial e a evolução do sistem a operacional. Quanto mais se avançar no projeto, mais difícil ficará mudar abordagens, por isso é importante escolher a arqui­ tetura apropriada logo no início do desenvolvim ento do sistema. De modo mais geral, é muito mais fá­ cil construir o edifício corretamente da primeira vez do que modificá-lo depois de construído. Uma das abordagens arqui­ te tô n ic a s m ais com uns e m p re ­ gadas em softwares de sistemas como os de sistemas operacionais é chamada 'de camadas'. Esse tipo de software é dividido em módulos denominados camadas e cada uma delas desempenha certas tarefas. Cada camada invoca os serviços prestados pela camada abaixo dela, enquanto a implementação daquela camada fica oculta da camada aci­ ma dela. A arquitetura em camadas combina as virtudes das técnicas de engenharia de software de modularidade e de ocultação de informa­ ções para fornecer uma base sólida para a construção de sistemas de qualidade. Discutimos a abordagem de camadas do software por todo o livro, começando com uma menção histórica do sistema THE de Dijkstra (veja a Seção 1.13.2, ''Arquitetura em camadas") e prosseguindo com explanações sobre como a técnica de camadas é usada no Linux e no W indows XP, nos capítulos 20 e 21, respectivamente. Pujurtv 1.5 Arcjucteturos cU sistema operosdonal de, udcrotuíclet). ✓ R e v iiã o ' 1. Qual a diferença entre um a arquitetura em cam adas pura e um a arquitetura de m icronúcleo? 2. Com o os m icronúcleos prom ovem a portabilidade? Capítulo 1 Introdução aos sistemas operacionais 23 Reípoitài: 1) U m a arquitetura em cam adas habilita com unicação exclusivamente entre com ponentes de sistem as operacionais de cam adas adjacentes. U m a arquitetura de m icronúcleo habilita com unicação entre todos os com ponentes do sistem a via m icronúcleo. 2) O m icronúcleo não depende de um a plataform a de hardw are particular; suporte para novo hardw are pode ser fornecido carregando-se um novo módulo. 1.13A Sistem as operasioKOÂS red& &distribuídos Avanços na tecnologia de telecomunicações afetaram profundamente os sistemas operacionais. U m sistema operacional de rede habilita seus processos a acessar recursos (por exemplo, arquivos) que residem em outros computadores independentes de um a rede.66A estrutura de muitos sistemas operacionais de rede e distribuídos freqüentemente é baseada no modelo cliente/ servidor (Figura 1.6). Os com putadores-cliente dessa rede requisitam recursos — com o arquivos e tempo de processador — via protocolo de rede apropriado. Os servidores respondem com os recursos apropriados. N essas redes, projetistas de sistemas operacionais devem considerar cuidadosamente como gerenciar dados e com unicação entre computadores. Alguns sistemas operacionais são m ais ‘de rede’ do que outros. Em um am biente de rede, um processo pode ser executado no com putador no qual foi criado ou em um outro com putador da rede. Em alguns sistem as operacionais de rede, usuários podem especificar exatam ente onde seus processos são executados; em outros, o sistem a operacional é que determ ina onde os processos são executados. Por exemplo, o sistem a pode determ inar que um processo pode ser executado mais eíicientem ente em um com putador que esteja m om entaneam ente com um a carga baixa de processam ento.67 Os sistem as de arquivos de rede são um com ponente im portante dos sistem as operacionais de rede. No nível mais baixo, usuários adquirem recursos em outra m áquina conectando-se explicitamente àquela m áquina e recuperando arquivos. Sistem as de arquivos de rede de nível m ais alto habilitam os usuários a acessar arquivos rem otos com o se estes estivessem no sistem a local. Entre os exemplos de sistem as de arquivo de rede estão o NetWork File System (NFS) da Sun e os sistem as de arquivos Andrew e Coda da CM U. Sistemas de arquivos de rede são abordados detalhadam ente no Capítulo 18, “ Sistemas distribuídos e serviços Web” . UM sistema operacional distribuído é um sistem a operacional único que gerencia recursos em mais de um sistem a de computador. Sistemas distribuídos dão a ilusão de que vários com putadores com põem um único com putador de grande capacidade, de m odo que um processo pode acessar todos os recursos do sistem a independentem ente da localização do processo dentro da rede de com putadores do sistem a distribuído.68 Sistemas distribuídos muitas vezes são difíceis de implementar, porque requerem algoritm os com plicados para habilitar os processos a se com unicarem e a com partilhar Figura, 1.6 Modelo de, sistema, operacional de, rede, cliente,/serindor. 24 S is te m a s o jte ra c io tu iis dados. Exem plos de sistem as operacionais distribuídos são o Chord do M IT e o A m oeba da Vrije Universiteit (VU) em Amsterdã.69,70 Discutirem os sistemas distribuídos no Capítulo 17, “Introdução a sistem as distribuídos” . A gora que apresentam os um a série aparentem ente infindável de fatos, questões e acrônim os, passarem os à discussão dos princípios básicos de hardw are e software de com putadores no Capítulo 2, “Conceitos de hardw are e softw are”. Ret/Uão' 1. Qual a principal diferença entre sistem as operacionais de rede e distribuídos? 2. Qual a vantagem prim ordial de um sistem a operacional distribuído? 1) Um sistem a operacional de rede controla um computador, mas coopera com outros com putadores da rede. Em um sistem a operacional distribuído, um sistem a operacional controla muitos com putadores da rede. 2) A vantagem primordial é que os processos não precisam conhecer as localizações dos recursos que usam, o que sim plifica a program ação de aplicações. Isso ocorre à custa do program ador de sistemas, que deve im plem entar algoritm os com plicados para habilitar processos a se com unicarem e a com partilhar dados entre m uitos com putadores, criando a ilusão de que são um único com putador de m aior porte. Resumo H á alguns anos sistem a operacional era definido com o o software que controla o hardware, mas o panoram a dos sistem as de com putador evoluiu significativamente desde então, exigindo um a descrição mais com plicada. Para au­ m entar a utilização do hardware, foram projetadas aplica­ ções para ser executadas concorrentem ente. Entretanto, se essas aplicações não forem cuidadosam ente programadas, poderão interferir um as nas outras. O resultado é um a cam ada de software denom inada sistem a operacional que separa as aplicações (a cam ada de software) do hardware que acessam. Q uando um usuário requisita que o com putador realize um a ação (ou seja, que execute um a aplicação ou im prim a um documento), o sistema operacional gerencia o software e o hardware para produzirem o resultado desejado. Sistemas operacionais são primordialmente gerenciadores de recursos — gerenciam hardware, incluindo, processadores, memória, dispositivos de entrada/saída e dispositivos de comunicação. O sistem a operacional tam bém tem de gerenciar aplicações e outras abstrações de software que, diferentem ente do har­ dware, não são objetos físicos. Os sistem as operacionais evoluíram nos últim os 60 anos passando por diversas fases ou gerações distintas que correspondem aproxim adam ente às décadas. N a década de 40, os prim eiros com putadores eletrônicos digitais não possuíam sistem as operacionais. O s sistem as da década de 50 geralm ente executavam apenas um jo b por vez, mas usavam técnicas que facilitavam a transição entre jo b s para obter a m áxim a utilização do sistem a do com puta­ dor. U m jo b consistia em um conjunto de instruções que um program a executaria. Esses prim eiros com putadores eram cham ados de sistem as de processam ento em lote de fluxo único, porque program as e dados eram subm etidos em grupos ou lotes, sendo carregados consecutivam ente em fita ou disco. Os sistem as da d écad a de 1960 tam bém eram de processam ento em lote, m as utilizavam os recursos do c o m p u ta d o r m ais e fic ie n te m e n te , ex e c u ta n d o vário s jo b s ao m esm o tem po. Os sistem as da década de 1960 m elhoraram a utilização de recursos perm itindo que um jo b usasse o processador enquanto outros utilizavam d is­ positivos periféricos. Com essas observações em mente, projetistas de sistem as operacionais desenvolveram siste­ mas de m ultiprogram ação que gerenciavam vários jobs ao m esm o tem po, e esse núm ero era indicado pelo grau de m ultiprogram ação do sistema. Em 1964, a IBM anunciou sua fam ília de com putado­ res System /360. Os vários m odelos de com putadores 360 foram projetados para ser com patíveis com hardw are, usar o sistem a operacional O S/360 e oferecer m aior capacidade de com putação à m edida que o usuário progredia em seu uso quanto aos m odelos de séries m ais avançadas. Foram desenvolvidos sistem as operacionais m ais avançados para atender a vários usuários interativos ao m esm o tem po. D esen v o lv eram -se sistem as de tem p o co m p artilh a d o para suportar grandes núm eros de usuários interativos sim ultâneos. Sistemas de tempo real tentam fornecer um a resposta em um certo período de tempo lim itado. Os recursos de um sistem a de tem po real são freqüentem ente muito subutilizados. Para esses sistem as é m ais im portante dar uma resposta rápida quando necessário do que usar seus recursos eficientemente. O tem po de retom o — período entre a apresentação de um job e o retom o de seus resultados — foi reduzido a minutos ou até segundos. O valor dos sistem as de tempo compartilhado no suporte do desenvolvimento de programas foi dem onstrado quando o M IT usou o sistem a CTSS para desenvolver seu próprio sucessor, o M ultics. TSS, M ultics e CP/CM S incorporavam m em ória virtual, que capacita os Capítulo 1 programas a acessar mais localizações de memória do que as fornecidas pela m em ória principal que tam bém é cham ada de m em ória real ou m em ória física. Os sistemas da década de 1970 eram primordialmente multimodais de tempo compartilhado que suportavam pro­ cessamento em lotes, tempo compartilhado e aplicações de tempo real. A com putação pessoal estava em seu estágio incipiente, favorecida pelos prim eiros desenvolvim entos na tecnologia do microprocessador. As comunicações entre sistemas de computadores por todos os Estados Unidos au­ mentaram à medida que os padrões de comunicação TCP/IP do Departamento de Defesa tomaram-se amplamente usados — em especial nos ambientes de com putação militares e universitários. Problemas de segurança aumentaram à medida que volumes crescentes de informações eram transmitidos por linhas de comunicação vulneráveis. Os anos 80 representaram a década do com putador pes­ soal e da estação de trabalho. Em vez de os dados serem levados até um com putador central de grande porte para processam ento, a com putação era distribuída aos lugares onde necessário. C om putadores pessoais provaram ser relativam ente fáceis de aprender e usar, em parte por causa das interfaces gráficas com o usuário (GUI) que usavam sím bolos gráficos com o janelas, ícones e menus para faci­ litar a interação do usuário com os programas. À medida que os custos da tecnologia decresciam , a transferência de inform ações entre com putadores e redes de com putadores tomava-se mais econômica e prática. O modelo de com puta­ ção distribuída cliente/servidor dissem inou-se amplamente. Clientes são com putadores de usuários que requisitam vá­ rios serviços; servidores são com putadores que executam os serviços requisitados. A área de engenharia de softw are continuou a evoluir, com um grande im pulso dado pelo governo dos Estados Unidos que visava especialm ente a perm itir um controle mais rígido dos projetos de software do D epartam ento de Defesa. Algum as metas da iniciativa eram pôr em prática a reutilização de códigos e um m aior grau de abstração das linguagens de program ação. U m outro desenvolvim ento da engenharia de software foi a im plem entação de processos contendo m últiplos threads de instrução que seriam execu­ tados independentem ente. No final da década de 1960, a ARPA (Advanced Rese­ arch Projects Agency) colocou em prática a interconexão em rede dos principais sistem as de com putador de cerca de um a dúzia de universidades e instituições de pesquisa financiadas pela agência. A ARPA partiu para implementar o que foi apelidado de ARPAnet — a avó da Internet atual. O principal benefício da ARPAnet provou ser sua capacidade de com unicação rápida e fácil pelo que veio a ser conhecido com o correio eletrônico (e-mail). Isso vale até mesmo para a Internet de hoje, com e-m ail, m ensagem instantânea e transferência de arquivos facilitando com unicações entre centenas de m ilhões de pessoas no m undo inteiro. A A RPA net foi projetada para operar sem controle centralizado. Os protocolos (conjunto de regras) para a com unicação p ela A R PA net ficaram conhecidos com o Introdução aos sistemas operacionais 25 Transm ission Control Protocol/Intem et Protocol (TCP/IP). O TCP/IP era usado para gerenciar a com unicação entre aplicações; protocolos garantiam que m ensagens fossem encam inhadas (roteadas) adequadam ente entre aplicações e chegassem intactas. Eventualm ente o governo decidiu perm itir o acesso à Internet para propósitos comerciais. A World W ide Web (W W W ) perm ite que usuários de com putador localizem e vejam documentos m ultimídia (do­ cum entos com texto, gráficos, animações, áudio ou vídeo) sobre praticam ente qualquer assunto. Em bora a Internet te­ nha sido desenvolvida há mais de três décadas, a introdução da World W ide Web é um evento relativam ente recente. Em 1989, Tim Bem ers-Lee, do CERN (European Center for N uclear Research) com eçou a desenvolver um a tecnologia de com partilham ento de inform ações via docum entos de texto interligados (hyperlinked). Para im plem entar essa nova tecnologia, ele criou a HyperText M arkup Language (HTM L). Também im plem entou o HyperText Transfer Pro­ tocol para form ar a espinha dorsal das com unicações desse novo sistem a de inform ações de hipertexto que batizou de World W ide Web. O d esem penho do hardw are continuou a m elhorar exponencialm ente na década de 1990. C apacidade de pro­ cessam ento e armazenamento de baixo custo permitiam que usuários executassem program as com plexos e grandes em com putadores pessoais e habilitavam em presas de pequeno a m édio portes a usar essas m áquinas econôm icas para as tarefas extensivas de banco de dados e processam ento que anteriorm ente eram delegadas a sistem as de grande porte. N a década de 1990, o m ovim ento em direção à com ­ putação distribuída (ou seja, usar vários com putadores in­ dependentes para executar um a tarefa com um ) acelerou-se rapidamente. À medida que crescia a dem anda por conexões com a Internet, o suporte de sistem as operacionais para as tarefas de rede tom aram -se padronizados. Usuários em suas casas e em grandes organizações aum entavam a produtivi­ dade acessando os recursos de redes de computadores. A M icrosoft Corporation tom ou-se dominante na década de 1990. Seus sistemas operacionais Windows, que tomavam em prestado muitos conceitos popularizados pelos primeiros sistemas operacionais M acintosh (como ícones, menus e janelas), habilitavam os usuários a navegar entre m últiplas aplicações concorrentes com facilidade. A tecnologia de objeto tomou-se popular em muitas áreas da computação. Um grande número de aplicações foi escrito em linguagens de program ação orientadas a objeto com o a C++ ou a Java. Nos sistemas operacionais orientados a ob­ jeto (SOOO), objetos representam com ponentes do sistema operacional. Foram explorados conceitos orientados a objeto, com o herança e interfaces, para criar sistemas operacionais modulares m ais fáceis de m anter e am pliar do que sistemas operacionais construídos com técnicas anteriores. A maioria dos softwares comerciais é vendida como código-objeto. O código-fonte não está incluído, habilitando os fornecedores a ocultar informações proprietárias e técnicas de programação. Software livre é distribuído com o código-fonte, ab S is te m a s o j^ e ra c io tu iis permitindo que os indivíduos tenham liberdade para exami­ nar, executar, copiar, distribuir, estudar, modificar e melhorar o software. O sistema operacional Linux e o servidor Web Apache são ambos livres e de fonte aberto. Na década de 1980, Richard Stallman, um desenvolvedor de software do MIT, lançou o projeto GNU para recriar e am pliar a m aioria das ferram entas do sistem a operacional UNIX da AT&T. Stallman criou o projeto GNU porque dis­ cordava do conceito de pagar pela perm issão para utilizar software. A Open Source Iniciative (OSI) foi fundada para prom over os benefícios da program ação de fonte aberto. Softw are de fonte aberto facilita o aperfeiçoam ento de produtos de software por perm itir que qualquer um da co­ m unidade dos desenvolvedores teste, depure e aperfeiçoe aplicações. Isso aumenta a chance de que sejam descobertos e corrigidos problem as im perceptíveis que, caso contrário, poderíam provocar riscos de segurança ou erros lógicos. E tam bém indivíduos e corporações podem modificar o fonte e criar software personalizado que atenda às necessidades de um am biente particular. N a década de 1990 os sistem as operacionais tornaram se cada vez m ais am igáveis ao usuário. A s capacidades de GUI que a A pple inseriu no seu sistem a operacional M acintosh na década de 80 eram am plam ente usadas em vários outros sistem as operacionais e tom aram -se m ais sofisticadas. C apacidades plug-and-play ( ‘ligar-e-usar’) foram em butidas em sistem as operacionais, habilitando usuários a adicionar e rem over com ponentes de softw are dinam icam ente sem ter de reconfigurar m anualm ente o sistem a operacional. M iddlew are é um softw are que liga duas aplicações, m uitas vezes por um a rede e freqüentem ente entre m á­ quinas incom patíveis. É particularm ente im portante para serviços W eb, porque sim plifica a com u n icação entre várias arquiteturas. Serviços Web abrangem um conjunto de padrões relacionados que habilitam q uaisquer duas aplicações de co m p u tad o r a se co m u n icarem e tro car dados via Internet. São peças de softw are prontas para o uso na Internet. Quando o IBM PC surgiu, deu-se imediatamente origem a um a im ensa indústria de software na qual fornecedores independentes de software (ISVs) conseguiam comercializar pacotes de software para o IBM PC que eram executados no sistem a operacional M S-DOS. Se um sistem a operacional apresentar um ambiente propício ao desenvolvimento rápido e fácil de aplicações, ele e o hardw are terão m ais probabi­ lidade de sucesso no mercado. U m a vez que um a base de aplicações (a com binação do hardw are com o am biente do sistem a operacional no qual a aplicação é desenvolvida) seja amplamente estabelecida, tom a-se extremamente difícil solicitar aos usuários e desenvolvedores de software que a convertam a um am biente de desenvolvim ento de aplica­ ções com pletam ente novo, proporcionado por um sistema operacional radicalm ente diferente. Sistemas operacionais destinados a am bientes avança­ dos devem ser projetados para suportar extensas mem órias principais, hardw are de uso específico e grandes núm eros de processos. Sistemas em barcados são caracterizados por um pequeno conjunto de recursos especializados que forne­ cem funcionalidade a dispositivos com o telefones celulares e PDAs. N esses am bientes, o gerenciam ento eficiente de recursos é a chave para a construção de um sistem a opera­ cional de sucesso. Sistem as de tempo real exigem que as tarefas sejam realizadas em um período de tempo particular (muitas vezes curto). Por exemplo, o recurso de piloto autom ático de um a aeronave deve ajustar constantem ente velocidade, altitude e direção. Essas ações não podem esperar indefinidamente — e às vezes não podem esperar de jeito nenhum — que outras tarefas não essenciais sejam concluídas. Alguns sistem as operacionais devem gerenciar hardw a­ re que possa ou não existir fisicamente na máquina. U m a m áquina virtual (VM ) é uma abstração de software de um com putador que freqüentem ente é executada com o uma aplicação de usuário sobreposta ao sistem a operacional nativo. Um sistema operacional de máquina virtual gerencia os recursos providos pela m áquina virtual. Uma aplicação de m áquinas virtuais é perm itir que várias instâncias de um sistema operacional sejam executadas concorrentem ente. O utra utilização de m áquinas virtuais é a em ulação — ca­ pacidade de usar software ou hardware que representem funcionalidades de hardware ou de software que não estejam presentes no sistema. Proporcionando a ilusão de que as aplicações estão sendo executadas em hardware ou sistemas operacionais diferentes, as m áquinas virtuais prom ovem a portabilidade — a capacidade de o software ser executado em várias plataform as — e m uitos outros benefícios. Um usuário interage com o sistema operacional via uma ou mais aplicações de usuário. M uitas vezes essa interação se dá por meio de um software especial denominado interpretador de comandos (shell). O software que contém os componentes centrais do sistema operacional é denominado núcleo (kemel). Entre os componentes típicos de sistemas operacionais, estão o escalonador de processo, o gerenciador de memória, o gerenciador de E/S, o gerenciador de com u­ nicação entre processos (CEP) e o gerenciador de sistemas de arquivos. Q uase todos os sistem as operacionais m odernos su­ portam um am biente de m ultiprogram ação no qual várias aplicações podem ser executadas concorrentem ente. O núcleo gerencia a execução de processos. Com ponentes de program as, executados independentem ente, mas que usam um único espaço de m em ória para com partilhar dados, são denom inados threads. Quando um processo quer acessar um dispositivo de E/S, deve em itir ao sistem a operacional um a cham ada ao sistema. A quela cham ada ao sistem a é subseqüentem ente tratada por um driver de dispositivo — um com ponente de softw are que interage diretam ente com o hardw are — e freqüentem ente contém com andos e outras instruções específicos do dispositivo para realizar as operações de entrada/saída requisitadas. Os usuários passaram a esperar certas características de sistemas operacionais com o eficiência, robustez, escalabili- Capítulo 1 dade, extensibilidade, portabilidade, segurança e proteção, interatividade e usabilidade. E m um sistem a operacional m onolítico todos os com ­ ponentes estão no núcleo. O resultado é que qualquer com ponente pode se com unicar diretam ente com qual­ quer outro. Sistem as operacionais m onolíticos tendem a ser altam ente eficientes. U m a desvantagem dos projetos m onolíticos é que é difícil determ inar a fonte de erros im perceptíveis. A abordagem de cam adas de sistem as operacionais tenta abordar essa questão agrupando com ponentes que realizem tarefas sim ilares em cam adas. Cada cam ada com unica-se exclusivam ente com as cam adas im ediatam ente acim a e abaixo dela. Em um a abordagem de cam adas, a requisição de um processo de usuário pode precisar passar por muitas camadas antes de ser atendida. Com o é preciso invocar m étodos adicionais para passar dados e controle de um a cam ada para a seguinte, o rendim ento do sistema Introdução aos sistemas operacionais 27 decresce em com paração com o do núcleo m onolítico que pode requerer apenas um a única cham ada para atender a um a requisição similar. U m a arquitetura de sistem a operacional de m icronúcleo fornece som ente um núm ero pequeno de serviços na tenta­ tiva de m anter o núcleo pequeno e escalável. M icronúcleos exibem um alto grau de m odularidade que os tom am exten­ síveis, portáveis e escaláveis. Todavia, essa m odularidade é resultado de um m aior grau de com unicação entre m ódulos que pode degradar o desem penho do sistema. U m sistem a operacional de rede é executado em um com putador e habilita seus processos a acessar recursos, com o arquivos e processadores, em um com putador remoto. Um sistem a operacional distribuído é um sistem a opera­ cional único que gerencia recursos em m ais de um sistem a de computador. Entre as m etas de um sistem a operacional distribuído, estão desempenho transparente, escalabilidade, tolerância a falhas e consistência. Exercícios 1.1 Qual a diferença entre multiprogramação e multiprocessamento? Quais as principais motivações para o desenvolvimento de cada um? 1.2 Discuta brevemente a importância de cada um dos seguintes sistemas mencionados neste capítulo: a. MS-DOS b. CTSS c. Multics d. OS/360 e. TSS f. UNIX g- Macintosh 1.3 Quais desenvolvimentos tornaram viável o computador pessoal? 1.4 Por que não é funcional usar uma máquina virtual para um sistema rígido de tempo real? 1.5 Que papel as interfaces gráficas com o usuário desempe­ nharam na revolução do computador pessoal? 1.6 A GNU Public License (GPL) promove software livre, no sentido de ‘liberdade’. Como a GPL oferece tal liberdade? 1.7 Como a computação distribuída afetou o projeto do sistema operacional? 1.8 Quais as vantagens e desvantagens da comunicação entre computadores? 1.9 Defina, compare e aponte as diferenças para cada um destes termos: a. on-line b. tempo real c. computação interativa d. tempo compartilhado 1.10 Como o middleware e os serviços Web promovem a intero­ perabilidade? 1.11 Avalie as arquiteturas monolítica, de camadas e de micro­ núcleo segundo a. eficiência b. robustez c. extensibilidade d. segurança Projetos sugeridos 1.12 Elabore um trabalho de pesquisa sobre o sistema operacional Linux. De que modo ele suporta a doutrina do software ‘livre’ de Stallman? De que modo o Linux conflita com essa filosofia? 1.13 Elabore um trabalho de pesquisa sobre a Internet e como sua penetração afeta o projeto de sistemas operacionais. 1.14 Elabore um trabalho de pesquisa sobre o movimento do soft­ ware de fonte aberto. Discuta se todo software de fonte aberto é livre, no sentido de ‘liberdade’ e ‘preço’. Como a GPL e licenças similares promovem o software de fonte aberto? 1.15 Elabore um trabalho de pesquisa sobre a evolução dos sistemas operacionais. Não esqueça de mencionar as principais tecnologias de hardware, software e comunicação que favoreceram cada ino­ vação nos sistemas operacionais. 1.16 Elabore um trabalho de pesquisa sobre o futuro dos sistemas operacionais. 1.17 Elabore um trabalho de pesquisa fornecendo uma taxonomia completa dos sistemas operacionais passados e presentes. 1.18 Elabore um trabalho de pesquisa sobre serviços Web. Discuta as principais tecnologias que fundamentam a infra-estrutura dos serviços Web. Como a disponibilidade de serviços Web afeta o desenvolvimento de aplicações? 1.19 Elabore um trabalho de pesquisa sobre aplicações para negó­ cios críticos e para missão crítica. Discuta os atributos principais de hardware, software de comunicações e sistemas operacionais, essenciais para construir sistemas que suportem esses tipos de aplicações. 28 S is te m a s o jte ra c io tu iis 1.20 Elabore um trabalho de pesquisa sobre sistemas de máquinas virtuais. Não se esqueça de investigar o sistema operacional VM da IBM e a Java Virtual Machine da Sun (JVM). 1.21 Elabore um trabalho de pesquisa sobre sistemas operacionais e a lei. Pesquise a legislação relacionada a sistemas operacionais. 1.22 Elabore um trabalho de pesquisa sobre o impacto de sistemas operacionais nos negócios e na economia. 1.23 Elabore um trabalho de pesquisa sobre sistemas operacionais e segurança e privacidade. Não se esqueça de considerar as questões de vermes e vírus. 1.24 Elabore um trabalho de pesquisa sobre questões éticas com as quais os sistemas operacionais precisam se preocupar. Não se esqueça de tratar de questões como a utilização de sistemas de computador em situações de guerra e de ameaça à vida, vírus e vermes e outros tópicos importantes que você descobrir ao fazer a investigação para o seu trabalho. 1.25 Liste diversas tendências que estão na vanguarda dos futuros projetos de sistemas operacionais. De que maneira cada uma afe­ tará a natureza dos futuros sistemas? 1.26 Elabore um trabalho de pesquisa discutindo o projeto de siste­ mas maciçamente paralelos. Não se esqueça de comparar sistemas de multiprocessamento de grande escala (por exemplo, o super­ computador Superdome da Hewlett-Packard, que contém até 64 processadores; www.hp.com/productsl/servers/scalableservers/superdome/), com sistemas agrupados e server farms (parque de servidores), que contêm centenas de milhares de computadores pouco avan­ çados que cooperam para desempenhar tarefas comuns (veja, por exemplo, www.beowulf.org). Use as informações em www.top500.org; você encontrará uma lista dos supercomputadores mais poderosos do mundo, para determinar o tipo de tarefas que cada um desses sistemas maciçamente paralelos desempenha. 1.27 Quais as tendências que estão na vanguarda dos impressio­ nantes avanços na computação paralela? Quais desafios devem ser enfrentados por projetistas de hardware e de software antes que a computação paralela tome-se amplamente utilizada? 1.28 Elabore um trabalho de pesquisa comparando a pesquisa de sistemas operacionais Exokemel do MIT (www.pdos.lcs.mit.eclu/ exo.html) com micronúcleo Mach da CMU (www-2.cs.cmu.edu/afs/ cs.cmu.edu/project/mach/public/www/mach.htmi).71 Qual o foco primordial de cada sistema operacional? Não se esqueça de mencionar como os pesquisadores organizaram componentes como gerenciador de memória, escalonador de disco e gerenciador de processo. Ambos ou nenhum desses sistemas tomaram-se um sucesso comercial? Um desses sistemas, ou todos, influenciou os projetos de sistemas operacionais de sucesso comercial? 1.29 Por que os sistemas UNIX e baseados em UNIX continua­ ram populares nas últimas décadas? Qual o impacto do Linux nos futuros sistemas UNIX? Notas 1. “Evolution of the Intel microprocessor: 1971-2007’*, 2. www.berghell.com/whitepapers/Evolution%20of%20lntel%20Microprocessor s%201971%202007.pdf. ‘Top 500 list for november 2002”, www.top500.org/list/2002/l 1/. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. N. Weizer, “A history of operating systems”, Datamation, jan. 1981, p. 119-126. H. Goldstein, The Computer from Pascal to von Neumann. Princeton: Princeton University Press, 1972. N. Stem, From Eniac to Univac: an appraisal ofthe EckertMauchly computers. Bedford: Digital Press, 1981. C. Bashe et al., lBM ’s early computers. Cambridge: MIT Press, 1986. N. Weizer, “A history of operating systems”, Datamation, jan. 1981, p. 119-126. H. Grosch, “The way it was in 1957”, Datamation, set. 1977. P. Denning, “Virtual memory”, ACM CSUR, v. 2, nfi 3, set. 1970, p. 153-189. E. Codd, E. Lowry, E. McDonough e C. Scalzi, “Multiprogramming STRETCH: feasibility considerations”, Commu­ nications ofthe ACM, v. 2, 1959, p. 13-17. A. Critchlow, “Generalized multiprocessor and multiprogramming systems”, Proc. AFIPS, FJCC, v. 24, 1963, p. 107-125. L. Belady et al., “The IBM history of memory management technology”, IBM Journal o f Research and Development, v. 25, nc 5, set. 1981, p. 491-503. “The evolution of S/390”, www-ti.informatik.uni-tuebingen.de/os390/ arch/history.pdf. G. Amdahl, G. Blaauw e F. Brooks, “Architecture of the IBM system/360”, IBM Journal o f Research and Development, v. 8, nfl 2, abr. 1964, p. 87-101. 15. N. Weizer, “A history of operating systems”, Datamation, jan. 1981, p. 119-126. 16. B. Evans, “System/360: a retrospective view”, Annals ofthe History ofComputing, v. 8, nQ2, abr. 1986, p. 155-179. 17. G. Mealy, B. Witt e W. Clark, “The functional structure of OS/360”, IBM Systems Journal, v. 5, nfl 1,1966, p. 3-51. 18. R. Case e A. Padeges, “Architecture of the IBM system/370”, Communications o f the ACM, v. 21, nc 1, jan. 1978, p. 7396. 19. D. Gifford e A. Spector, “Case study: IBM’s system/360-370 architecture”, Communications ofthe ACM, v. 30, nQ4, abr. 1987, p. 291-307. 20. “The evolution of S/390”, www-ti.informatik.uni-tuebingen.de/os390/ arch/history.pdf. 21. D. Berlind, “Mainframe Linux advocates explain it all”, ZDNet, 12 abr. 2002, techupdate.zdnet.com/techupdate/stories/ m ain/0,14179/2860720/00.html. 22. 23. 24. 25. 26. 27. 14. 28. K. Frenkel, “Allan L. Scherr: Big Blue’s time-sharing pioneer”, Communications o f the ACM, v. 30, nc 10, out. 1987, p. 824-829. T. Harrison et al., “Evolution of small real-time IBM Com­ puter systems”, IBM Journal o f Research and Development, v. 25, nfl 5, set. 1981, p. 441-451. F. Corbato et al., The compatible time-sharing system, a programmeFs guide. Cambridge: MIT Press, 1964. P. Crisman et al. (eds.), The compatible time-sharing system. Cambridge: MIT Press, 1964. A. Lett e W. Konigsford, ‘TSS/360: a time-shared operating system”, Proceedings ofthe Fali Joint Computer Conference, AFIPS, v. 33, parte 1, 1968, p. 15-28. A. Bensoussan, C. Clingen e R. Daley, “The multics virtual memory: concepts and designs”, Communications o f the ACM, v. 15, nQ5, maio 1972, p. 308-318. R. Creasy, “The origins of the VM/370 time-sharing system”, IBM Journal o f Research and Development, v. 25, nfl 5, p. 483-490. Capítulo 1 29. K. Conrow, ‘T he CMS cookbook”, Computing and Networking Services, Kansas State University, 29 jun. 1994, 54. www.ksu.edu/cns/pubs/cms/cms-took/cms-cook.pdf. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. P. Denning, “Virtual memory”, ACM Computing Surveys, v. 2,11*3, set. 1970, p. 153-189. R. Parmelee et al., “Virtual storage and virtual machine concepts”, IBM Systems Journal, v. 11, n2 2, 1972. G. Kildall, “CP/M: a family of 8- and 16-bit operating Sys­ tems”, Byte, v. 6, n2 6, jun. 1981, p. 216-232. J. S. Quarterman e J. C. Hoskins, “Notable Computer networks”, Communications oftheACM, v. 29, n2 10, out. 1986, p. 932-971. M. Stefik, “Strategic computing at DARPA: overview and assessment”, Communications ofthe ACM, v. 28, n2 7, jul. 1985, p. 690-707. D. Comer, Intemetworking with TCP/IP: principies, protocols, and architecture. Englewood Cliffs, NJ: Prentice Hall, 1988. J. Martin e K. K. Chapman, Local area networks: architectures and implementations. Englewood Cliffs, NJ: Prentice Hall, 1989. R. Metcalfe e D. Boggs, “Ethernet: distributed packet switching for local Computer networks”, Communications ofthe ACM, v. 19, n* 7, jul. 1976. E. Balkovich, S. Lerman e R. Parmelee, “Computing in higher education: the Athena experience”, Computer, v. 18, n2 11, nov. 1985, p. 112-127. C. Zmoelnig, “The graphical user interface, time for a paradigm shift?”, 30 ago. 2001, www.sensomotic.com/chz/gui/ 55. 56. 57. D. Engelbart, “Who we are. How we think. What we do”, 24 jun. 2003, www.bootstrop.org/index.html. 41. E. Martin, ‘The context of STARS”, Computer, v. 16, n2 11, nov. 1983, p. 14-20. 42. G. Moore, “Cramming more components onto integrated circuits”, Electronics, v. 38, n2 8, 19 abr. 1965. 43. “One trillion-operations-per-second”, Intel Press Release, 17 dez. 1996, www.intel.com/pressroom/archive/releoses/cnl21796.htm. 44. B. Mukherjee, K. Schwan e P. Gopinath, “A survey of multiprocessor operating Systems”, Geórgia Institute of Technology, 5 nov. 1993, p. 2. 4 5 . “Microsoft timeline”, www.microsoft.com/museum/mustimeline.mspx. 46. R. Lea, P. Armaral e C. Jacquemot, “COOL-2: An object oriented support platform built above the CHORUS Microkemel”, Proceedings o f the International Workshop on Object Orientation in Operating Systems 1991, out. 1991. 47. A. Weiss, “The politics of free (software)”, netWorker, set. 2001, p. 26. 4 8 . “The GNU manifesto”, www.delorie.com/gnu/docs/GNU/GNU>. 49. A. Weiss, “The politics of free (software)”, netWorker, set. 2001, p. 27. 50. A. Weiss, “The politics of free (software)”, netWorker, set. 2001, p. 27-28. 51. M. Ricciuti, “New Windows could solve age old format puzzle — at a price”, CNet, 13 mar. 2002, news.com.com/20091017-857509.html. 52. P. Thurrott, “Windows ‘longhom’ FAQ”, Paul ThurrotPs Super-Site fo r Windows, 6 out. 2 0 0 3 , www.winsupersite.com/faq/ longhom.asp. 53. M. D. Cannon et al., “A virtual machine emulator for per­ formance evaluation”, Communications o f the ACM, v. 23, n2 2, fev. 1980, p. 72. 29 M. D. Cannon et al., “A virtual machine emulator for per­ formance evaluation”, Communications ofthe ACM, v. 23, n2 2, fev. 1980, p. 72. “VMware: simplifying Computer infrastructure and expanding possibilities”, www.vmware.com/company/. M. D. Cannon et al., “A virtual machine emulator for per­ formance evaluation”, Communications ofthe ACM, v. 23, n2 2, fev. 1980, p. 73. “Shell”, whatis.com, www.searchsolaris.techtarget.com/sDefinition/ 0„sidl 2_gd212978,00.html. 58. 59. 60. 61. 62. 63. history.html. 40. Introdução aos sistemas operacionais 64. 65. 66. 67. 68. B. Mukherjee, K. Schwan e P. Gopinath, “A survey of multiprocessor operating Systems”, Geórgia Institute o f Technology (GlT-CC-92/0), 5 nov. 1993, p. 4. E. W. Dijkstra, ‘The structure of the ‘THE’-multiprogramming system”, Communications oftheACM, v. 11, n25, maio 1968, p. 341-346. N. M. Kamik e A. R. Tripathi, ‘Trends in multiprocessor and distributed operating Systems”, Journal o f Supercomputing, v. 9, n2 1/2, 1995, p. 4-5. B. Mukherjee, K. Schwan e P. Gopinath, “A survey of mul­ tiprocessor operating system Kemels”, Geórgia Institute o f Technology (GIT-CC-92/0), 5 nov. 1993, p. 10. D. S. Miljocic, F. Douglis, Y. Paindaveine, R. Wheeler e S. Zhou, “Process migration”, ACM Computing Surveys, v. 32, n2 3, set. 2000, p. 263. J. Liedtke, ‘Toward real Microkemels”, Communications o fth e ACM, v. 39, n2 9, set. 1996, p. 75, e T. Camp e G. Oberhsause, “Microkemels: a submodule for a traditional operating Systems course”, Communications o f the ACM, 1995, p . 155. J. Liedtke, ‘Toward real Microkemels”, Communications o fth e ACM, v. 39, n2 9, set. 1996, p. 75, e T. Camp e G. Oberhsause, “Microkemels: a submodule for a traditional operating Systems course”, Communications o f the ACM, 1995, p. 155. D. S. Miljocic, F. Douglis, Y. Paindaveine, R. Wheeler e S. Zhou, “Process migration”, ACM Computing Surveys, v. 32, n2 3, set. 2000, p. 263. A. S. Tanenbaum e R. V. Renesse, “Distributed operating Systems”, Computing Surveys, v. 17, n2 4, dez. 1985, p. 424. A. S. Tanenbaum e R. V. Renesse, “Distributed operating Systems”, Computing Surveys, v. 17, n2 4, dez. 1985, p. 424. G. S. Blair, J. Malik, J. R. Nicol e J. Walpole, “Design issues for the COSMOS distributed operating system”, Proceedings from the 1988 ACM SIGOPS European Workshop, 1988, p. 1- 2. 69. “MIT LCS parallel and distributed operating systems”, 2 jun. 2 0 0 3 , www.pdos.lcs.mit.edu. 70. “Amoeba WWW home page”, abr. 1998, www.cs.vu.nl/pub/ amoeba/. 71. D. R. Engler, M. F. Kaashoek e J. OToole Jr., “Exokemel: an operating system architecture for application-level resource management,” SIGOPS ‘95, dez. 1995, p. 252. CoKcdtds dekardware Agora,! Agora,!”,gritou, a, Kainka,. “Mais depressa,! Mais depressa,!” Lewis Carroll Conquistar sem, risco é, triunfar sem,glória,. Pierre Corneille Nossa, tnda, é, desperdiçada, em, detalhes... Simplifique,, simplifique,. Henry Thoreau Oh, sorta, simplicidade,! John Huss (Últimas palavras, na fogueira) O b je tiv o s Este capítulo apresenta: • Os componentes de hardware que devem ser gerenciados por um sistema operacional. • Como o hardware evoluiu para suportar funções de sistemas operacionais. • Como otimizar o desempenho de vários dispositivos de hardware. • O conceito de interface de programação de aplicação (API). • O processo de compilação, ligação e carregamento. C u fú tu lo 2 C o n ce ito s d e , k a rd w a re , e, s o ftw a re . 31 2.1 Introdução Os com putadores hoje perm item que usuários acessem a Internet, consultem páginas Web, apresentem gráficos e vídeo, ouçam m úsicas, joguem — e muito mais. Com putadores pessoais e profissionais aum entam a produtividade gerenciando grandes quantidades de dados, fornecendo ferram entas de desenvolvim ento de aplicações e apresentando um a interface intuitiva para autoria de conteúdo. Com putadores em rede coordenam -se para executar enorm es quantidades de cálculos e de transações por segundo. No m ercado da com putação móvel, telefones celulares arm azenam números de telefones, enviam e recebem textos de m ensagens e até produzem fotos e vídeo. Todos esses com putadores contêm vários tipos de hardware e software e são gerenciados por sistem as operacionais. Com o o sistem a operacional é prim ariam ente um gerenciador de recursos, seu projeto deve estar intim am ente ligado aos recursos de software e hardware que gerencia; entre os quais estão processadores, memória, armazenamento secundário (discos rígidos), outros dispositivos de E/S, processos, threads, arquivos, bancos de dados e assim por diante. À m edida que os com putadores evoluem, os sistemas operacionais devem se adaptar às tecnologias em ergentes de hardw are e software e m anter a com patibilidade com uma base já instalada de hardware e software mais antigos. N este capítulo apresentarem os conceitos de hardw are e software. Revuãa 1. Liste alguns recursos com uns de hardw are e software gerenciados por sistemas operacionais. 2. Liste os tipos de dados referidos nesta introdução. Reipoiícu: 1) Processadores, memória, dispositivos de arm azenam ento secundário e outros, processos, threads, arquivos e bancos de dados. 2) Páginas Web, gráficos, vídeo, música, dados de jogos, dados de escritório, conteúdo, dados de transações, números de telefones celulares, mensagens de texto, fotos, dados na memória, dados em arm azenam ento secundário, dados de entrada ou saída por dispositivos de E/S e dados processados por processadores. 2.2 Evolução de, dispositivos de, hardware, Toda vez que o desenvolvim ento tecnológico perm itiu m aiores velocidades de com putação, essas novas capacidades foram im ediatam ente absorvidas pelas exigências de recursos de com putação feitas por aplicações m ais am biciosas. A com putação parece ser um recurso inesgotável. Problemas ainda mais interessantes esperam pela disponibilidade de sistemas de com putação cada vez mais poderosos, com o previsto pela lei de M oore (veja no site deste livro: “Biografia — G ordon M oore e Lei de M oore”). É um a situação com o a ‘do ovo e da galinha’. São as dem andas crescentes por aplicações que forçam a evolução da tecnologia de com putação ou são os avanços dessas tecnologias que nos tentam a im aginar aplicações novas e inovadoras? Inicialm ente, a programação de sistemas, que implicava escrever códigos para realizar gerenciam ento de hardware e fornecer serviços a program as, era relativam ente direta porque o sistem a operacional gerenciava um núm ero pequeno de program as e de recursos de hardware. Sistemas operacionais facilitam a programação de aplicações pelo fato de os desenvolvedores poderem escrever softwares que requisitem serviços e recursos ao sistema operacional para executar tarefas (por exemplo, editar textos, carregar páginas Web ou processar folhas de pagam ento), sem precisar escrever código para realizar o gerenciam ento do dispositivo. À m edida que o núm ero de fabricantes de hardw are e dispositivos proliferava, sistem as operacionais tom avam -se mais com plexos. Para facilitar a program ação de sistemas e m elhorar a extensibilidade, a m aioria dos sistemas operacionais é escrita para ser independente da configuração de hardware particular de um sistema. Sistem as operacionais usam drivers de dispositivos, muitas vezes fornecidos pelos fabricantes de hardware, para realizar operações de E/S específicas dos dispositivos. Isso habilita o sistem a operacional a suportar um novo dispositivo usando apenas o driver de dispositivo apropriado. N a verdade, drivers de dispositivos representam um a parte tão integrada aos sistem as de hoje, que com preendem aproxim adam ente 60% do código-fonte do núcleo do Linux.1 M uitos com ponentes de hardware foram projetados para interagir com o sistem a operacional de um modo que facilita a extensibilidade do próprio sistema. Por exemplo, dispositivos plug-and-play identificam-se a si mesm os para o sistem a operacional quando são conectados ao com putador (veja a Seção 2.4.4, “Plug and play”). Isso habilita o sistem a operacio­ nal a selecionar e usar um driver de dispositivo apropriado com pouca ou nenhum a interação do usuário, simplificando a instalação de um novo dispositivo. Sob a perspectiva do usuário, dispositivos adicionados ao sistem a estão prontos para serem usados quase imediatamente. As discussões sobre hardw are nas próxim as seções concentram -se em com putadores de uso geral (com putadores e servidores pessoais) — com putadores específicos, com o os usados em telefones celulares e carros estão fora do escopo deste livro. Discutirem os os com ponentes com uns de hardw are encontrados em sistem as de com putador típicos e, então, 32 lis te m o s o p e ra c io n a is FUjura, Z. 1 1Número de, transistores plotado contra, o tempo para,processadores Intel} focalizarem os os com ponentes de hardw are projetados especificam ente para suportar a funcionalidade do sistem a opera­ cional. Rcviião' 1. Por que projetar sistem as operacionais é mais difícil hoje do que há 50 anos? 2. Com o drivers e interfaces do tipo plug-and-play facilitam a extensibilidade de sistem as operacionais? R e ip a itã i: 1) Os sistemas operacionais de 50 anos atrás gerenciavam um número pequeno de programas e dispositivos de hardware. Os sistemas operacionais atuais norm alm ente gerenciam um grande núm ero de program as e um conjunto de dispositivos de hardware que varia de um com putador para outro. 2) Drivers liberam o projetista de sistemas operacionais dos detalhes da interação com dispositivos de hardware. Sistemas operacionais podem suportar novo hardw are usando apenas o driver de dispositivo apropriado. D ispositivos plug-and-play habilitam sistem as operacionais a identificar facilm ente os recursos de hardware de um computador, o que facilita a instalação de dispositivos e seus drivers correspondentes. Sob a perspectiva do usuário, um dispositivo está pronto para ser usado quase im ediatam ente após sua instalação. 2.3 Componentes de, hardware O hardw are de um com putador consiste em seus dispositivos físicos — processador(es), m em ória principal e disposi­ tivos de entrada/saída. As subseções seguintes descrevem com ponentes de hardw are que um sistem a operacional gerencia para atender às necessidades de com putação de seus usuários. 23.1 PUücas[triHxufxus Com putadores dependem das interações entre muitos dispositivos de hardw are para satisfazer aos requisitos do sis­ tema. Para habilitar a com unicação entre dispositivos diferentes, com putadores são equipados com uma ou m ais placas Cafútido 2 Conceitos de, kardware, e, software, 33 de circuito impresso (P rinted Circuit Board — PCB). Uma PCB é um com ponente de hardw are que fornece conexões elétricas entre dispositivos em vários lugares da placa. A placa principal (tam bém denom inada placa-mãe), a PCB central de um sistema, pode ser im aginada com o a espinha dorsal de um computador. A placa principal fornece encaixes nos quais outros com ponentes — com o o processador, m e­ m ória principal e outros dispositivos de hardw are — são inseridos. Esses encaixes fornecem acesso às conexões elétricas entre os vários com ponentes de hardware e habilitam os usuários a personalizar a configuração de seus com putadores adi­ cionando e rem ovendo dispositivos dos encaixes. A placa principal é um dos quatro com ponentes de hardware requeridos para executar instruções em um com putador de uso geral. Os outros três são o processador (Seção 2.3.2 “Processadores”), a m em ória principal (Seção 2.3.5 “M em ória principal”) e o arm azenam ento secundário (Seção 2.3.6 “A rm azenam ento secundário”). Os fios m etálicos tradicionais são muito grossos para estabelecer o grande núm ero de conexões elétricas entre com po­ nentes nos sistem as atuais. Assim , placas principais norm alm ente consistem em diversas cam adas extrem am ente delgadas de silício contendo conexões elétricas m icroscópicas denom inadas pistas que servem com o canais de com unicação e dão conectividade à placa. Um grande conjunto de pistas form a um canal de com unicação de alta velocidade conhecido com o barramento (bus). Grande parte das placas principais inclui diversos chips de com putador para realizar operações de baixo nível. Por exemplo, placas principais contêm, normalm ente, um chip de sistema básico de entrada/saída (Basic Input/O utput System - BIOS) que arm azena instruções para a iniciação e gerenciam ento do hardw are básico. O BIOS tam bém é responsável por carregar na m em ória a porção inicial do sistem a operacional denom inada autocarregamento (bootstrapping)(veja a Seção 2.4.3, “A utocarregam ento” . Depois de o sistem a operacional ter sido carregado, ele pode usar o BIOS para se co­ m unicar com o hardw are de um sistem a para executar operações de E/S de baixo nível (isto é, básicas). Placas principais tam bém contêm chips denom inados controladores que gerenciam a transferência de dados nos barram entos da placa. Um conjunto de chips (chipset) é a coleção de controladores, co-processadores, barram entos e outros com ponentes de hardware integrados à placa principal que determ inam as capacidades de hardw are do sistem a (por exemplo, que tipos de processadores e m em órias são suportados). Uma tendência recente no projeto de placas principais é integrar à PCB com ponentes de hardware de grande capacidade. Tradicionalm ente, m uitos deles eram inseridos em encaixes e em placas de expansão (add-on cards). M uitas das placas principais de hoje contêm chips que executam processam ento gráfico, trabalho em rede e operações de RAID (Redundant Array o f Independent Discs). Esses dispositivos embutidos reduzem o custo geral do sistem a e contribuem significativa­ m ente para a forte e contínua dim inuição dos preços dos com putadores. U m a desvantagem é que estão perm anentem ente ligados à placa principal e não podem ser substituídos facilmente. R e v U ã fy 1. Qual a função prim ária da placa principal? 2. Por que o BIOS é crucial para sistem as de com putador? 1) A placa principal serve com o espinha dorsal para a com unicação entre com ponentes de hardware, perm itindo que se com uniquem via conexões elétricas da placa. 2) O BIOS executa a iniciação e o gerenciam ento do hardw are básico e carrega o com ponente inicial do sistem a operacional na m emória. O BIOS tam bém fornece instruções que habilitam o sistem a operacional a com unicar-se com o hardw are do sistema. 2 3 .2 Processadores Um processador é um com ponente de hardw are que executa um fluxo de instruções em linguagem de máquina. Pro­ cessadores podem se apresentar sob diversas form as em com putadores, por exemplo, um a unidade central de proces­ samento (Central Processing Unit - CPU), um co-processador gráfico ou processador de sinais digitais (Digital Signal Processor — DSP). Uma CPU é um processador que executa as instruções de um programa; um co-processador, com o um processador gráfico ou processador de sinais digitais, é projetado para executar eficientem ente um conjunto de instruções de finalidade especial (com o as transform ações 3D). E m sistem as em barcados, os processadores podem realizar tarefas específicas com o converter um sinal digital para um sinal de áudio analógico em um telefone celular — um exemplo de DSP. N a qualidade de um processador primário no sistema, um a CPU executa o grosso das instruções, mas pode aum entar a eficiência enviando tarefas de com putação intensa a um co-processador especificam ente projetado para executá-las. Em todo este livro usaremos o term o ‘processador’ ou ‘processador de uso geral’ quando nos referirm os à CPU. As instruções que um processador pode executar são definidas por seu conjunto de instruções. O tam anho de cada instrução, ou comprimento da instrução, pode ser diferente entre arquiteturas e dentro de cada arquitetura — alguns 34 S U tw u is o jte ra à o fu iti processadores com portam instruções de vários tamanhos. A arquitetura do processador tam bém determ ina a quantidade de dados com a qual se pode trabalhar de uma só vez. Por exemplo, um processador de 32 bits m anipula dados em unidades distintas de 32 bits. Processadores modernos executam muitas operações de gerenciam ento de recursos no hardw are para m elhorar o desem penho. Entre elas, estão suporte para a m em ória virtual e interrupções de hardw are — dois conceitos im portantes discutidos m ais adiante neste livro. A despeito da variedade de arquiteturas de processadores, há diversos com ponentes presentes em quase todos os processadores contem porâneos, entre eles a unidade de busca de instrução, previsor de bifurcação, unidade de execução, registradores, caches e um a interface de barram ento (Figura 2.2). A unidade de busca de instrução carrega instruções na m em ória de alta velocidade denom inada registradores de instruções, para que o processador possa executá-las rapida­ mente. A unidade de decodifícação de instrução interpreta a instrução e passa a entrada correspondente para a unidade de execução executá-la. A parte principal da unidade de execução é a unidade de lógica e aritmética — U L A (Arithmetic and Logic Unit - ALU) que executa operações básicas de aritm ética e lógica, com o adição, m ultiplicação e com parações lógicas (note que o form ato em ‘V ’ da ALU é com um em diagram as de arquitetura). A interface de barram ento perm ite que o processador interaja com a m em ória e com outros dispositivos do sistema. Com o os processadores norm alm ente funcionam em velocidades muito m ais altas do que a m em ória principal, eles contêm m em ória de alta velocidade denom inada cache que arm azena cópias de dados na m em ória principal. Os caches aum entam a eficiência do processador habilitando acesso rápido a dados e instruções. Com o os caches de alta velocidade são signi­ ficativamente mais caros do que a m em ória principal, tendem a ser relativam ente pequenos. Caches são classificados em níveis — Nível 1 (L l) é o cache mais rápido e mais caro e está localizado no processador. O cache de Nível 2 (L2), que é m aior e m ais lento do que o L l, com um ente está localizado na placa principal m as, cada vez mais está sendo integrado ao processador para m elhorar o desem penho.3 Registradores são mem órias de alta velocidade localizadas em um processador que guardam dados para uso imediato pelo processador. Para que um processador possa trabalhar com os dados, estes devem ser colocados em registradores. A rm azenar instruções de processador em qualquer outro tipo m ais lento de m em ória seria ineficiente, porque o processa­ dor ficaria ocioso enquanto esperasse pelo acesso aos dados. Registradores são conectados ao circuito do processador e localizados fisicamente próxim o às unidades de execução, o que faz que o acesso a eles seja m ais rápido do que o acesso ao cache L l. O tam anho dos registradores é determ inado pelo núm ero de bits sobre o qual o processador pode trabalhar Unidade de execução Interface de barramento PujurOs 2.2 | CcuiponmUí do procetsaAor. Ü L jú tu lo 2 C o n ce ito s d e , k a rd w a re , e, s o ftw a re , 35 de um a só vez. Por exemplo, um processador de 32 bits pode arm azenar 32 bits de dados em cada registrador. Hoje, a m aioria dos processadores de com putadores pessoais são de 32 bits; processadores de 64 bits estão tom ando-se cada vez mais populares.4 Cada arquitetura de processador fornece um núm ero diferente de registradores, e cada registrador atende a um a fina­ lidade diferente. Por exemplo, o processador Pentium 4 da Intel fornece 16 registradores de execução de programa. Caracteristicam ente, m etade desses registradores é reservada para uso por aplicações para acesso rápido a valores de dados e ponteiros durante a execução. Esses registradores são denom inados registradores de propósito geral. O processador do PowerPC 970 da IBM (usado nos com putadores G5 da Apple) contém 32 registradores de uso geral. Os outros registradores (conhecidos com o registradores de controle) arm azenam inform ações específicas de sistema, por exemplo, o contador de program a que o processador usa para determ inar a próxim a instrução a executar.5 Revíião' 1. Qual a diferença entre um a CPU e um co-processador? Com o um sistem a poderia se beneficiar de CPUs múltiplas? Com o um sistem a poderia se beneficiar de co-processadores múltiplos? 2. Q uais aspectos de um sistem a são especificados por um a arquitetura de processador? 3. Por que o acesso à m em ória do registrador é m ais rápido do que o acesso a qualquer outro tipo de memória, incluindo o cache L l? 1) Uma CPU executa instruções em linguagem de máquina; um co-processador é otim izado para realizar instruções de uso especial. CPU s m últiplas habilitariam um sistem a a executar m ais do que um program a por vez; co-processadores m últiplos poderíam m elhorar o desem penho executando processam ento em paralelo com um a CPU. 2) A arquitetura de um a CPU especifica o conjunto de instruções, o suporte à m em ória virtual e a estrutura de interrupção do computador. 3) Registradores são conectados ao circuito do processador e localizados fisicamente próxim o das unidades de execução. 2.3.3 "Relógios O tem po do com putador geralm ente é medido em ciclos, tam bém denom inados pulsos. O term o ciclo se refere a um a oscilação com pleta de um sinal elétrico fornecido pelo gerador de relógio do sistema. O gerador de relógio estabelece a cadência de um sistem a de com putador de m odo m uito sem elhante a um m aestro de orquestra. Especificamente, o gerador de relógio determ ina a freqüência com a qual os barram entos transferem dados, com um ente m edida em ciclos por segundo, ou hertz (Hz). Por exemplo, o barramento frontal {Frontside Bus - FSB) que conecta processadores a m ódulos de memória funciona caracteristicam ente a várias centenas de megahertz (MHz; um m egahertz é igual a um m ilhão de hertz). G rande parte dos processadores de com putadores de m esa m odernos executa a velocidades m áxim as de centenas de m egahertz (M Hz) ou até m esm o a vários bilhões de hertz ou gigahertz (G H z), o que m uitas vezes é m ais rápido do que o barram ento frontal.6 Processadores e outros dispositivos geram velocidades derivadas m ultiplicando ou dividindo a velocidade do barram ento frontal. Por exem plo, um processador de 2 G H z com um barram ento frontal de 200 M H z usa um m ultiplicador de 10 para gerar seus ciclos; um a placa de som de 66 M H z usa um divisor de 2,5 para gerar seus ciclos. Retfião' 1. (V/F) Todos os com ponentes de um sistem a funcionam na m esma velocidade de relógio. 2. Q uais problem as podem surgir se um com ponente em um barram ento tiver um m ultiplicador extrem am ente alto e um outro com ponente no m esm o barram ento tiver um divisor extrem am ente alto? 1) Falso. Dispositivos norm alm ente usam um m ultiplicador ou um divisor que define sua velocidade em relação à velo­ cidade do barram ento frontal. 2) Podem ocorrer engarrafam entos, porque um com ponente com um divisor alto funcionará a um a velocidade m uito m ais lenta do que um dispositivo com m ultiplicador alto. Um dispositivo de m ultiplicador alto que depende de inform ações de um dispositivo de divisor alto será obrigado a esperar. 2.3.4 Hierarcjuàv cüv mencóruL O tam anho e a velocidade da m em ória são lim itados pelas leis da física e da econom ia. Q uase todos os dispositivos eletrônicos transferem dados usando elétrons que passam por pistas de PCBs. H á um lim ite para a velocidade com que os elétrons podem viajar; quanto mais com prido o fio entre dois term inais, m ais tempo dem orará a transferência. A lém disso, S U tw u is o jte ra à o tu u s 36 é proibitivam ente caro equipar processadores com grandes quantidades de m em ória que possam atender às requisições de dados à m esm a (ou próxima) velocidade do processador. O com prom isso custo/desem penho caracteriza a hierarquia da memória (Figura 2.3). A m em ória m ais veloz e mais cara está no topo e caracteristicam ente tem pequena capacidade. A m em ória mais lenta e menos cara está na base e com um ente tem grande capacidade. Note que o tam anho de cada bloco representa o modo com o a capacidade aum enta para m em órias m ais lentas, mas a figura não está desenhada em escala. Registradores com põem a m em ória m ais veloz e m ais cara de um sistem a — operam à m esm a velocidade dos proces­ sadores. Velocidades de m em órias cache são medidas conform e sua latência — o tem po requerido para transferir dados. Latências são m edidas em nanossegundos ou ciclos de processador. Por exemplo, o cache L I de um processador Intel Pentium 4 opera com um a latência de dois ciclos de processador.7 Seu cache L2 opera com um a latência de aproxim ada­ m ente 10 ciclos. Em muitos dos processadores atuais, os caches L I e L2 são integrados ao processador para que possam explorar as interconexões de alta velocidade do processador. Caches L I costum am arm azenar dezenas de kilobytes de dados, enquanto caches L2 com um ente arm azenam centenas de kilobytes ou vários megabytes. Processadores avançados podem conter um terceiro nível de cache de processador (denom inado cache L3) que é mais lento do que o L2, porém m ais rápido do que a m em ória principal. Em seguida na hierarquia vem a memória principal — tam bém cham ada de memória real ou memória física. A m em ória principal introduz latência adicional, porque os dados têm de passar através do barram ento frontal que norm al­ m ente opera a um a fração das velocidades do processador. A m em ória principal nas arquiteturas de hoje exibem latências de dezenas ou centenas de ciclos de processador.8 Os tam anhos das m em órias principais de uso geral atuais vão de cen­ tenas de m egabytes (PCs) a dezenas ou centenas de gigabytes (servidores avançados). A m em ória principal é discutida na Seção 2.3.5, “M em ória principal” e no Capítulo 9, “Organização e gerenciam ento da m em ória real”. Registradores, caches e mem órias principais são, tipicam ente, meios voláteis, portanto seus dados desaparecem quando o fornecim ento de energia elétrica é interrompido. O disco rígido e outros dispositivos de arm azenam ento com o CDs, DVDs e fitas estão entre as menos dispendiosas e m ais lentas unidades de arm azenam ento de um sistem a de computador. As latências do arm azenam ento em disco são norm alm ente m edidas em m ilissegundos, em geral um m ilhão de vezes mais lentas do que as latências do cache do pro­ cessador. Em vez de perm itir que o processador fique ocioso enquanto espera dados do arm azenam ento secundário, o sistem a operacional norm alm ente executa um outro processo para m elhorar a utilização do processador. U m a vantagem primordial dos dispositivos de arm azenam ento secundário é que eles têm grande capacidade, muitas vezes centenas de gigabytes. U m a outra vantagem do arm azenam ento secundário é que os dados são guardados em um meio persistente, portanto são preservados quando se retira a fonte de energia do dispositivo. Projetistas de sistem as devem equilibrar o Latência (em ciclos do processador) 0 J Z t 2 -3 SRAM ~ 10 SRAM Registradores Cache L1 Cache L2 DRAM ~ 30 ~ 106 FujUrã/2.3 Hierasíjuiosda utemóruv. DDR Rambus SDRAM Disco rígido Fita CDs DVDs Memória principal Armazenamentos secundário e terciário C & fú tu J o 2 C o n ce ito s d e , k a rd w a re , e, s o ftw a re , 37 custo e o desem penho de vários dispositivos de arm azenam ento para atender às necessidades dos usuários (veja o quadro “Reflexões sobre sistem as operacionais, Caching”). Revuão' 1) Qual a diferença entre meios de arm azenam ento voláteis e persistentes? 2) Por que a hierarquia da m em ória adota um form ato piram idal? R e ifjo iíã i: 1) M eios voláteis perdem seus dados quando o com putador é desligado, enquanto meios persistentes os retêm. Em geral, o arm azenam ento volátil é mais rápido e m ais caro do que o arm azenam ento persistente. 2) Se um meio de arm azenam ento for menos dispendioso, os usuários poderão com prar em m aior quantidade; assim, o espaço de arm azenam ento aumenta. 2.3.5 M em ória/pvuuxpal M em ória principal consiste em memória volátil de acesso aleatório (Random A ccess M em ory - RAM); ‘aleatório’ no sentido de que os processos podem acessar localizações de dados em qualquer ordem. Ao contrário, as localizações de dados em um meio de arm azenam ento seqüencial (por exem plo, fita) devem ser lidas em seqüência. D iferentem ente de fitas e discos rígidos, as latências da m em ória para cada endereço da m em ória principal são essencialm ente iguais. A form a m ais com um de RAM é a RAM dinâmica (DRAM), que requer que um circuito de renovação leia perio­ dicam ente (algumas vezes a cada m ilissegundo) o conteúdo, ou os dados serão perdidos. Isso não acontece com a RAM estática (SRAM) que não precisa ser renovada para m anter os dados que armazena. A SRAM , com um ente em pregada em caches de processador, é tipicam ente m ais rápida e mais cara do que a DRAM . Um objetivo im portante dos fabricantes de DRAM s é reduzir a diferença entre a velocidade do processador e a ve­ locidade de transferência da memória. M ódulos de m em ória são projetados para m inim izar a latência do acesso a dados dentro do m ódulo e m axim izar o núm ero de vezes por segundo que os dados são transferidos. Essas técnicas reduzem a latência geral e aum entam a largura de banda — a quantidade de dados que pode ser transferida por unidade de tempo. À m edida que os fabricantes desenvolvem novas tecnologias de m emória, a velocidade e a capacidade da m em ória tendem a aumentar, e o custo por unidade de arm azenam ento tende a diminuir, segundo a Lei de Moore. Retidão1) Com pare m em ória principal e disco em term os de tem po de acesso, capacidade e volatilidade. 2) Por que a m em ória principal é denom inada m em ória de acesso aleatório? Todos usamos c a c h in g n a nossa vida real. De modo geral, um c a c h e é um lugar para armazenar provisões que podem ser acessadas rapida­ mente. Esquilos armazenando bolotas (frutos do carvalho) enquanto se preparam para o inverno é uma forma de caching. Nós guardamos lápis, canetas, grampos, fitas e cli­ pes nas gavetas de nossas mesas de trabalho para poder ter acesso rápido a eles quando precisarmos (em vez de ter de ir buscá-los no armário de suprimentos). Sistemas operacionais empregam muitas téc­ nicas de caching, como caching de dados e instruções de um processo para acesso rápido em memórias ca­ che de alta velocidade, e caching de dados de discos na memória princi­ pal para acesso rápido enquanto um programa está em execução. Projetistas de sistemas opera­ cionais devem ser cuidadosos ao usar caching, porque em um sis­ tema de computador os dados em cache são uma cópia dos dados cujo original é mantido em um nível mais baixo da hierarquia da memória. A cópia em cache é usualmente aquela na qual as mudanças são feitas em primeiro lugar; desse modo, rapida­ mente, pode ficar fora de sincronia com os dados originais, causando inconsistência. Se um sistema vier a falhar quando o cache contiver dados atualizados e o original não, os dados modificados poderão ser perdidos. Portanto, sistemas ope­ racionais copiam freqüentem ente os dados em cache para o original — esse processo é denominado es­ vaziamento de cache. Sistemas de arquivos distribuídos muitas vezes colocam o cache tanto no servidor quanto no cliente, o que torna ainda mais complexo manter a consistên­ cia do cache. 38 S U tw u is o jte ra à o tu u t R e ip o ità i: 1) Os tem pos de acesso para a m em ória principal são muito m enores do que os tem pos para um disco. Esses têm, tipi­ cam ente, capacidade m aior do que a m em ória principal, porque o custo por unidade de arm azenam ento em disco é m enor do que o da m em ória principal. A m em ória principal é volátil, ao passo que discos arm azenam dados persistentem ente. 2) Processos podem acessar as localizações da m em ória principal em qualquer ordem e aproxim adam ente à m esm a veloci­ dade, independentem ente da localização. 23.6. AriMAtceHAmetito secundário Devido à sua capacidade lim itada e volatilidade, a m em ória principal é inadequada para arm azenar grandes quantidades de dados ou dados que devem persistir após a interrupção da energia elétrica. Para arm azenar perm anentem ente grandes quantidades de dados, com o arquivos de dados e softwares de aplicação, o com putador usa armazenamento secundário (tam bém denom inado armazenamento persistente ou auxiliar), que m antém seus dados depois de o com putador ser desligado. A m aioria dos com putadores usa discos rígidos para arm azenam ento secundário. Em bora as unidades de disco rígido arm azenem mais e custem menos do que a RAM , elas não são práticas com o o arm azenam ento de m em ória primária, porque o acesso a esse tipo de disco é m uito m ais lento do que o acesso à m em ória principal. A cessar dados arm azenados em discos rígidos requer m ovim ento m ecânico do cabeçote de leitura/gravação, latência rotacional enquanto os dados giram até o cabeçote, e tempo de transferência enquanto os dados passam pelo ca­ beçote. Esse m ovim ento m ecânico é muito m ais lento do que a velocidade dos sinais elétricos entre a m em ória principal e um processador. Além disso, os dados devem ser carregados do disco para a m em ória principal antes que possam ser acessados por um processador.9 U m disco rígido é um exemplo de dispositivo de bloco, porque transm ite dados em blocos de bytes de tam anho fixo (norm alm ente centenas de bytes a dezenas de kilobytes). A lguns dispositivos de arm azenam ento secundário gravam dados em meios de m enor capacidade que podem ser removidos do computador, o que facilita a cópia de segurança dos dados (backup) e a transferência de dados entre com ­ putadores. Entretanto, esse tipo de arm azenam ento secundário exibe um a latência m ais alta do que outros dispositivos com o discos rígidos. Um dispositivo popular de arm azenam ento é o disco compacto (Com pact Disc — CD), que pode arm azenar até 700 M B em cada lado. Os dados em CD são codificados sob form a digital e ‘queim ados’ no CD com o uma série de depressões sobre um a superfície até então lisa, que representa ‘uns’ e ‘zeros’. D iscos do tipo grava-uma-vez, lêvárias (write-once, read rnany — WORM), tais com o discos com pactos grava-uma-vez (CD-R) e discos digitais versáteis grava-uma-vez (DVD-R), são removíveis. Outros tipos de arm azenam ento persistente são os discos Zip, discos flexíveis, cartões de m em ória Flash e fitas. Dados gravados em um disco CD-RW (CD regravável) são arm azenados em m aterial m etálico dentro do disco plástico. A luz do laser modifica as propriedades refletivas do m eio de gravação criando dois estados que representam ‘um ’ e ‘zero’. CD -Rs e CD-ROM s consistem em um a tintura entre cam adas de plástico que não pode ser alterada um a vez queim ada pelo laser. Recentem ente a tecnologia do DVD (tam bém denom inado videodisco digital), que se destinava originalm ente a gra­ var filmes, passou a ser um meio de arm azenam ento de dados de preço razoável. DVDs são do m esm o tamanho de CDs, mas arm azenam dados em trilhas m ais finas em até duas cam adas por lado e podem arm azenar até 5,6 GB de dados por camada. Alguns sistemas contêm níveis de memória além do armazenamento secundário. Por exemplo, sistemas de processamento de dados de grande porte muitas vezes têm bibliotecas de fitas que são acessadas por um braço robótico. Esses sistem as de armazenamento, com um ente classificados com o arm azenagem terciária, são caracterizados por m aior capacidade e tempos de acesso m ais lentos do que o arm azenam ento secundário. Revuã# 1) Por que acessar dados arm azenados em disco é mais lento do que acessar dados na m em ória principal? 2) Com pare CDs e DVDs m ostrando suas diferenças. Reipoifai: 1) A m em ória principal pode ser acessada por sinais elétricos somente, mas discos requerem m ovim entos mecânicos para m over o cabeçote de leitura/gravação, latência rotacional enquanto o disco gira para posicionar os dados sob o cabe­ çote e tempo de transferência enquanto eles passam pelo cabeçote. 2) CDs e DVDs têm o mesmo tam anho e são acessados por luz de laser, mas DVDs arm azenam dados em camadas m últiplas usando trilhas mais finas e, por isso, possui m aior capacidade. C & fú tu J o 2 C o n ce ito s d e , k a rd w a re , e, s o ftw a re . 39 23.7 Barrcunentos B arram ento é um conjunto de pistas (ou de outras conexões elétricas) que transportam inform ações entre dispositivos de hardw are. Os dispositivos enviam sinais elétricos pelo barram ento para se com unicarem com outros dispositivos. A m aioria dos barram entos consiste em um barramento de dados que transporta dados, e um barramento de endere­ ços que determ ina o receptor ou as fontes daqueles d ad o s.10 U m a porta é um barram ento que conecta exatam ente dois dispositivos. U m barram ento com partilhado por diversos dispositivos para executar operações de E/S é denom inado canal de E/S.11 A cesso à m em ória principal é um ponto de contenção para canais e processadores. N orm alm ente pode ocorrer so­ m ente um acesso a um m ódulo particular de m em ória a qualquer dado instante; todavia, os canais de E/S e o processador podem tentar acessar a m em ória sim ultaneam ente. Para evitar que dois sinais colidam no barram ento, o acesso à m em ória é priorizado por um dispositivo de hardw are denom inado controlador, e os canais tipicam ente ganham prioridade sobre os processadores. Cham am os isso de roubo de ciclo, porque o canal de E/S efetivamente rouba ciclos do processador. Canais de E/S consom em um a pequena fração do total de ciclos do processador, o que é norm alm ente com pensado pela m elhor utilização do dispositivo de E/S. Lem bre-se de que o barram ento frontal (FSB) conecta um processador à m em ória principal. À m edida que a velocidade do FSB aum enta, a quantidade de dados transferida entre a m em ória principal e um processador aum enta, o que tende a increm entar o desempenho. Velocidades de barramentos são medidas em M H z (por exemplo, 133 M Hz e 200 M Hz). Alguns conjuntos de chips im plem entam um FSB de 200 M Hz, mas funcionam efetivamente a 400 M Hz, porque executam duas transferências de m em ória por ciclo de relógio. Essa característica, que deve ser suportada por am bos, conjunto de chips e RAM , é denom inada taxa dupla de dados {Double D ata Rate — DDR). U m a outra im plem entação, denom inada quad pumping (bom beam ento quádruplo), perm ite até quatro transferências por ciclo, efetivamente quadruplicando a largura de banda da m em ória do sistema. O barramento de interconexão de componente periférico (Peripheral Com ponent Interconnect — PCI) conecta dispositivos periféricos, com o placas de som e placas de rede, ao resto do sistema. A prim eira versão da especificação do PCI requeria que o barram ento de PCI funcionasse a 33 M H z e tivesse 32 bits de com prim ento, o que lim itava considera­ velm ente a velocidade com que os dados eram transferidos de e para dispositivos periféricos. O PCI Express é um padrão recente que atende a barram entos de larguras variáveis. Com o PCI Express cada dispositivo é conectado ao sistem a por até 32 vias, cada um a delas pode transferir 250 MB por segundo em cada direção — um total de até 16 GB por segundo de largura de banda por enlace.12 A Porta Gráfica Acelerada (A ccelerated G raphics Port - AGP) é usada prim ariam ente com placas gráficas, que norm alm ente requerem dezenas ou centenas de m egabytes de RAM para executar m anipulações gráficas em 3D em tem po real. A especificação original da AGP requeria um barram ento de 32 bits, 66 M Hz, que fornecia aproxim adam ente 260 MB por segundo de largura de banda. Os fabricantes aum entaram a velocidade desse barram ento em relação à sua especificação original — indicando um aum ento de velocidade por um fator de 2 com o 2x, por um fator de 4 com o 4x e assim por diante. Especificações atuais perm item versões 2x, 4x e 8x desse protocolo, possibilitando até 2 GB por segundo de largura de banda. R cvU cu y 1. Com o a velocidade do FSB afeta o desem penho do sistema? 2. Com o controladores simplificam o acesso a barram entos com partilhados? 1) O FSB determ ina quantos dados podem ser transferidos entre processadores e m em ória principal por ciclo. Se um processador requisitar mais dados do que podem ser transferidos por ciclo, o desem penho do sistem a dim inuirá porque aquele processador talvez precise esperar até que as transferências requisitadas sejam concluídas. 2) Controladores priorizam requisições m últiplas sim ultâneas de acesso ao barram ento para que dispositivos não interfiram uns nos outros. 2 3 .8 Acesso direto à/ ncemória, ( V irect Memory Access — DMA) A m aioria das operações de E/S transfere dados entre a m em ória principal e um dispositivo de E/S. E m com putadores antigos isso se conseguia usando E/S programada (programmed I/O — PIO), que especificava um byte ou palavra a ser transferida entre a m em ória principal e um dispositivo de E/S e, depois, esperava ociosam ente que a operação fosse concluída. Isso levava ao desperdício de um núm ero significativo de ciclos de processador enquanto se esperava que as operações PIO fossem concluídas. M ais tarde projetistas implem entaram E/S com andada por interrupção, que habilitava um processador a em itir uma requisição E/S e im ediatam ente continuar a executar instruções de software. O dispositivo de E/S avisava o processador quando a operação estava concluída gerando um a interrupção.13 S U tw u is o jte ra c io fu iti 40 O acesso direto à memória (DMA) aprim ora essas técnicas habilitando dispositivos e controladores a transferir blocos de dados de e para a m em ória principal, o que libera o processador para executar instruções de software (Figura 2.4). Um canal de acesso direto à m em ória (DM A) usa um controlador de E/S para gerenciar transferência de dados entre dispositivos de E/S e a m em ória principal. Para avisar o processador, o controlador de E/S gera um a interrupção quando a operação é concluída. O DM A m elhora significativamente o desem penho em sistem as que executam grandes números de operações de E/S (por exemplo, com putadores de grande porte e servidores).14 O DM A é com patível com diversas arquiteturas de barramento. Em arquiteturas legadas (arquiteturas que ainda estão em uso, mas não são m ais produzidas ativam ente), com o barram entos Industry Standard Architecture (ISA), ISA am pliada (EISA) ou M icro Channel Architecture (M CA), um controlador de DM A (tam bém denom inado ‘dispositivo de terceiros’) gerencia transferências entre a m em ória principal e dispositivos de E/S (veja o quadro “Reflexões sobre sistemas opera­ cionais, Hardw are e software legados”). Barram entos PCI em pregam transferência por DM A próprio usando mestre de transferência de dados — um dispositivo de PCI assum e o controle do barram ento para realizar a operação. Em geral a transferência de DM A próprio é m ais eficiente do que a transferência de terceiros e tem sido im plem entada pela maioria das arquiteturas de barram ento m odernas.15 R evU ã# 1. Por que o DM A é m ais eficiente do que o PIO ? 2. Qual a diferença entre DM A próprio e de terceiros? Reipaitêu: 1) Em um sistem a que usa PIO, um processador espera ociosam ente que cada transferência de m em ória seja con­ cluída. O DM A livra os processadores de realizar o trabalho necessário para transferir inform ações entre a m em ória principal e dispositivos de E/S, por isso habilita-os a executar instruções. 2) DM A de terceiros requer um controlador para gerenciar o acesso ao barram ento. DM A próprio habilita dispositivos a assum ir o controle do barram ento sem hardw are adicional. 2.3.9 VUposctwúsperiféricos Um dispositivo periférico é qualquer dispositivo de hardw are não requerido por um com putador para executar ins­ truções de softw are. Entre os dispositivos periféricos estão m uitos tipos de dispositivos de E/S (im pressoras, scanners RAM 0 Um processador envia uma solicitação de E/S ao controlador de E/S, que envia a solicitação ao disco. 0 processador continua executando instruções. (? ) O disco envia dados ao controlador de E/S; os dados são colocados no endereço de memória especificado pelo comando do DMA. (V ) O disco envia uma interrupção ao processador indicando que a E/S foi concluída. FLjUfO/ 2.4 Acesso direto ècmnMÓruc (DMA). Capítulo 2 Cottceitos de*kardwture, e, software, 41 Hardware* e*software* legada. As últimas versões de sistemas operacionais são projetadas para su­ portar as mais recentes funcionali­ dades disponíveis de software e har­ dware. Todavia, a vasta maioria de hardware e software que está 'por aí' muitas vezes são equipamentos e aplicações mais antigos nos quais indivíduos e organizações investiram e querem continuar usando mesmo após a instalação de um novo siste­ ma operacional. Os itens mais an­ tigos são chamados de hardwares e softwares legados. Um enorme desafio para os projetistas de sis­ temas operacionais é dar suporte a tais sistemas legados, desafio que os sistemas operacionais do mundo real precisam enfrentar. e m ouses), dispositivos de rede (placas de interface de rede e m odem ) e dispositivos de arm azenam ento (CD , DVD e unidades de disco). D ispositivos com o o processador, a placa principal e a m em ória principal não são considerados periféricos. D ispositivos periféricos internos (os que estão localizados dentro da carcaça do com putador) usualm ente são denom inados dispositivos periféricos integrados, entre os quais estão m odem s, placas de som e unidades internas de CD-ROM . Talvez o dispositivo periférico m ais com um seja o disco rígido. A F igura 2.5 lista diversos dispositivos periféricos.16Teclados e m ouses são exem plos de dispositivos de caracteres — transferem dados um caractere por vez. D ispositivos periféricos podem ser ligados a com putadores via portas e outros barram entos.17 Portas seriais transferem dados um bit por vez, conectando dispositivos com o teclados e mouses; portas paralelas transferem vários bits de dados por vez conectando, tipicam ente, im pressoras.18 Barramento serial universal ( U niversal Serial B us — USB) e portas IEEE 1394 são interfaces seriais populares de alta velocidade. A interface de sistemas computacionais pequenos (Sm all C om puter System s Interface — SCSI) é um a interface paralela popular. Portas USB transferem dados e fornecem energia a dispositivos com o unidades externas de disco, câm eras digitais e im pressoras. D ispositivos USB podem ser adicionados, reconhecidos e rem ovidos do com putador enquanto ele estiver ligado sem danificar o hardware do sistem a (uma técnica denom inada hot swapping, ou ‘ligação a quente’). O USB 1.1 perm ite transferência de dados a velocidades de 1, 5 M bit (megabits, ou 1 m ilhão de bits; 8 bits = 1 byte) por segundo e 12 M bit por segundo. Com o os com putadores requeriam acesso rápido a grandes quantidades de dados em dispositivos Dispositivo Descrição Unidade de CD-RW Lê e grava dados de e para discos óticos. Unidade de Zip Transfere dados de e para um disco magnético durável removível. Unidade de disco flexível Lê e grava dados de e para discos magnéticos removíveis. Mouse Transmite a mudança de localização de um ponteiro ou cursor em uma interface gráfica com o usuário (GUI). Teclado Transmite caracteres ou comandos digitados por um usuário. Impressora multifuncional Pode imprimir, copiar, enviar fax e escanear documentos. Placa de som Converte sinais digitais em sinais de áudio para alto-falantes. Também pode receber sinais de áudio via microfone e produzir um sinal digital. Acelerador de vídeo Exibe gráficos na tela; acelera gráficos bi e tridimensionais. Placa de rede Envia e recebe dados de e para outros computadores. Câmera digital Grava e muitas vezes exibe imagens digitais. Dispositivo biométrico Executa varredura (scan) de características humanas como impressões digitais e retinas, normalmente para finalidades de identificação e autenticação. Dispositivo de infravermelho Comunica dados entre dispositivos via conexão sem fio em linha de visada. Dispositivo sem fio Comunica dados entre dispositivos via conexão sem fio onidirecional. fig u ra , 2 .S Dispositivosperiféricos. S is te m a s o p e ra c io n a is 4a USB, com o unidades de disco, foi desenvolvido o USB 2.0 para fornecer transferência de dados com velocidades de até 480 M bit por segundo.19 O padrão IEEE 1394, denom inado com ercialm ente pela Sony de iLink e pela A pple de FireW ire, é com um ente encon­ trado em câm eras digitais de vídeo e dispositivos de armazenamento de massa (por exemplo, unidades de disco). O FireW ire pode transferir dados a velocidades de até 800 M bits por segundo; espera-se que revisões futuras elevem a velocidade para 2 G bit (gigabits, ou 1 bilhão de bits) por segundo. Sem elhante ao USB, o FireW ire perm ite que os dispositivos sejam ‘ligados a quente’ (hot swappables) e ele fornece energia elétrica a dispositivos. A lém disso, sua especificação perm ite com unicação entre vários dispositivos sem que eles estejam ligados a um com putador.20 Por exem plo, um usuário pode conectar diretam ente dois discos rígidos de Firew ire e copiar o conteúdo de um no outro. Entre outras interfaces usadas para conectar dispositivos periféricos aos sistem as, estão a interface de sistemas com pu­ tacionais pequenos (SCSI) e a conexão de tecnologia avançada (Advanced Technology A ttachm ent— ATA) que implementa a interface eletrônica de unidades integradas (Integrated D rive Electronics - IDE). Essas interfaces transferem dados de um dispositivo com o um disco rígido ou uma unidade de DVD para um controlador da placa principal, no qual esses dados podem ser roteados até o barram ento apropriado.21 Algum as das interfaces mais recentes são a ATA Serial (SATA) que perm ite taxas de transferência m ais altas do que a ATA e diversas interfaces sem fio, entre elas, a Bluetooth (para conexões sem fio de curto alcance) e a IEEE 802.1 lg (para conexões sem fio de alcance m édio e alta velocidade). A SCSI (pronuncia-se ‘scâzi’ em inglês) foi desenvolvida no início da década de 80 como uma conexão de alta velocidade para dispositivos de arm azenam ento de massa. É usada prim ordialm ente em am bientes de alto desem penho com muitos dispositivos de grande largura de banda.22 A especificação original da SCSI perm itia um a taxa de transferência m áxim a de 5 MB por segundo e suportava oito dispositivos em um barram ento de 8 bits. Especificações atuais, com o a SCSI Ultra320, perm item transferência de dados a taxas de até 320 MB por segundo para 16 dispositivos em barram entos de 16 bits.23 Reviião' 1. Qual a principal diferença entre um dispositivo periférico, com o um a im pressora, e um dispositivo com o um pro­ cessador? 2. Com pare USB e FireW ire e aponte as diferenças entre eles. # 1) D ispositivos periféricos não são exigidos por um com putador para executar instruções de software. Ao contrário, todos os com putadores precisam de pelo menos um processador para funcionar. 2) Tanto o USB com o o FireW ire fornecem grandes larguras de banda e conexões ativas com dispositivos. O FireW ire tem m aior capacidade do que o USB e perm ite que os dispositivos se com uniquem sem que estejam ligados a um computador. 2.4 Suportahardw areparco sistemas operacionais A rquiteturas de com putador contêm recursos que executam funções de sistemas operacionais rapidam ente em hardware para m elhorar o desem penho. Também possuem recursos que habilitam o sistem a operacional a im por rígida proteção, o que m elhora a segurança e a integridade do sistema. 2.4.1 Processador A m aioria dos sistem as operacionais depende de processadores para im plem entar seus m ecanism os de proteção im pe­ dindo processos de acessar instruções privilegiadas ou de acessar m em órias que não lhes foram alocadas. Se os processos tentarem violar os m ecanism os de proteção de um sistema, o processador alerta o sistem a operacional para que ele possa reagir. O processador tam bém invoca o sistem a operacional para reagir a sinais que vêm de dispositivos de hardware. Modo usuúrio, utodo núcleo & instruçõesprUnle^iadas Sistemas de com putador geralm ente têm diversos modos de execução.24 Variar o m odo de um a m áquina possibilita construir sistem as mais robustos, tolerantes a falhas e seguros. N orm alm ente, quando a m áquina está operando em um de­ term inado m odo, as aplicações têm acesso a som ente um subconjunto de instruções da m áquina. No caso de aplicações de usuário, o subconjunto de instruções que o usuário pode executar em modo usuário (tam bém denom inado estado usuário ou estado-problema) impede, por exemplo, a execução direta de instruções de entrada/saída; um a aplicação de usuário à que fosse perm itido executar entrada/saída arbitrárias podería, por exemplo, descarregar a lista m estra de senhas do sistema, im prim ir inform ações de qualquer outro usuário ou destruir o sistem a operacional. O sistem a operacional ordinariam ente executa com o estado usuário mais confiável em modo núcleo (também denom inado estado supervisor); ele tem acesso a todas as instruções do conjunto de instruções da máquina. Em m odo núcleo, um processador pode executar instruções privilegiadas e acessar recursos para realizar tarefas em nom e dos processos. Tal dicotom ia m odo usuário/m odo núcleo Capctuio 2 g B R e f l e x õ e s . P r u ic ífz iô $ o \? c e d o fw u d d é y io $ \d e m < % $ Conceitos de, hardware, e, software, 43 o ^ e c A ú \o \A A .\$ w to tó De modo geral, o princípio do privilégio mínimo diz que, em qual­ quer sistema, deve-se dar às várias entidades somente as capacidades de que necessitam para realizar suas tarefas, mas não mais. O governo emprega esse princípio para conce­ der permissões de segurança. Você o emprega quando decide quem pode te r as chaves da sua casa. Em presas o em pregam quando permitem que funcionários tenham acesso à informações críticas e con­ fidenciais. Sistemas operacionais o empregam em muitas áreas. tem sido adequada para a m aioria dos sistem as m odernos de computador. Em sistem as de alta segurança, entretanto, é desejável ter mais de dois estados para perm itir um a proteção mais minuciosa. Estados m últiplos autorizam perm issão de acesso pelo princípio do privilégio mínimo — qualquer usuário particular deve receber a quantidade m ínim a de privilégio e acesso requerida para cum prir suas tarefas designadas (veja o quadro “Reflexões sobre sistem as operacionais, Princípio do privilégio m ínim o”). É interessante notar que, à m edida que as arquiteturas de com putadores evoluíam, o número de instruções privilegiadas (as instruções não acessíveis em m odo usuário) tendia a aumentar, indicando um a inclinação em direção à incorporação de m ais funções de sistemas operacionais no hardware. Proteção e,gerenciamento da, memória, A m aioria dos processadores oferece m ecanism os para proteção da m em ória e gerenciam ento da m emória. Proteção da memória, que im pede que processos acessem m em ória que não lhes foi designada (como a m em ória de outros usuários e a m em ória do sistem a operacional), é im plem entada por meio de registradores de processador que som ente podem ser modificados com instruções privilegiadas (veja o quadro “Reflexões sobre sistemas operacionais, Proteção”). O processa­ dor verifica os valores desses registradores para assegurar que os processos não possam acessar m em ória que não lhes foi alocada. Por exemplo, em sistem as que não usam m em ória virtual, processos são alocados apenas a um bloco contíguo de endereços de m emória. O sistem a pode im pedir esses processos de acessar localizações de m em ória que não lhes tinham sido alocadas fornecendo registradores de limites, que especificam os endereços do início e do fim da m em ória alocada a um processo. A proteção é im plem entada determ inando-se se um dado endereço está dentro do bloco alocado. Grande parte das operações de proteção de hardw are é realizada em paralelo com a execução de instruções de program a de m odo que não degrade o desempenho. A maioria dos processadores também contém hardware que traduz endereços virtuais referidos por processos para endere­ ços correspondentes na memória principal. Sistemas de memória virtual permitem que programas se refiram a endereços que não precisem corresponder ao conjunto limitado de endereços reais (ou físicos) disponível na memória principal.25 Usando hardware, o sistema operacional traduz dinamicamente os endereços virtuais de um processo para endereços físicos em tempo de execução. Sistemas de memória virtual permitem que processos se refiram a espaços de endereços muito maiores do que o número de endereços disponíveis na memória principal, o que possibilita aos programadores criarem aplicações independentes (na maior parte do tempo) das restrições da memória física. A memória virtual também facilita a programação para sistemas de tempo compartilhado, porque os processos não precisam estar cientes da localização real de seus dados na memória principal. Gerenciamento e proteção da memória são discutidos detalhadamente nos capítulos 9 a 11. Interrupções e, exceções Processadores inform am a sistem as operacionais sobre eventos com o erros na execução de program as e mudanças no estado de dispositivos (por exemplo, chegou um pacote de rede ou foi concluída um a entrada/saída por disco). Um processador pode fazer isso consultando repetidam ente o status de cada dispositivo, um a técnica denom inada sondagem (polling). Entretanto, isso pode gerar um significativo custo adicional de execução quando os dispositivos sondados não tiverem m udado de status. Em vez disso, a m aioria dos dispositivos envia ao processador um sinal denom inado interrupção quando ocorre um evento. O sistem a operacional pode responder a um a m udança no status do dispositivo notificando os processos que estão à espera desses eventos. Exceções são interrupções geradas em resposta a erros, com o falhas de hardware, erros de lógica e violações de proteção (veja no site deste livro: “Curiosidades — Origens do Termo ‘G litch’” )* Em vez de provocar a falha do sistema, o processador tipicam ente invocará o sistem a operacional para que este determ ine com o ele deve reagir. Por exemplo, o sistem a operacional pode determ inar que o processo que esteja causando o erro deva ser encerrado ou que 44 S is te m a s o j^ e ra c io tu iis Proteção Os prim eiros com putadores tinham sistemas operacionais pri­ mitivos que conseguiam executar somente um serviço por vez. Isso mudou rapidamente à medida que eram adicionadas capacidades de processamento paralelo a sistemas locais e conforme eram desenvolvi­ dos sistemas distribuídos nos quais ocorriam atividades paralelas através de redes de computadores como a Internet. Sistemas operacionais de­ vem se preocupar com vários tipos de proteção, especialmente quando conectados à Internet. O sistema operacional e seus dados devem ser protegidos de ser massacrados por programas de usuários sujeitos a erro, seja acidental ou propositadamente. Programas de usuários devem ser protegidos de massacrar um ao ou­ tro. Essa proteção deve ser imposta na máquina local e entre usuários e componentes de sistemas operacio­ nais dispersos por redes de compu­ tadores. Estudaremos proteção em muitos capítulos deste livro, especial­ mente no Capítulo 9, "Organização e gerenciamento da memória real" e no Capítulo 10, "Organização da memória virtual". Consideraremos proteção sob a forma de controles de acesso a arquivos no Capítulo 13, "Sistemas de arquivos e de banco de dados". Discutiremos proteção em geral por todo o livro e também nos estudos de casos do Linux e do Windows XP nos capítulos 20 e 21, respectivamente. o sistem a deva ser reiniciado. Já que o sistem a pode falhar, o sistem a operacional pode fazê-lo com elegância, reduzindo a quantidade de trabalho perdido. Processos tam bém podem registrar tratadores de exceções no sistem a operacional. Q uan­ do o sistem a receber um a exceção do tipo correspondente, ele convocará o tratador de exceções do processo para reagir. M ecanism os de interrupção e tratadores de exceção são discutidos na Seção 3.4, “Interrupções” . Revuão' 1. Q uais os princípios racionais da im plem entação de estados m últiplos de execução? 2. Q uais as diferenças entre exceções e outros tipos de interrupção? 1) Estados m últiplos de execução proporcionam proteção evitando que a m aioria dos softwares danifique o sistema e acesse recursos sem autorização, seja acidental, seja propositalm ente. Essas operações estão restritas ao m odo núcleo, o que habilita o sistem a operacional a executar operações privilegiadas. 2) Exceções indicam que ocorreu um erro (por exemplo, divisão por zero ou um a violação de proteção) e invocam o sistem a operacional para que esse determ ine com o responder. O sistem a operacional pode decidir nada fazer ou encerrar um processo. Se o sistema operacional encontrar diversos erros que o im peçam de executar adequadam ente, ele poderá reiniciar o computador. 2.4.2 TeHipGtrUcculores &relógios Um temporizador de intervalo gera periodicam ente um a interrupção que faz o processador invocar o sistem a operacional. Sistem as operacionais freqüentem ente usam tem porizadores de intervalo para im pedir que processos m o­ nopolizem o processador. Por exem plo, o sistem a operacional pode responder à interrupção do tem porizador retirando os processos atuais do processador de m odo que um outro possa ser executado. U m relógio (de 24 horas) habilita o com putador a seguir o ‘horário norm al do dia/n o ite’, com precisão típica de m ilésim os ou m ilionésim os de segundo. A lguns relógios de com putador funcionam com baterias, o que perm ite que continuem funcionando m esm o quando o com putador esteja desligado de qualquer fonte externa de energia. E sses relógios dão um a m edida de continuidade a um sistem a; por exem plo, quando o sistem a operacional é carregado, ele pode ler o horário do dia para determ inar a hora e o dia atuais. Reríião' 1. Com o um tem porizador de intervalo evita que um processo m onopolize o processador? 2. Processadores freqüentem ente contêm um contador, increm entado após cada ciclo de processador, dando uma m edição do tem po com precisão de nanossegundos. Com pare e aponte as diferenças entre essa m edição do tem po e a fornecida pelo relógio normal. Cafútulo 2 Conceitos d&hardware, e, software, 45 Reípoitài: 1) O tem porizador de intervalo gera interrupções periodicamente. O processador responde a cada interrupção invocando o sistem a operacional que, então, pode designar um processo diferente a um processador. 2) O contador de um processador habilita o sistem a a determ inar com alta precisão quanto tempo passou entre eventos, mas não mantém suas inform ações quando o sistem a é desligado. Com o o relógio normal funciona com batería, é mais apropriado para determ inar o horário do dia/noite. Todavia, ele m ede o tem po com um a precisão m ais grosseira do que um contador de processador. 243 Autocartregammtô (Bõôtstrapping) Antes que um sistem a operacional possa com eçar a gerenciar recursos, ele deve ser carregado na memória. Q uando um sistema de com putador é ligado, o BIOS inicializa o hardware do sistema e tenta carregar instruções na memória principal em um a região de arm azenam ento secundário (por exemplo, um disco flexível, um disco rígido ou um CD ), denom inada setor de inicialização (boot sector), um a técnica cham ada autocarregam ento (Figura 2.6). O processador é forçado a executar essas instruções que norm alm ente carregam com ponentes do sistem a operacional na m emória, inicializam registradores de processador e preparam o sistem a para executar aplicações de usuários. Em m uitos sistem as o BIOS pode carregar um sistem a operacional em um a localização predefinida em um núm ero lim itado de dispositivos (por exemplo, o setor de inicialização de um disco rígido ou de um disco com pacto). Se o setor de inicialização não for encontrado em um dispositivo suportado, o sistem a não será carregado, e o usuário não conse­ guirá acessar nenhum hardw are do computador. Para proporcionar m aior funcionalidade na hora da inicialização, a Intel Corporation desenvolveu a interface extensível de firmware (Extensive Firm w are Interface - EFI) em substituição ao BIOS. A EFI suporta um interpretador de com andos, por meio do qual usuários podem acessar diretam ente dispositivos de computador, e incorpora unidades de dispositivos para suportar acesso a unidades de disco rígido e redes, im ediatam ente após ligar o sistem a.26 RevUcur 1. Com o a EFI aborda as lim itações do BIOS? 2. Por que os sistem as operacionais devem im pedir que usuários acessem o setor de inicialização? Reipoitãi: 1) Um BIOS típico contém instruções de baixo nível que proporcionam funcionalidade lim itada e restringem o m odo com o o software é carregado inicialm ente. A EFI suporta drivers e fornece um interpretador de com andos, habilitando o usuário a interagir com um sistema e a personalizar o m odo com o o sistem a operacional é carregado. 2) Se os usuários pudessem acessar o setor de inicialização, também poderíam , acidental ou propositalm ente, modificar o código do sistema operacional inutilizando o sistem a ou perm itindo que um invasor assum isse o controle do sistema. 244 Plug cuuifUay A tecnologia plug-and-play ( ‘ligue-e-use’) perm ite que sistem as operacionais configurem e usem hardw are recéminstalado sem interação do usuário. Um dispositivo de hardw are plug-and-play: \.G IAutocarregamento. SUtWiAS OjMrOCiotUlti 46 1 2 3 identifica-se inequivocam ente no sistem a operacional; comunica-se com o sistema operacional para indicar os recursos e serviços que requer para funcionar adequadamente; e identifica seu driver correspondente e perm ite que o sistem a operacional o utilize para configurar o dispositivo (ou seja, designa o dispositivo a um canal DM A e aloca ao dispositivo um a região da m em ória principal).27 Essas características habilitam usuários a adicionar hardware a um sistem a e utilizá-lo im ediatam ente com suporte adequado do sistem a operacional. Conform e os sistem as móveis de com putação tom am -se m ais populares, um núm ero cada vez m aior de sistem as de­ pende de baterias para funcionar. Conseqüentem ente, o plug-and-play evoluiu para abranger recursos de gerenciam ento de energia que habilitam o sistem a a ajustar dinam icam ente seu consum o de energia para aum entar a vida útil da batería. A interface avançada de configuração e energia (Advanced Configuration and Power Interface — ACPI) define um a interface-padrão para que os sistem as operacionais configurem dispositivos e gerenciam seu consum o de energia. Todos os sistem as operacionais W indows recentes suportam plug-and-play; o Linux versão 2.6 é com patível com muitos dispo­ sitivos plug-and-play.28 R cvU cu y 1. Por que você acha que é necessário que um plug-and-play se identifique inequivocamente no sistema operacional? 2. Por que o gerenciam ento de energia é particularm ente im portante para dispositivos móveis? Reipoifai: 1) Antes que um sistem a possa configurar e disponibilizar um dispositivo a usuários, ele deve determ inar as necessi­ dades de recursos exclusivas daquele dispositivo. 2) Dispositivos móveis dependem de baterias; gerenciar o consum o de energia de um dispositivo pode aum entar a vida útil da batería. .S Cachuig & N a seção 2.3.4 discutim os com o os com putadores contêm um a hierarquia de dispositivos de arm azenam ento que fun­ cionam a velocidades diferentes. Para m elhorar o desem penho, a m aioria dos sistem as executa caching colocando cópias das inform ações as quais os processos se referem em arm azenam ento m ais rápido. Devido ao alto custo do arm azenam ento rápido os caches podem conter som ente um a pequena parte das inform ações contidas em arm azenam ento m ais lento. Conseqüentem ente, as entradas de cache (também cham adas de linhas de cache) devem ser gerenciadas adequadam ente para m inim izar o núm ero de vezes que as inform ações referidas não estão presentes no cache, um evento denom inado ausência do cache {cache miss). Q uando ocorre um a ausência do cache, o sistem a deve recuperar a inform ação referida do arm azenam ento mais lento. Quando um item está presente no cache, ocorre o que cham am os de presença no cache {cache hit), habilitando o sistem a a acessar dados a um a velocidade relativam ente alta.29 Para conseguir melhor desempenho do caching, os sistemas precisam garantir que um número significativo de referências à m em ória resulte em presenças no cache. Com o discutirem os na Seção 11.3, “Paginação por dem anda”, é difícil prever com alta precisão as inform ações à que os processos irão se referir dentro de instantes. Portanto, a m aioria dos caches é gerenciada por heurísticas — regras práticas e outras aproxim ações — que dão bons resultados com custo de execução relativam ente baixo (veja o quadro “Reflexões sobre sistemas operacionais - Heurística”). Exem plos de cache são os L I e L2 do processador que arm azenam dados utilizados recentem ente para m inim izar o núm ero de ciclos durante o qual o processador fica ocioso. M uitos sistem as operacionais alocam um a parte da memória principal para fazer cache de dados de unidades de arm azenam ento secundário com o discos, que norm alm ente exibem latências cujas ordens de magnitude são várias vezes m aiores do que a da m em ória principal. Buffer (arm azenam ento tem porário) é um a área que guarda dados tem porariam ente durante transferências entre dispo­ sitivos ou processos que funcionam a velocidades diferentes.30 Buffers m elhoram o desem penho do sistem a perm itindo que o software e os dispositivos de hardware transm itam dados e requisições assincronamente (ou seja, independentem ente um do outro). Exem plos de buffers são os de disco rígido, teclado e im pressora.31,32 Com o os discos rígidos funcionam a um a velocidade m uito m enor do que a da m em ória principal, os sistemas operacionais norm alm ente arm azenam dados tem porariam ente em buffers que correspondem a solicitações de escrita. O buffer guarda os dados até que o disco rígido tenha term inado a operação de escrita, habilitando o sistem a operacional a executar outros processos enquanto espera pelo térm ino da E/S. Um buffer de teclado muitas vezes é usado para m anter os caracteres digitados por usuários até que um processo possa confirm ar recebim ento e responder às interrupções correspondentes do teclado. Spooling (operações periféricas simultâneas em linha) é um a técnica pela qual um dispositivo interm ediário, com o um disco, é interposto entre um processo e um dispositivo de baixa velocidade ou de E/S lim itada por buffer. Por exemplo, C&fútuJò 2 Conceitos de, kardware, e, software, 47 se o processo tentar im prim ir um docum ento, mas a im pressora estiver ocupada imprim indo outro docum ento, o processo, em vez de esperar que a im pressora fique disponível, grava o resultado no disco. Q uando a im pressora tom a-se disponível, os dados que estão no disco são impressos. O spooling perm ite que o processo requisite operações em um dispositivo pe­ riférico sem exigir que o dispositivo esteja pronto para atender à requisição.33 O termo ‘spooling’ vem da idéia de bobinar o fio no carretei (spool) para ser desenrolado quando se quiser usá-lo. Revuãa 1. Com o o caching m elhora o desem penho do sistem a? 2. P or que os buffers em geral não m elhoram a produtividade, se um dispositivo ou processo produzir dados significa­ tivamente m ais rápido do que são consum idos? 1) Caches m elhoram o desem penho colocando em arm azenam ento rápido inform ações às quais um processo provavel­ m ente vai se referir dentro de pouco tempo; processos podem se referir a dados e instruções presentes em um cache muito m ais rapidam ente do que aos presentes na m em ória principal. 2) Se a entidade produtora for m uito mais veloz do que a entidade consum idora, o buffer ficará cheio rapidam ente e a relação será lim itada pela velocidade relativam ente lenta da entidade consum idora — a entidade produtora terá de desacelerar porque encontrará o buffer cheio repetidas vezes, e terá de esperar (em vez de executar à sua velocidade normal m ais rápida) até que a consum idora eventualm ente libere espaço no buffer. Similarmente, se a entidade consum idora for m ais rápida, ela encontrará o buffer vazio repetidas vezes e terá de desacelerar até aproxim adam ente a velocidade da entidade produtora. 6 Visão geral do N esta seção farem os uma revisão dos conceitos básicos de program ação de com putador e software. Program adores escrevem instruções em várias linguagens de programação; algumas são entendidas diretamente pelos com putadores, outras requerem tradução. As linguagens de program ação podem ser classificadas, de modo geral, com o linguagens de máquina, de montagem (assembly) ou de alto nível. 2.6.1 Luiguagem, de mÁguituv e linguagem, de montagem, Um com putador pode entender som ente sua própria linguagem de máquina. N a qualidade de ‘linguagem natural’ de um com putador particular, a linguagem de m áquina é definida pelo projeto de hardw are do computador. Linguagens de m áquina consistem geralm ente em cadeias de números (reduzidos a ls e Os) que instruem os com putadores a executar suas operações m ais elem entares. Linguagens de m áquina dependem da m áquina — um a determ inada linguagem de | y | R c j - l c x o e ç ç o W c ç l d c m A é o ^& c a c \ o \k ô \ ç> Heurística/ Heurística é uma 'regra prática' — uma estratégia que parece razoá­ vel e, quando empregada, normal­ m ente dá bons resultados. Nem sempre tem uma base matemáti­ ca, porque o sistema a que ela se aplica é suficientemente complexo para desafiar uma análise matemáti­ ca fácil. Ao sair de casa pela manhã, é provável que você use a heurísti­ ca ''Se parecer que vai chover, levo meu guarda-chuva". Você faz isso porque, na sua experiência, 'pare­ ce que vai chover' é um indicador razoável (embora não perfeito) de que choverá. Aplicando essa heu­ rística no passado, você já deixou de ficar encharcado algumas vezes, portanto, tende a confiar nela. Ao observar a pilha de papéis em sua mesa e programar seu dia de tra­ balho, você pode usar uma outra heurística: "Faça as tarefas mais curtas antes". Esse procedimento propicia um resultado satisfatório porque você termina várias tarefas rapidamente; mas, por outro lado, há o efeito colateral desvantajoso de adiar tarefas mais longas (provavel­ mente importantes). Pior ainda, se chegar um fluxo contínuo de novas tarefas curtas, você talvez adie in­ definidamente tarefas mais longas, importantes. Veremos heurísticas de sistemas operacionais em mui­ tos capítulos do livro, especialmente naqueles que discutem estratégias de g e re n cia m e n to de recursos como o Capítulo 8, "Escalonamen­ to de processador" e o Capítulo 12, "Otim ização do desempenho de disco". Sistemas oj^eraciotuiis 48 m áquina pode ser usada apenas em um tipo de computador. Parte de um program a antigo em linguagem de m áquina que som a pagam ento de horas extras com salário-base e arm azena o resultado em pagam ento bruto é apresentada a seguir e dem onstra a incom preensibilidade da linguagem de m áquina para os seres humanos: 1300042774 1400593419 1200274027 À m edida que aumentava a popularidade dos com putadores, a program ação em linguagem de m áquina provou ser lenta e suscetível a erros. Em vez de usar cadeias de núm eros que os com putadores pudessem ler diretam ente, program adores com eçaram a usar abreviaturas da língua inglesa para representar as operações básicas do computador. Essas abreviações form aram a base das linguagens de montagem. Program as tradutores denom inados montadores (assemblers) convertiam programas em linguagem de m ontagem para linguagem de máquina. Parte de um program a simples em linguagem de montagem tam bém som a pagam ento de horas extras com salário-base e arm azena o resultado em pagam ento bruto, mas apresenta as etapas com um a clareza um pouco m aior para leitores humanos: LOAD ADD STORE SALARIOBASE HORASEXTRAS PAGTOBRUTO Esse código em linguagem de m ontagem é m ais claro para os seres hum anos, mas os com putadores não podem entendê-lo até que seja traduzido para linguagem de m áquina por um program a montador. Rwíiiur 1. (V/F) Com putadores norm alm ente executam código de m ontagem diretamente. 2. Softwares escritos em linguagem de m áquina são portáveis? R e ip o itâ i: 1) Falso. M ontadores traduzem código de m ontagem para código de linguagem de m áquina antes que o código possa ser executado. 2) Não; linguagens de m áquina dependem da máquina; portanto, software escrito em linguagem de m áquina executa som ente em m áquinas do mesmo tipo. 2.6.2 iKter^retadotres & MUipiladores E m bora a program ação em linguagens de m ontagem seja m ais rápida do que em linguagem de m áquina, ainda assim as linguagens de m ontagem exigem m uitas instruções para realizar até a m ais sim ples das tarefas. Para aum en­ tar a eficiência do program ador foram desenvolvidas linguagens de alto nível. L inguagens de alto nível cum prem tarefas m ais substanciais com um núm ero m enor de com andos, m as exigem program as tradutores denom inados compiladores para converter program as em linguagem de alto nível para linguagem de m áquina. L inguagens de alto nível habilitam program adores a escrever instruções que se assem elham ao inglês do dia-a-dia e contêm notações m atem áticas com uns. P or exem plo, um a aplicação de folha de pagam ento escrita em linguagem de alto nível pode conter um com ando com o PAGTOBRUTO = SALARIOBASE + HORASEXTRAS Esse com ando produz o mesmo resultado das instruções escritas em linguagem de m áquina e linguagem de m ontagem m ostradas anteriorm ente. Enquanto com piladores convertem program as em linguagem de alto nível para program as em linguagem de m áquina, interpretadores são program as que executam diretam ente código-fonte ou código que foi reduzido a um a linguagem de baixo nível, que não é o código de m áquina. L inguagens de program ação com o Java com pilam para um form ato denom inado bytecode (em bora a Java tam bém possa ser com pilada para linguagem de m áquina), que age com o um código de m áquina para um a entidade denom inada m áquina virtual. A ssim , o bytecode não depende da m áquina real, física, na qual ele é executado, o que prom ove a portabilidade da aplicação. U m interpretador de Java analisa cada com ando e executa o bytecode na m áquina física. D evido ao adicional de tem po de execução incorrido na tradução, program as executados via interpretadores tendem a ser m ais lentos do que os que foram com pilados para código de m áquina.34*35 Sistemas oj^eraciotuiis 48 m áquina pode ser usada apenas em um tipo de computador. Parte de um program a antigo em linguagem de m áquina que som a pagam ento de horas extras com salário-base e arm azena o resultado em pagam ento bruto é apresentada a seguir e dem onstra a incom preensibilidade da linguagem de m áquina para os seres humanos: 1300042774 1400593419 1200274027 À m edida que aumentava a popularidade dos com putadores, a program ação em linguagem de m áquina provou ser lenta e suscetível a erros. Em vez de usar cadeias de núm eros que os com putadores pudessem ler diretam ente, program adores com eçaram a usar abreviaturas da língua inglesa para representar as operações básicas do computador. Essas abreviações form aram a base das linguagens de montagem. Program as tradutores denom inados montadores (assemblers) convertiam programas em linguagem de m ontagem para linguagem de máquina. Parte de um program a simples em linguagem de montagem tam bém som a pagam ento de horas extras com salário-base e arm azena o resultado em pagam ento bruto, mas apresenta as etapas com um a clareza um pouco m aior para leitores humanos: LOAD ADD STORE SALARIOBASE HORASEXTRAS PAGTOBRUTO Esse código em linguagem de m ontagem é m ais claro para os seres hum anos, mas os com putadores não podem entendê-lo até que seja traduzido para linguagem de m áquina por um program a montador. Rwíiiur 1. (V/F) Com putadores norm alm ente executam código de m ontagem diretamente. 2. Softwares escritos em linguagem de m áquina são portáveis? R e ip o itâ i: 1) Falso. M ontadores traduzem código de m ontagem para código de linguagem de m áquina antes que o código possa ser executado. 2) Não; linguagens de m áquina dependem da máquina; portanto, software escrito em linguagem de m áquina executa som ente em m áquinas do mesmo tipo. 2.6.2 iKter^retadotres & MUipiladores E m bora a program ação em linguagens de m ontagem seja m ais rápida do que em linguagem de m áquina, ainda assim as linguagens de m ontagem exigem m uitas instruções para realizar até a m ais sim ples das tarefas. Para aum en­ tar a eficiência do program ador foram desenvolvidas linguagens de alto nível. L inguagens de alto nível cum prem tarefas m ais substanciais com um núm ero m enor de com andos, m as exigem program as tradutores denom inados compiladores para converter program as em linguagem de alto nível para linguagem de m áquina. L inguagens de alto nível habilitam program adores a escrever instruções que se assem elham ao inglês do dia-a-dia e contêm notações m atem áticas com uns. P or exem plo, um a aplicação de folha de pagam ento escrita em linguagem de alto nível pode conter um com ando com o PAGTOBRUTO = SALARIOBASE + HORASEXTRAS Esse com ando produz o mesmo resultado das instruções escritas em linguagem de m áquina e linguagem de m ontagem m ostradas anteriorm ente. Enquanto com piladores convertem program as em linguagem de alto nível para program as em linguagem de m áquina, interpretadores são program as que executam diretam ente código-fonte ou código que foi reduzido a um a linguagem de baixo nível, que não é o código de m áquina. L inguagens de program ação com o Java com pilam para um form ato denom inado bytecode (em bora a Java tam bém possa ser com pilada para linguagem de m áquina), que age com o um código de m áquina para um a entidade denom inada m áquina virtual. A ssim , o bytecode não depende da m áquina real, física, na qual ele é executado, o que prom ove a portabilidade da aplicação. U m interpretador de Java analisa cada com ando e executa o bytecode na m áquina física. D evido ao adicional de tem po de execução incorrido na tradução, program as executados via interpretadores tendem a ser m ais lentos do que os que foram com pilados para código de m áquina.34*35 (U ifÁ tu lo l CôHX&ctos de, kardw tures & sojtum re^ 4 9 R cvilcu r 1. D iscuta os benefícios de linguagens de alto nível sobre linguagens de montagem. 2. Por que program as com pilados para bytecode são m ais portáveis do que os com pilados para código de máquina? 1) Program as em linguagem de alto nível requerem um núm ero m enor de instruções do que os em linguagem de m ontagem ; além disso, fazer program as em linguagens de alto nível é m ais fácil do que em linguagem de montagem , porque as de alto nível reproduzem com m aior sem elhança o inglês do dia-a-dia e as notações m atem áticas com uns. 2) Bytecode é com pilado para executar em um a m áquina virtual que pode ser instalada em muitas plataform as diferentes. Ao contrário, program as com pilados para linguagem de m áquina podem ser executados som ente no tipo de m áquina para o qual o program a foi compilado. 2.6.3 LuujtuujeKS da alto Em bora tenham sido desenvolvidas centenas de linguagens de alto nível, relativam ente poucas conquistaram ampla aceitação. Hoje, linguagens de program ação tendem a ser ou estruturadas, ou orientadas a objeto. N esta seção enum eramos algum as das linguagens m ais populares e discutim os com o se relacionam a cada modelo de programação. A IBM desenvolveu a linguagem Fortran em m eados da década de 50 para criar aplicações científicas e de engenharia que requeriam cálculos m atem áticos com plexos. A Fortran ainda é am plam ente usada, principalm ente em am bientes de alto desem penho, com o com putadores de grande porte e supercom putadores. COmmon Business Oriented Language (COBOL), ou linguagem com um orientada para negócios, foi desenvolvida no final da década de 50 por um grupo de fabricantes de computador, agências governam entais e usuários de com putador industrial. A CO BOL é projetada para aplicações de negócios que m anipulam grandes volumes de dados. Uma parte con­ siderável dos softwares de negócios de hoje ainda é program ada em COBOL. A linguagem C, que D ennis Ritchie desenvolveu no Bell Laboratories no início da década de 70, conquistou reconhe­ cim ento geral com o a linguagem de desenvolvim ento do sistem a operacional UNIX. No início da década de 80, no Bell Laboratories, B jam e Stroustrup desenvolveu a C ++, um a extensão da C. A linguagem C++ oferece recursos para pro­ gramação orientada a objeto — POO (O bject-O riented Programming — OOP). Objetos são com ponentes de software reutilizáveis que m odelam itens do m undo real. Program as orientados a objeto são com um ente m ais fáceis de entender, depurar e modificar do que os desenvolvidos com o em prego de técnicas anteriores. M uitos dos sistemas operacionais populares de hoje são escritos em C ou em C++. Q uando a popularidade da World Wide Web explodiu em 1993, a Sun M icrosystem s percebeu im ediatam ente o poten­ cial de utilização de sua nova linguagem de program ação orientada a objeto, Java, para criar aplicações que podiam ser descarregadas pela Web e executadas em navegadores. A Sun anunciou a Java ao público em 1995 e conquistou a atenção da com unidade de negócios por causa do grande interesse pela Web. A Java tom ou-se um a linguagem de desenvolvim ento de software am plam ente usada; ela é utilizada para gerar páginas Web dinam icam ente, m ontar aplicações em presariais em grande escala, aperfeiçoar a funcionalidade de servidores Web, fornecer aplicações para dispositivos de consum o (por exemplo, telefones celulares, pagers e PDAs) e para muitos outros propósitos. Em 2000 a M icrosoft anunciou a C # (pronuncia-se ‘C -sharp’) e sua estratégia .NET. A linguagem de program ação C # foi projetada especificam ente para ser a linguagem fundam ental da plataform a .NET; tem raízes nas linguagens C, C ++ e Java. C# é orientada a objeto e tem acesso à poderosa biblioteca .NET de com ponentes pré-fabricados, habilitando program adores a desenvolver aplicações rapidamente. Rem ia 1. C lassifiq u e cad a um a das seg u in tes lin g u ag en s de p ro g ram ação em e stru tu ra d a ou o rien ta d a a objeto: a) C#; b) C; c) Java; d) C++. 2. Cite alguns benefícios da POO. 1) a) orientada a objeto; b) estruturada; c) orientada a objeto; d) orientada a objeto. 2) Program as orientados a objeto com um ente são m ais fáceis de entender, depurar e modificar do que program as desenvolvidos com técnicas anteriores. A POO tem, também , com o objetivo, criar com ponentes de software reutilizáveis. S U tw u is o jte ra c io fu iti 50 2.6.4 Progranuiçã/) estruturada. Durante a década de 1960, era com um que esforços de desenvolvim ento de software não cum prissem o cronograma, os custos excedessem em m uito os orçam entos e os produtos acabados não fossem confiáveis. A s pessoas com eçaram a perceber que desenvolvim ento de software era um a atividade m uito mais com plexa do que tinham imaginado. As atividades de pesquisa dedicadas a esse item resultaram na evolução da programação estruturada — um a abordagem disciplinada para a criação de program as claros, corretos e fáceis de modificar. Essas pesquisas levaram ao desenvolvim ento da linguagem de program ação Pascal pelo Ppofessor Nicklaus W irth em 1971. A linguagem recebeu o nome de Pascal em honra ao m atem ático e filósofo do século XVII Blaise Pascal. Projetada para ensinar program ação estruturada, ela rapidam ente se tom ou a linguagem de program ação introdutória preferida na m aioria das universidades. Faltavam a essa linguagem muitas características necessárias que a tom assem útil para aplica­ ções com erciais, industriais e governam entais. A linguagem de program ação Ada foi desenvolvida com o patrocínio do D epartam ento de D efesa dos Estados Unidos (DoD) durante a década de 1970 e início da década de 1980. Seu nom e se deve à Lady A da Lovelace, filha do poeta Lord Byron. Lady Lovelace é geralm ente reconhecida com o a prim eira program adora de com putadores do mundo, tendo escrito um a aplicação em m eados do século XIX para o dispositivo m ecânico de com putação denom inado Analytical Engine, projetado por Charles Babbage. A A da foi um a das primeiras linguagens projetadas para facilitar programação concorrente, que é discutida com exemplos em pseudocódigo e Java no Capítulo 5, “Execução assíncrona concorrente” e no Capítulo 6, “Program ação concorrente”. R eviicuy 1. Quais foram os problem as abordados pela program ação estruturada nos prim eiros tempos do desenvolvim ento de software? 2. Qual a diferença entre a linguagem de program ação Ada e outras linguagens de program ação estruturadas com o a Pascal e a C? 1) Nos prim órdios da program ação, os desenvolvedores não tinham um a abordagem sistem ática na construção de program as com plexos, o que resultava em custos altos desnecessários, prazos não cum pridos e produtos não confiáveis. A program ação estruturada satisfez a necessidade de um a abordagem disciplinada no desenvolvim ento de software. 2) A Ada foi projetada para facilitar program ação concorrente. 2.6.5 Progranuição orientada/uobjeto Q uando os benefícios da program ação estruturada foram percebidos na década de 1970, com eçou a aparecer uma tecnologia aprim orada de software. Contudo, foi som ente depois de a program ação orientada a objeto ter-se estabelecido amplam ente nas décadas de 1980 e 1990 que os desenvolvedores de software finalmente sentiram que tinham as ferramentas necessárias para melhorar drasticam ente o processo de desenvolvim ento de software. A tecnologia de objeto é um esquem a de em pacotam ento para criar unidades de software significativas. Praticam ente qualquer substantivo pode ser representado com o um objeto de software. Objetos têm propriedades (tam bém denom ina­ das atributos) com o cor, tam anho e peso; e executam ações (também cham adas de comportamentos ou métodos) com o mover-se, dorm ir ou desenhar. Classes são tipos de objetos relacionados. Por exemplo, todos os carros pertencem à classe ‘carros’, mesmo que carros individuais variem quanto à fabricação, m odelo, cor e pacotes de opcionais. U m a classe espe­ cifica o formato geral de seus objetos, e as propriedades e ações disponíveis para um objeto dependem de sua classe. Um objeto está relacionado com sua classe do mesmo m odo que um edifício está relacionado com sua planta. Antes de surgirem as linguagens orientadas a objeto, linguagens de programação procedimental (como Fortran, Pascal, BASIC e C) concentravam -se em ações (verbos) e não em objetos (substantivos), o que tom ava a program ação um tanto desajeitada. Entretanto, usando as linguagens orientadas a objeto de hoje, com o C++, Java e C#, program adores podem program ar de um m odo orientado a objeto que reflete com m aior naturalidade a m aneira com o as pessoas percebem o mundo, resultando em ganhos significativos de produtividade de programação. A tecnologia de objeto perm ite que classes projetadas adequadam ente sejam reutilizadas em vários projetos. Usar bibliotecas de classes pode reduzir enorm em ente o esforço exigido para im plem entar novos sistemas. Todavia, algumas organizações afirmam que o benefício fundam ental da program ação orientada a objeto não é a característica de reutilização do software, mas sim a produção de software mais inteligível, porque é m ais bem organizado e m ais fácil de manter. Program ação orientada a objeto perm ite que program adores se concentrem no ‘quadro geral’. Em vez de se preocupa­ rem com os m inúsculos detalhes do modo com o objetos reutilizáveis são im plem entados, eles podem se concentrar nos com portam entos e interações de objetos. Também podem se concentrar na m odificação de um objeto sem se preocuparem Capítulo 2 Conceitos de, hardware, e, software, 51 com o efeito sobre outro objeto. Um m apa rodoviário que mostrasse todas as árvores, casas e cam inhos seria difícil, senão impossível, de ler. Q uando esses detalhes são rem ovidos e apenas as inform ações essenciais (estradas) perm anecem , o m apa fica mais fácil de entender. Do m esm o modo, um a aplicação dividida em objetos é m ais fácil de entender, modificar e atualizar porque oculta grande parte dos detalhes. R et/U ão' 1. Em que são diferentes o foco central da program ação orientada a objeto e o da program ação estruturada? 2. Com o objetos facilitam modificações em software existente? 1) Program ação orientada a objeto concentra-se na m anipulação de objetos (substantivos), ao passo que program ação procedim ental focaliza ações (verbos). 2) Objetos ocultam grande parte dos detalhes de um a aplicação, perm itindo que program adores concentrem -se no quadro geral. Eles podem dedicar-se à modificação de um objeto sem se preocuparem com o efeito sobre um outro objeto. 2.7 Interfaces de,programação de, aplicação ( APIs) As aplicações de hoje exigem acesso a m uitos recursos gerenciados pelo sistema operacional com o arquivos em disco e dados de com putadores remotos. Visto que o sistema operacional deve agir com o um gerenciador de recursos, norm alm ente ele não perm ite que processos obtenham esses recursos sem prim eiro requisitá-los explicitamente. Interfaces de programação de aplicação (Application Programming Interfaces - APIs) fornecem um a série de rotinas que os program adores podem usar para requisitar serviços do sistem a operacional (Figura 2.7). N a m aioria dos sistemas operacionais atuais, a com unicação entre o software e o sistem a operacional é executada exclusivamente por meio das APIS. Exem plos de APIs são os padrões POSIX (Portable Operating System Interface) e a API do Windows para o desen­ volvim ento de aplicações do M icrosoft W indows. POSIX recom enda A PIs padronizadas baseadas nos prim eiros sistemas UNIX e são am plam ente usadas em sistem as operacionais baseados no UNIX. A API W in32 é a interface da M icrosoft para aplicações executadas em am biente Windows. Processos executam chamadas a funções definidas pela API para acessar serviços fornecidos por um a cam ada mais baixa do sistema. Essas cham adas à função podem em itir chamadas ao sistema para requisitar serviços do sistem a operacional. Cham adas ao sistem a são análogas a interrupções por dispositivos de hardware — quando ocorre um a cham ada ao sistema, esse passa para o m odo núcleo, e o sistem a operacional é executado para atender à cham ada ao sistema. R to/U ão' 1. Por que os processos devem em itir cham adas ao sistem a para requisitar serviços ao sistem a operacional? 2. Com o o POSIX tenta m elhorar a portabilidade de aplicação? R eip a itã i: 1) Para proteger o sistema, o sistem a operacional não pode perm itir que processos acessem diretam ente serviços do sistem a operacional ou instruções privilegiadas. Em vez disso, os serviços que um sistem a operacional pode fornecer são Aplicação API Espaço do usuário Espaço do núcleo ____________ L J __________ Interface de chamada ao sistema - Memória j Disco 17 Interface, de,programação de, aplicação (API). Rede S istem as ojaerasioftass 5a em pacotados em APIs. Processos podem acessar esses serviços som ente por meio da interface de cham ada ao sistem a que, essencialm ente, põe o sistem a operacional no controle. 2) Softwares escritos usando uma determ inada API som ente podem ser executados em sistem as que im plem entam a m esm a API. POSIX tenta atacar esse problem a especificando um a API padrão para sistem as baseados em UNIX. A té m esm o m uitos sistem as não baseados em UNIX agora suportam POSIX. 2.8 Cotn^Uação, ligação &carregamento Antes que um program a escrito em linguagem de alto nível possa ser executado, deve ser traduzido para linguagem de máquina, ligado a vários outros program as em linguagem de m áquina dos quais depende e carregado na memória. N esta seção examinamos a maneira com o programas escritos em linguagens de alto nível são compilados em código de linguagem de m áquina e descrevem os com o ligadores e carregadores preparam código com pilado para execução.36 2 .8 .1 C ô tK fH Ü içã ô Em bora cada tipo de com putador possa entender som ente sua própria linguagem de m áquina, quase todos os program as são escritos em linguagens de alto nível. O prim eiro estágio do processo de criação de program as executáveis é com pilar a linguagem de program ação de alto nível para linguagem de máquina. Um com pilador aceita código-fonte escrito em um a linguagem de alto nível com o entrada e devolve código-objeto contendo as instruções de execução em linguagem de m áquina com o resultado. Praticam ente todos os program as disponíveis no com ércio são entregues em código-objeto e algum as distribuições (software de fonte aberto) tam bém incluem o código-fonte.37 O processo de com pilação pode ser dividido em várias fases; um a visão da com pilação é apresentada na Figura 2.8. Cada fase modifica o program a para que ele possa ser interpretado na fase seguinte, até que o program a tenha sido traduzido para código de m áquina. Prim eiro o código-fonte é passado pelo analisador léxico (tam bém conhecido com o lexer ou scanner) que separa os caracteres do fonte de um program a em símbolos (tokens). Entre os exemplos de sím bolos, estão palavras-chave (por exemplo, if, else e int), identificadores (por exem plo, variáveis e constantes nom eadas), operadores (por exemplo, -, +, * e í) e pontuação (por exemplo, ponto-e-vírgula). O analisador léxico passa essa cadeia de sím bolos para o analisador sintático (tam bém denom inado parser) que agrupa os sím bolos em com andos sintaticam ente corretos. O gerador de código intermediário converte essa estrutura sintática em uma cadeia de instruções sim ples que se assem elha à linguagem de m ontagem (em bora não especifique os registradores usados para cada operação). O otimizador tenta m elhorar a eficiência de execução do código e reduz os requisitos de m em ória do programa. N a fase final o gerador de código produz o arquivo-objeto contendo as instruções em linguagem de m áquina.38,39 R e rtiã o ' 1. Qual a diferença entre com pilação e m ontagem ? 2. Um program a em Java podería ser executado diretam ente em um a m áquina real, em vez de virtual? 1) O processo de montagem sim plesm ente traduz instruções em linguagem de montagem para linguagem de máquina. Um com pilador traduz código de linguagem de alto nível para código de linguagem de m áquina e tam bém pode otim izar o código. 2) Um program a em Java pode ser executado em um a m áquina real usando um com pilador que transform a o código-fonte em Java, ou bytecode, na linguagem de m áquina correspondente. Código-fonte Linguagem de baixo nível !.S fases da, com^ilaçãs. Cafdtulo 2 2 .8 .2 Côttceitos d&hardware, e, software, 53 L ig a ç ã o Program as usualm ente consistem em diversos subprogram as desenvolvidos independentem ente, cham ados módulos. Funções que executam rotinas com uns de com putador com o m anipulações de E/S ou geração de números aleatórios são em pacotadas em m ódulos pré-com pilados denom inados bibliotecas. Ligação (linking) é o processo que integra os vários m ódulos referidos por um program a em um a única unidade executável. Q uando um program a é com pilado, seu m ódulo-objeto correspondente contém dados e instruções de program a recu­ perados do arquivo-fonte do programa. Se o program a se referir a funções ou dados de um outro m ódulo, o com pilador os traduz com o referências externas. Além disso, se o program a disponibilizar funções ou dados para outros programas, cada um deles é representado por um nome externo. M ódulos-objeto arm azenam essas referências e nomes externos em um a estrutura de dados denom inada tabela de símbolos (Figura 2.9). O m ódulo integrado produzido pelo ligador é denom inado módulo de carga. As entradas para o ligador podem ser módulos-objeto, módulos de carga e com andos de controle, com o a localização de arquivos de bibliotecas que são referidos.40 É com um o ligador ser fornecido com diversos arquivos-objeto que formam um único programa. Esses arquivos nor­ malm ente especificam as localizações de dados e instruções por meio de endereços relativos ao início de cada arquivo denom inados endereços relativos. N a Figura 2.10 o sím bolo X no m ódulo-objeto A e o sím bolo Y no m ódulo-objeto B têm o mesmo endereço relativo em seus respectivos módulos. O ligador deve modificar esses endereços de modo que eles não se refiram a dados ou instruções inválidas quando os m ódulos forem com binados para form ar um program a ligado. A realocação de endereços assegura que cada com ando seja identificado inequivocam ente por um endereço dentro de um arquivo. Q uando um endereço é m o­ dificado, todas as referências a ele devem ser atualizadas com a nova localização. No módulo de carga resultante, X e Y foram realocados para novos endereços relativos que são exclusivos dentro do m ódulo de carga. M uitas vezes os ligadores tam bém fornecem endereçam ento relativo no m ódulo de carga; todavia, os endereços são designados de tal m odo que todos eles são relativos ao início de todo o m ódulo de carga. Ligadores tam bém executam resolução de símbolos, que converte referências externas de um m ódulo a seus nomes externos correspondentes em outro módulo.41,42 Na Figura 2.11 a referência externa ao sím bolo C no m ódulo-objeto 2 é resolvida com o nom e externo C do m ódulo-objeto 1. U m a vez que uma referência externa seja em parelhada com o nome correspondente em um m ódulo separado, o endereço da referência externa deve ser modificado para refletir essa integração. A ligação muitas vezes ocorre em duas passagens. A prim eira determ ina o tam anho de cada módulo e m onta um a tabela de símbolos. A tabela de sím bolos associa cada sím bolo (com o o nome de um a variável) a um endereço, para que o ligador possa localizar a referência. N a segunda passagem o ligador designa endereços a diferentes unidades dc instruções e dados e resolve referências externas a sím bolos .43 Com o o m ódulo de carga pode se tom ar a entrada de uma outra passagem de ligação, ele contém um a tabela de sím bolos na qual todos os sím bolos são nomes externos. N ote que, na Figura 2.11, a referência externa ao sím bolo Y não aparece na tabela de sím bolos do m ódulo porque foi resolvida. O m omento em que um program a é ligado depende do am biente. Um program a pode ser ligado no m omento da com ­ pilação se o program ador incluir todo o código necessário no arquivo-fonte de m odo que não haja referências a nomes externos, o que é realizado procurando-se no código-fonte por quaisquer sím bolos referidos extem am ente e colocando esses sím bolos no arquivo-objeto resultante. Esse método norm alm ente não é exeqüível, porque m uitos program as dependem Módulos fig u ra , 2.9 \ Módulo-objeto. 54 Sistemas oj^eraciotuiis Resolve endereços relativos e referências internas ^ Todas as referências a código e dados são ajustadas às novas localizações Tabela de símbolos FujUfOs 2. 10 Processo d&ligação. Módulo-objeto 1 Módulo-objeto 2 Referência à C Código Código Dados Dados Tabela de símbolos Tabela de símbolos Nome externo A B C Referência externa Y Nome externo X Y Z Referência externa A C n Ligação \S fig u ra , 2.11 Resolução símbolos. CaçútuJô 2 Conceitos de hardware e software 55 de bibliotecas compartilhadas, que são coleções de funções que podem ser com partilhadas entre processos diferentes. M uitos program as podem se referir às m esm as funções (como funções de biblioteca que m anipulam entrada e saída se­ riais de caracteres) sem incluí-las no seu código-objeto. Esse tipo de ligação é tipicam ente executada após a com pilação e antes do carregamento. Com o discutido no quadro “M iniestudo de caso, M ach”, bibliotecas com partilhadas habilitam o m icronúcleo M ach a em ular vários sistemas operacionais. E sse m esm o processo pode ser executado em tem po de carregam ento (veja a Seção 2.8.3, “C arregam ento” ). Às vezes, ligação e carregam ento são am bos executados por um a aplicação denom inada carregador de ligação. A ligação som ente pode ocorrer em tem po de execução, um processo denom inado ligação dinâmica. N esse caso, referências a funções externas não são resolvidas até que o processo seja carregado na m em ória ou em ita um a cham ada à função. Isso é útil para program as grandes que usam program as controlados por um a terceira parte, porque um program a li­ gado dinam icam ente não tem de ser religado quando um a biblioteca que ele usa é m odificada.44 E m ais, pelo fato de program as ligados dinam icam ente não serem ligados até que estejam na m em ória principal, o código com partilhado da biblioteca pode ser arm azenado separadam ente de outro código de program a. A ssim , a ligação dinâm ica tam bém econom iza espaço na m em ória secundária, pois apenas um a cópia de um a biblioteca com partilhada é arm azenada para qualquer núm ero de program as que a usarem . RevU cuy 1. Com o a ligação facilita o desenvolvim ento de grandes program as m ontados por muitos desenvolvedores? 2. Cite um a possível desvantagem da utilização de um ligador dinâm ico. Cite um benefício. Reipoifai: 1) Ligação perm ite que program as sejam escritos com o m uitos m ódulos separados. O ligador com bina esses m ódulos em um m ódulo final de carregam ento quando todas as partes do program a tiverem sido com piladas. 2) Se um a biblioteca não puder ser encontrada durante a execução, um program a em execução será forçado a parar, possivelm ente perdendo todo o trabalho realizado até aquele ponto. U m benefício é que program as dinam icam ente ligados não têm de ser religados quando um a biblioteca é modificada. 2.8.3 CarregaMiento U m a vez que o ligador tenha criado o m ódulo de carga, ele passa-o para o program a carregador. O carregador é res­ ponsável por colocar cada instrução e dado em um endereço de m em ória particular, um processo denom inado vinculação Ac C & êO M acU O sistema Mach foi desenvolvi­ que discutiremos no Capítulo 21 ).4748 49 Uma implementação de fonte do na Universidade Carnegie-Mellon aberto, o GNU Mach, é usado como (CMU), de 1985 a 1994, e teve núcleo para o sistema operacional como base o Accent, um sistema GNU Hurd, que está no momento operacional de pesquisa anterior da CMU.45 O projeto foi dirigido por em desenvolvimento.50 Richard Rashid, agora vice-presiden­ Uma poderosa capacidade do te sênior da M icrosoft Research.46 sistem a de m icronúcleo Mach é O Mach foi um dos prim eiros e que ele pode emular outros siste­ m ais bem -conhecidos sistem as mas operacionais. O Mach faz isso operacionais de micronúcleo (veja usando 'bibliotecas transparentes a Seção 1.13.3, "A rq uite tura de com partilhadas'.51 Uma biblioteca micronúcleo"). Foi incorporado em transparente compartilhada imple­ sistem as posteriores, entre eles menta as ações para as chamadas Mac OS X, NeXT e OSF/1, e teve ao sistema do sistem a operacio­ forte influência sobre o W indows nal que está emulando e, então, intercepta chamadas ao sistem a NT (e, afinal, sobre o W indows XP, feitas por programas escritos para executar no sistem a operacional emulado.52' 53 As chamadas ao sis­ tema interceptadas podem ser tra­ duzidas para chamadas ao sistema Mach, e quaisquer resultados são traduzidos novamente para a forma em ulada.54* 55 Assim , o programa do usuário não tem de ser portado para executar em um sistema que está executando o M ach. Além disso, qualquer número dessas bi­ bliotecas transparentes pode ser guardado na m em ória, de modo que o Mach pode em ular vários sistemas operacionais simultanea­ m ente.56 56 S is te m a s o ^ e ra x ío n a ts de endereço. H á diversas técnicas para carregar program as na m em ória principal, a m aioria delas é im portante apenas para sistemas que não suportam m em ória virtual. Se o módulo de carga já especificar endereços físicos na memória, o carregador sim plesm ente coloca as unidades de instrução e dados nos endereços especificados pelo program ador ou com pilador (su­ pondo que os endereços de m em ória estejam disponíveis), um a técnica cham ada carregamento absoluto. Carregamento realocável é realizado quando o m ódulo de carga contiver endereços relativos que precisam ser convertidos para endereços de m em ória real. O carregador é responsável por requisitar um bloco de espaço de m em ória no qual colocar o programa, realocando, em seguida, os endereços do program a para que correspondam à sua localização na memória. N a Figura 2.12, o sistem a operacional alocou o bloco de m em ória que com eça com o endereço de m em ória 10.000. À m edida que o program a é carregado, o carregador deve adicionar 10.000 a cada endereço no m ódulo de carga. O carre­ gador atualiza o endereço de m em ória da variável Exemplo da Figura 2.12 para 10.450 com base no seu endereço relativo original 450. Carregamento dinâmico é a técnica que carrega m ódulos de program a na prim eira utilização.57 Em m uitos sistemas de m em ória virtual é designado a cada processo seu próprio conjunto de endereços virtuais com eçando em zero, portanto o carregador fica responsável por carregar o program a em um a região de m em ória válida. Revisamos todo o processo de com pilação, ligação e carregam ento (usando vinculação de endereço em tempo de carregam ento) desde o código-fonte até a execução na Figura 2.13. O program ador com eça escrevendo o código-fonte em algum a linguagem de alto nível — neste caso, C. Em seguida o com pilador transform a os arquivos de código-fonte foo.c e bar.c em linguagem de m áquina criando os m ódulos-objeto foo.o e bar.o. No código, o program ador definiu a variável X em foo.c e a variável Y em bar.c; am bas estão localizadas no endereço relativo 100 em seus respectivos m ódulos-objeto. Os m ódulos-objeto são colocados em arm azenam ento secundário até que sejam requisitados pelo usuário ou por outro processo, quando então os m ódulos devem ser ligados. N a próxim a etapa, o ligador integra os dois m ódulos em um único m ódulo de carga. O ligador realiza essa tarefa coletando inform ações sobre tam anhos de m ódulos e sím bolos externos na prim eira passagem e ligando os arquivos na segunda. N ote que o ligador realoca a variável Yao endereço relativo 400. N a terceira etapa, o carregador requisita um bloco de m em ória para o programa. O sistem a operacional fornece um a faixa de endereços de 4000 a 5050, portanto o carregador realoca a variável Xpara o endereço absoluto 4100 e a variável Ypara o endereço absoluto 4400. R etidão1. Com o o carregam ento absoluto pode lim itar o grau de m ultiprogram ação de um sistem a? 2. Com o o carregam ento dinâm ico aprim ora o grau de m ultiprogram ação de um sistema? 1) Dois program as que especificam endereços sobrepostos não podem executar ao mesmo tem po, porque som ente um pode residir na m esm a localização de m em ória por vez. 2) M ódulos são carregados conform e a necessidade, portanto a m em ória contém apenas os m ódulos que são utilizados. 10.000 0 Código Código 300 10,300 Carregamento Dados Dados Exemplo 450 t\> /r j _____________ ] [ !. 12 Carregamento. Exemplo 10,450 nJ ry ] [ _____________ I Qgútuio 2 Conceitos dc hardware, e, software, 57 | fig u ra , 2.13 Comjgilaçao, ligação e, carregamento. 2.9 Firmware, Além do hardw are e do software, a m aioria dos com putadores contém firmware, instruções executáveis armazenadas em m em ória persistente, quase sempre som ente de leitura, ligada a um dispositivo. Firm ware é program ado com microprogramação, um a cam ada de program ação abaixo da linguagem de m áquina de um computador. O microcódigo (instruções de m icroprogam a) norm alm ente inclui instruções sim ples, fundam entais, necessárias para implementar todas as operações em linguagem de máquina.58Por exemplo, uma instrução de m áquina típica pode especificar que o hardw are execute um a operação de adição. O m icrocódigo para essa instrução especifica as operações primitivas que o hardw are deve executar, com o increm entar o ponteiro que aponta para a instrução de m áquina atual adicionando cada bit dos números, arm azenando o resultado em um novo registrador e buscando a próxim a instrução.59,60 O professor M aurice W ilkes, criador do primeiro com putador EDS AC, foi quem prim eiram ente introduziu os conceitos de microprogram ação em 1951.61 Contudo, só quando surgiu o IBM System /360 em 1964 é que o microcódigo foi utilizado em grande escala. Conjuntos de instruções de m áquina im plem entados em microcódigo atingiram o ápice com o sistema operacional VAX, mas declinaram nos últim os anos, porque a execução de instruções em m icrocódigos lim ita a veloci­ dade m áxim a de um processador. Assim , operações anteriorm ente executadas por instruções em m icrocódigo agora são realizadas pelo hardw are de processador.62 Hoje, m uitos dispositivos de hardware, entre eles discos rígidos e dispositivos periféricos, contêm processadores em miniatura. As instruções desses processadores são com um ente im plem entadas por meio de m icrocódigo.63 Revíião' 1. (V/F) Não há instruções m enores do que em linguagem de máquina. 2. D escreva o papel do firmware em um sistem a de computador. Reípoitài: 1) Falso. O m icrocódigo especifica uma cam ada de program ação abaixo da linguagem de m áquina de um processador. 2) O firmware especifica instruções sim ples, fundam entais, necessárias para im plem entar instruções em linguagem de máquina. 2.10 Middleware, O software desem penha um papel im portante em sistem as distribuídos nos quais com putadores são ligados através de um a rede. Os com putadores que com põem um sistem a distribuído usualm ente são heterogêneos — utilizam hardwares diferentes, executam sistemas operacionais diferentes e se com unicam por meio de diferentes arquiteturas de rede usando vários protocolos de rede. A natureza dos sistem as distribuídos requer um middleware para habilitar interações entre os diversos processos executados em um ou mais com putadores através de uma rede. O middleware perm ite que uma aplicação executada em um com putador com unique-se com uma aplicação executada em um com putador remoto, habilitando com unicações entre com putadores em sistemas distribuídos. O middleware também perm ite que aplicações sejam executadas em plataform as de com putação heterogêneas, contanto que cada com putador tenha o middleware instalado. O middleware simplifica o desenvolvim ento de aplicações porque os desenvolvedores não 58 Sistemas oj^eraciotuiis precisam conhecer os detalhes da m aneira com o ele executa suas tarefas e, portanto, podem se concentrar em desenvolver programas em vez de desenvolver protocolos de comunicação. Conectividade aberta para banco de dados (Open DataBase Connectivity — ODBC) é um exem plo de API para acesso a bancos de dados, que perm ite que aplicações acessem bancos de dados por meio de middleware, denom inado unidade de ODBC. Ao desenvolverem tais aplicações, desenvolvedores precisam fornecer apenas o banco de dados com o qual a aplicação deve se conectar. A unidade de ODBC adm inistra a conexão com o banco de dados e a recuperação da inform ação requisitada pela aplicação. D a Seção 17.3.1, “M iddleware” , à Seção 17.3.4, “CORBA (Com m on Object Request Broker A rchitecture)”, são abordadas im plem entações e protocolos com uns de middleware que formam a espinha dorsal de muitos sistemas distribuídos. Revtáur 1. Q uais os custos e benefícios da utilização de middleware? 2. Com o o m iddleware facilita a construção de sistemas heterogêneos? # 1) M iddlew are prom ove m odularidade de program a e facilita program ação de aplicações, porque o desenvolvedor não precisa escrever código para gerenciar interações entre processos. Entretanto, a com unicação entre m iddlew are e processos incorre em custos adicionais em com paração com a com unicação direta. 2) M iddlew are facilita a com unica­ ção entre com putadores que usam protocolos diferentes traduzindo m ensagens para form atos diferentes à m edida que passam entre transm issor e receptor. R e s íU ftô Um sistem a operacional é prim ariam ente um geren­ ciador de recursos, portanto o projeto desses sistem as está intim am ente ligado aos recursos de software e hardware que devem gerenciar. U m a PCB é um com ponente de hardw are que fornece conexões elétricas entre dispositivos em vários lugares da placa. A placa principal é a PCB à qual estão ligados dispo­ sitivos com o processadores e m em ória principal. U m processador é um com ponente de hardw are que executa um fluxo de instruções em linguagem de máquina. A CPU é um processador que executa as instruções de um program a; um co-processador executa instruções de uso específico (como gráficos ou áudio) eficientemente. Neste livro usam os o term o ‘processador’ para nos referirm os à CPU. Registradores são m em órias de alta velocidade lo­ calizadas em um processador e que retêm dados para uso im ediato do processador. Antes que um processador possa operar com os dados, esses devem ser colocados em regis­ tradores. O com prim ento da instrução é o tamanho de uma instrução em linguagem de máquina; alguns processadores suportam vários com prim entos de instrução. Tempo de com putador é medido em ciclos; cada ciclo representa um a oscilação com pleta de um sinal elétrico fornecido pelo gerador de relógio do sistema. Velocidades de processador são com um ente m edidas em G H z (bilhões de ciclos por segundo). A hierarquia da m em ória é um esquem a de categorização, que posiciona a m em ória mais rápida e mais cara no topo e a mais lenta e menos dispendiosa em baixo. Tem um formato íngreme, piramidal, no qual a m em ória do registrador ocupa o nível m ais alto da hierarquia, seguida da m em ória cache L I , m em ória cache L2, m em ória principal, arm azenam ento secundário e arm azenam ento terciário. A m em ória principal de um sistem a é o arm azenam ento de dados de nível m ais baixo da hierarquia da m em ória à que o processador pode se referir diretamente. A m em ória principal é volátil, o que significa que ela perde seu conteúdo quando o sistem a é desligado. A rm a­ zenam ento secundário, com o discos rígidos, CD s, DVDs e discos flexíveis, arm azena persistentem ente grandes quantidades de dados a um custo baixo por unidade de armazenamento. Barram ento é um conjunto de conexões elétricas del­ gadas cham adas pistas que transportam inform ações entre dispositivos de hardware. U m a porta é um barram ento que conecta dois dispositivos. Canais de E/S são com ponentes de uso específico dedicados a tratar E/S, independentemente dos processadores principais do sistem a do computador. Dispositivo periférico é um hadw are que não é requi­ sitado por um com putador para executar instruções. Im ­ pressoras, scanners e mouses são dispositivos periféricos; processadores e m em ória principal não são. Existem alguns hardw ares especificam ente destinados a m elhorar o desem penho e sim plificar o projeto de siste­ mas operacionais. Sistem as de com putador em geral têm diversos estados diferentes de execução. Para aplicações de usuário, o subconjunto de instruções que o usuário pode executar em m odo usuário im pede, por exem plo, a execução direta de instruções de entrada/saída. O sistem a operacional ordinariam ente executa com o estado usuário m ais confiável em m odo núcleo; em m odo núcleo um pro­ cessador pode executar instruções privilegiadas e acessar CaçútuJô 2 recursos para executar tarefas em nom e dos processos. Proteção da m em ória, que im pede que processos acessem m em ória que não lhes foi designada (com o a m em ória de outros usuários e a m em ória do sistem a operacional), é im plem entada por m eio de registradores de processa­ dor que podem ser m odificados som ente por instruções privilegiadas. A m aioria dos dispositivos envia um sinal denom inado interrupção ao processador quando ocorre um evento. O sistem a operacional pode responder a um a m udança no status do dispositivo notificando os processos que esperam por esses eventos. E/S program ada (PIO) é um a técnica pela qual um pro­ cessador tom a-se ocioso enquanto são transferidos dados entre um dispositivo e a m em ória principal. Ao contrário, o acesso direto à m em ória (DM A) habilita dispositivos e controladores a transferir diretam ente blocos de dados de e para a m em ória principal, o que libera o processador para executar instruções de software. Interrupções perm item que o hardw are envie sinais ao processador, que notifica a interrupção ao sistem a opera­ cional. O sistem a operacional decide que ação executar em resposta à interrupção. Um com putador contém vários tipos de relógios e temporizadores. Um tem porizador de intervalo é útil para evitar que um processo m onopolize um processador. A pós um intervalo designado, o tem porizador gera uma interrupção para atrair a atenção do processador; com o resultado dessa interrupção o processador pode então ser designado a uma outra aplicação. O relógio de 24 horas segue o ‘horário de relógio norm al’. Autocarregam ento (bootstrapping) é o processo de car­ regamento dos com ponentes iniciais do sistema operacional na memória. Esse processo é realizado pelo BIOS de um computador. Tecnologia plug-and-play perm ite que sistem as ope­ racionais configurem um hardw are recém -instalado sem interação do usuário. Para suportar plug-and-play, um dis­ positivo de hardw are deve identificar-se inequivocamente no sistem a operacional, com unicar-se com o sistem a ope­ racional para indicar os recursos e serviços que ele requer para funcionar adequadam ente, e identificar o driver que suporta o dispositivo e perm ite que o software o configure (por exemplo, designa o dispositivo a um canal de DMA). Caches são m em órias relativam ente rápidas projeta­ das para aum entar a velocidade de execução do program a m antendo cópias de dados que serão acessadas dentro de pouco tem po. Exem plos de caches são os caches de processador L I e L2 e o cache da m em ória principal para discos rígidos. Um buffer é um a área de arm azenam ento tem porário que guarda dados durante transferências de E/S. A m em ó­ ria de buffer é usada prim ariam ente para coordenar com u­ nicação entre dispositivos que estão funcionando em velo­ cidades diferentes. Buffers podem arm azenar dados para processam ento assíncrono, coordenar entrada/saída entre dispositivos que funcionam com velocidades diferentes ou perm itir que sinais sejam entregues assincronam ente. Conceitos dc kardwture, e, software, 59 Spooling é um a técnica de buffering (arm azenam ento tem porário) pela qual um dispositivo interm ediário, com o um disco, é interposto entre um processo e um dispositivo de baixa velocidade ou de E/S lim itado por buffer. O spoo­ ling perm ite que os processos requisitem operações de um dispositivo periférico sem exigir que o dispositivo esteja pronto para atender à requisição. Linguagem de m áquina, linguagem de m ontagem e linguagens de alto nível são três tipos de linguagem de programação. Linguagens de m áquina consistem em ca­ deias de números (reduzidos a ls e Os) que instruem os com putadores a executar suas operações m ais elementares. U m com putador pode entender som ente sua própria lingua­ gem de máquina. Linguagens de montagem representam instruções de linguagem de m áquina usando abreviaturas sem elhantes a palavras em inglês. Linguagens de alto nível perm item que program adores escrevam instruções que se assem elham ao inglês do dia-a-dia e contenham notações m atem áticas comuns. Linguagens de alto nível cum prem tarefas mais substanciais com um núm ero m enor de co­ m andos, mas exigem program as tradutores denom inados com piladores para converter program as em linguagem de alto nível para linguagem de máquina. C, C++, Java e C# são exemplos de linguagens de alto nível. Hoje, linguagens de alto nível tendem a ser de dois tipos, linguagens de program ação estruturadas e linguagens de program ação orientadas a objeto. Program ação estruturada é uma abordagem disciplinada para a criação de programas claros, corretos e fáceis de modificar. Pascal e Fortran são linguagens de program ação estruturadas. Program as orien­ tados a objeto concentram -se na m anipulação de objetos (substantivos) para criar softw are reutilizável, fácil de modificar e entender. C++, C # e Java são linguagens de program ação orientadas a objeto. APIs perm item que um program a requisite serviços de um sistem a operacional. Program as cham am funções API que podem acessar o sistema operacional fazendo chamadas ao sistema. Antes que um program a escrito em linguagem de alto nível possa ser executado, deve ser traduzido para código de m áquina e carregado na memória. Com piladores convertem código em linguagem de alto nível para código de m áqui­ na. Ligadores designam endereços relativos a diferentes program as ou unidades de dados e resolvem referências externas entre subprogramas. Carregadores convertem esses endereços em endereços físicos e colocam o program a ou unidades de dados na m em ória principal. A maioria dos computadores contém firmware que espe­ cifica instruções de software que fazem parte, fisicamente, de um dispositivo de hardware. Grande parte dos firmwares é programada com microprogramação, ou seja, um a camada de program ação abaixo da linguagem de m áquina de um computador. Middleware habilita comunicação entre vários processos executados em um ou m ais com putadores através de uma rede. Ele facilita a construção de sistemas distribuídos he­ terogêneos e sim plifica program ação de aplicações. 60 Sistemas oj^eraciotuiis Exercícios 2.1 2.2 Qual a diferença entre hardware, software e firmware? Dados os seguintes dispositivos de hardware: i. placa principal ii. processador iii. barramento iv. memória v. disco rígido vi. dispositivo periférico vii. dispositivo de armazenamento terciário viii. registrador ix. cache indique quais desses dispositivos é melhor definido por cada uma das seguintes opções. (Alguns itens podem ter mais de uma resposta.) a. executa instruções de programa b. não é requerido para que um computador execute ins­ truções de programa c. meio de armazenamento volátil d. a PCB que conecta os processadores de um sistema à memória, ao armazenamento secundário e a dispositivos periféricos e. memória mais rápida de um sistema de computador f. conjunto de pistas que transmite dados entre dispositivos de hardware g. memória rápida que melhora o desempenho da apli­ cação h. nível mais baixo de memória na hierarquia da memória, à qual um processador pode se referir diretamente 2.3 Velocidades de processadores vêm dobrando aproximada­ mente a cada 18 meses. O desempenho geral do computador dobrou à mesma taxa? Por que sim ou por que não? 2.4 Classifique a lista seguinte da memória mais rápida e mais cara para a memória mais lenta e menos dispendiosa: armazenamen­ to secundário, registradores, memória principal, armazenamento terciário, cache L2, cache L l. Por que sistemas contêm diversos armazéns de dados de diferentes tamanhos e velocidades? Qual a motivação que está por trás do caching? 2.5 Cite alguns custos e benefícios da utilização de RAM não volátil em todos os caches e na memória principal. 2.6 Por que é importante suportar arquiteturas legadas? 2.7 Relacione o princípio do menor privilégio com os conceitos de modo usuário, modo núcleo e instruções privilegiadas. 2.8 Descreva diversas técnicas de implementação de proteção da memória. 2.9 Buffering duplo é uma técnica que permite que um canal de E/S e um processador funcionem em paralelo. Na entrada de buffer duplo, por exemplo, enquanto um processador consome um conjunto de dados em um buffer, o canal lê o próximo conjunto de dados para outro buffer de modo que os dados (espera-se) estejam prontos para o processador. Explique detalhadamente como um esquema de buffer triplo poderia funcionar. Em que circunstâncias o buffering triplo seria efetivo? 2.10 Descreva duas técnicas diferentes para tratar as comunica­ ções entre um processador e dispositivos. 2.11 Explique como o DMA melhora o desempenho do sistema e o roubo de ciclos. 2.12 Por que é apropriado que controladores de canal roubem ciclos de processadores quando acessam memória? 2.13 Explique o conceito de spooling e por que é útil. Como você acha que funciona um sistema de entrada por spooling projetado para ler cartões perfurados de uma leitora de cartões? 2.14 Considere os seguintes tipos de linguagens de programação: i. linguagem de máquina ii. linguagem de montagem iii. linguagem de alto nível iv. linguagem de programação orientada a objeto v. linguagem de programação estruturada Indique quais dessas categorias é mais bem definida por cada uma das seguintes opções. (Alguns itens podem ter mais de uma resposta.) a. concentra-se em manipular coisas (substantivos) b. requer um programa tradutor para converter o código em algo que algum processador específico possa entender c. é escrita usando ls e Os d. define uma abordagem disciplinada para o desenvolvi­ mento de software e concentra-se em ações (verbos) e. especifica operações básicas de computador usando como instruções abreviaturas parecidas com palavras em inglês f. Java e C++ g. Fortran e Pascal h. permite que programadores escrevam código usando palavras inglesas do dia-a-dia e notação matemática 2.15 Descreva brevemente como um programa escrito em uma linguagem de alto nível é preparado para execução. 2.16 Quais as semelhanças e diferenças entre carregadores ab­ solutos e carregadores realocáveis. Cite diversas motivações para o conceito de carregamento realocável. 2.17 O que é microprogamação? Por que o termo ‘firmware’ é apropriado para descrever microcódigo que faz parte de um dis­ positivo de hardware? Projetos sugeridos 2.18 Elabore um trabalho de pesquisa sobre MRAM, uma forma de RAM não volátil (consulte www.research.ibm.com/resources/news/ 20030610_mram.shtml). 2.19 Elabore um trabalho de pesquisa sobre armazenamento MEMS (MicroElectroMechanical System), um dispositivo de armazenamento secundário que pretende melhorar tempos de acesso em discos rígidos (visite www.pdl.cmu.edu/MEMS). 2.20 Pesquise a diferença entre a interface SCSI e a interface IDE para dispositivos de armazenamento secundário. Por que a IDE tomou-se a opção mais popular? 2.21 Elabore um trabalho de pesquisa sobre o projeto e a imple­ mentação da estrutura .NET da Microsoft. ÜLjútulo 2 Côttceitos de hardware e software, 61 Notas 1. 2. 3. 4. 5. 6. 7. 8. D. A. Wheeler, “More than a gigabuck: estimating GNU/ Linux’s size”, 30 jun. 2001, atualizado em 29 jul. 2002, versão 1.07, www.dwheeler.com/sloc/. S. Gilheany, “Evolution of Intel microprocessors: 1971 to 2007”, Berghell Associates, 28 mar. 2002, www.berghell.com/ whitepapers/Evolution%20of%20lntel%20Microprocessors%201971 %20to% 202007.pdf. “Processors”, PCTechGuide, www.pctechguide.com/02procs.htm. “Registers”, PCGuide , w w w .p cg u id e .co m /re f/cp u /a rch /in t/ compRegisters-c.html. 27. default.asp. 28. 29. 30. 10. 31. 17 a b r. 2 0 0 1 , www.pcguide.com/intro/fun/clock.htm. 33. 12. 13. 14. 15. buffer.html. 32. 34. ref/hdd/. “System bus functions and features” , P C G uide, (computer_software). “Hard disk drives”, PCGuide, 17 abr. 2001, www.pcguide.com/ D. Gifford e A. Spector, “Case study: EBM’s system/360-370 architecture”, Communications ofthe ACM, v. 30, nu4, abr. 1987, p. 291-307. “ P C I express”, PCI-SIG, www.pcisig.com/specifications/pciexpress/. T. A. Scott, “Illustrating programmed and interrupt driven I/O”, Proceedings o f the Seventh Annual CCSC Midwestern Conference on Small Colleges, out. 2000, p. 230-238. J. Hennessy e D. Patterson, Computer organizjation and design. São Francisco: Morgan Kaufmann Publishers, 1998, p. 680-681. “DMA channel function and operation”, PCGuide.com, 35. 36. 37. “Peripheral device”, Webopedia, 14 dez. 2 0 0 1, www.webopedia. “Serial port”, CNET Glossary, www.cnet.com/Resources/lnfo/ 18. “Serial port”, CNET Glossary, www.cnet.com/Resources/lnfo/ 19. GlossaryAerms/serialport.html. “ U S B ” , Computer Peripherals, peripherals.about.com/library/ glossary/bldefusb.htm. 38. 39. 21. 22. 23. 24. 25. 26. “IDE/ATA vs. SCSI: interface drive com parison” , PCGuide.com, www.pcguide.com/ref/hdd/if/comp.htm. 40. 41. 42. 43. 44. 45. showdoc.html?i=l 791 &p=2. L. Presser e J. White, “Linkers and loaders”, ACM Computer Surveys, v. 4, na 3, set. 1972, p. 153. J. Levine, Linkers and loaders. São Francisco: Morgan Kaufman Publishers, 2000, p. 5. L. Presser e J. White, “Linkers and loaders”, ACM Computer Surveys, v. 4, na 3, set. 1972, p. 164. J. Levine, Linkers and loaders. São Francisco: Morgan Kaufman Publishers, 2000, p. 6. L. Presser e J. White, “Linkers and loaders”, ACM Computer Surveys, v. 4, na 3, set. 1972, p. 151. Carnegie-Mellon University, “The mach project home page”, 21 fev. 1 9 9 7 , www-2.cs.cmu.edu/afs/cs/project/mach/public/ www/mach.html. 46. Microsoft Corporation, “Microsoft-Press pass rick rashid biography”, 2003, w w w .m icrosoft.com /presspass/exec/rick/ default.asp. 47. I. Westmacott, “The UNIX vs. NT Myth”, jul. 1997, webserver.cpg.com/wa/2.6. 48. “ S C S I F A Q ” , www.faqs.org/faqs/scsi-faq/partl/. www.scsita.org/aboutscsi/termsTermin.html. D. Gifford e A. Spector, “Case study: IBM’s system/360-370 architecture”, Communications ofthe ACM, v. 30, na 4, abr. 1987, p. 291-307. P. Denning, “Virtual memory”, ACM Computing Surveys, v. 2, na 3, set. 1970, p. 153-189. “Intel developer forum day 3 — more from the tech showcase”, Anandtech.com, 20 fev. 2003, www.anandtech.com/ A. Aho e J. Ullman, Principies of compiler design. Reading, MA: Addison Wesley, 1977, p. 6-7. “Compiler”, IBM Reference/Glossary, www -l.ibm .com /ibm / history/reference/glossary_c.html. P. Liu e D. Thompson, “IEEE 1394: changing the way we do multimedia Communications”, IEEE Multimedia, abr. 2 0 0 0 , www.computer.org/multimedia/articles/firewire.htm. L. Presser e J. White, “Linkers and loaders”, ACM Computer Surveys, v. 4, na 3, set. 1972, p. 149-151. “Object code”, 7 abr. 2001, whatis.techtarget.com/definition/ 0„sid9_gci539287/00.html. GlossaryAerms/serialport.html. 20. “Spooling”, Sun Product Documentation: Glossary, Solaris 2.4 System Administrator AnswerBook, docs.sun.com/db/doc/ 801 -6 6 28/óil 08opae?a=view. com/TERM/P/peripheral_device.html. 17. “Definition: buffer”, FS-1037,23 ago. 1996, www.its.bldrdoc.gov/ fs-1037/dir-005/_0739.htm. www.pcguide.com/ref/mbsys/res/dma/func.htm. 1 6. “Buffer”, Webopedia, I a set. 1 9 9 7 , www.webopedia.comAERM/B/ R. L. Glass, “An elementary discussion of compiler/interpreter writing”, ACM Computing Surveys (CSUR), v. 1, na 1, jan. 1969. “Interpreter (Computer software)”, Wikipedia, The Free Encyclopedia, 19 fev. 2 0 0 3 , www.wikipedia.org/wiki/lnterpreter_ www.pcguide.com/ref/mbsys/buses/func.htm. 11. A. Smith, “Cache memories”, ACM Computing Surveys, v. 14, na 3, set. 1982, p. 473-530. “Buffer”, Data Recovery Glossary, www.datarecoverygroup.com/ glossary/buffer.html. read.php?artide_id=5000172. 9. “Plug and play for Windows 2000 and Windows XP”, Microsoft Windows Platform Development, 21 mar. 2003, www.microsoft.com/hwdev/tech/PnP/PnPNT5_2.asp. “PowerPC microprocessor family: programming environments manual for 64- and 32-bit microprocessors, ver. 2.0”, IBM, 10 jun. 2003. “Clock signals, cycle time and frequency”, PCGuide.com, “IA-32 Intel architecture software developer’s manual”, System Programmer’s Guide, v. 1, 2002, p. 41. J. De Gelas, “A ce’s guide to memory technology” , Ace's Hardware, 13 jul. 2000, www.aceshardwore.com/Spades/ “Plug and play technology”, Microsoft Windows Platform Development, 21 mar. 2 0 0 3 , www.microsoft.com/hwdev/tech/pnp/ Carnegie-Mellon University, “The mach project home page”, 21 fev. 1997, www-2.cs.cmu.edu/afs/cs/project/mach/public/ www/mach.html. 49. Apple Computer, Inc., “Mac OS x Technologies-Darwin”, 2 0 0 3 , www.apple.com/macosx/technologies/darwin.html. 50. Free Software Foundation, “GNU Mach”, 26 maio 2003, www.gnu.org/software/hurd/gnumach.html. 51. R. Rashid et al., “Mach: a system software Kernel”, Proceedings o f the 1989 IEEE International Conference, COMPCON 89, fev. 1989, ftp://ftp.cs.cmu.edu/project/mach/doc/ published/syskernel.ps. 69 52. StitwuisoperncíôKAÍs G. Coulouris, J. Dollimore e T Kindberg, “UNIX Emulation in Mach and Chorus”. In: Distributed systems: concepts and design. Reading, MA: Addison Wesley, 1994, p. 597-584, 57. 58. www.cdk3.net/oss/Ed2/UNIXEmulation.pdf. 53. R. Rashid et al., “Mach: a system software Kemel”, Proceedings o f the 1989 IEEE International Conference, COMPCON 89, fev. 1989, ftp://ftp.cs.cmu.edu/project/mach/doc/ 59. published/syskernel.ps. 54. 55. 56. G. Coulouris, J. Dollimore e T Kindberg, “UNIX emulation in Mach and Chorus’’. In: Distributed systems: concepts and design. Reading, MA: Addison Wesley, 1994, p. 597-584, 60. www.cdk3.net/oss/Ed2/UNIXEmulation.pdf. 61. R. Rashid et al., “Mach: a system software Kernel”, Proceedings o f the 1989 IEEE International Conference, COMPCON 89, fev. 1989, ftp://ftp.cs.cmu.edu/project/mach/doc/ published/syskernel.ps. 62. R. Rashid et al., “Mach: a system software Kemel”, Proceedings o f the 1989 IEEE International Conference, COMPCON 89, fev. 1 9 8 9 , ftp://ftp.cs.cmu.edu/project/mach/doc/ 63. published/syskernel.ps. L. Presser e J. White, “Linkers and loaders”, ACM Computer Surveys, vol. 4, n2 3, set. 1972, p. 150. J. Hennessy e D. Patterson, Computer organization and de­ sign. São Francisco: Morgan Kaufmann Publishers, 1998, p. 399-400. T. Rauscher e P. Adams, “Microprogramming: a tutorial and survey of recent developments”, IEEE Transactions on Computers, v. C-29, n2 1, jan. 1980, p. 2-20. J. Hennessy e D. Patterson, Computer organization and de­ sign. São Francisco: Morgan Kaufmann Publishers, 1998, p. 424-425. M. Wilkes, “The best way to design an automatic calculating machine”, Report ofthe Machine University Computer Inaugural Conference, Manchester University, jul. 1951, p. 16-18. J. Hennessy e D. Patterson, Computer organization and de­ sign. São Francisco: Morgan Kaufmann Publishers, 1998, p. 424-425. “Firmware”, PCGuide, 17 abr. 2 0 0 1 , www.pcguide.com/ref/hdd/ op/logicFirmware-c.html. ? b h f \ ô i 'Troemos t tkrm ds Era* surpreendente* que* a, N atureza* tivesse*prosseguido trajujüilajueute* com* seu* dourado processo em* m eio a*ta n ta s diabruras. Stephen Crane ara conseguir desempenho máximo e atenderás necessidades dos usuários, os sistemas operacionais executam muitas atividades simultaneamente usando as abstrações de processo e thread para manter o controle das atividades paralelas. Nos seis capítulos seguintes, você estudará como sistemas operacionais gerenciam processos e threads para garantir que coexistam pacificamente, cooperem sem percalços e não colidam uns com os outros enquanto se ocupam de suas tarefas. Você aprenderá a escrever suas próprias aplicações Java deform a multithread. A s vezes processos e threads precisam esperar quando há alguma contenda por recursos — você estudará adiamento indefinido e deadlock (impasse) — , problemas que podem sobrevir se entidades que estão à espera não forem gerenciadas adequadamente. Para manter processos e threads progredindo eficientemente, você aprenderá como sistemas operacionais planejam o uso de seu mais valioso recurso de hardware: processadores. P Não há*naAa*studs indispenscurtlem*negócios d*o que* o despacho. Joseph Addison CdKcdtd clt trocem ! Aprenda, a, trabalhar e,a, esperar. Henry W adsworth Longfellow M uitos correrão para, lá e,para, cá) e, o conhecim ento aumentará* Daniel 12:2 Vote, acordará) e, lem brará, e, entenderá* Robert Browning Este capítulo apresenta: • O conceito de um processo. • O ciclo de vida de um processo. • Estados de processo e transições de estado. • Blocos de controle de processos (PCBs) / descritores de processos. • Como processadores transitam entre processos via chaveamento de contexto. • Como interrupções habilitam o hardware a se comunicar com o software. • Como processos conversam uns com os outros via comunicação interprocessos (IPC). Processos UNIX. 66 S U tw u is o j m m ío h a j U 3.1 Introdução M uitos sistem as na natureza têm a capacidade de realizar várias ações ao m esm o tempo. Por exemplo, o corpo hum ano realiza uma grande variedade de operações em paralelo — ou, com o diremos, concorrentemente. Respiração, circulação do sangue, digestão, pensar, andar, por exemplo, podem ocorrer concorrentem ente. De modo semelhante, todos os senti­ dos — visão, tato, olfato, paladar e audição — podem acontecer sim ultaneam ente. O s com putadores tam bém executam operações concorrentem ente. E com um um com putador de m esa (desktop) com pilar um programa, enviar um arquivo a um a im pressora, exibir um a página Web, apresentar um videoclipe digital e receber m ensagens de correio eletrônico con­ correntem ente (veja o quadro “Reflexões sobre sistem as operacionais, Afinal, os clientes querem aplicações”). Neste capítulo apresentam os form alm ente o conceito de processo, fundam ental para entender com o os sistem as de com putador atuais realizam e controlam muitas atividades simultâneas. A presentam os algum as das definições mais po­ pulares de processo. Introduzim os o conceito de estados de processo distintos e discutim os com o e por que processos transitam entre esses estados. Abordam os tam bém várias operações que os sistem as operacionais realizam para atender aos processos, com o criar, destruir, suspender, retom ar e acordar processos. 3.1.1 Vefuáção de-processo O term o ‘processo’ no contexto de sistem as operacionais foi usado pela prim eira vez pelos projetistas do sistem a M ultics na década de 60 (veja o “M iniestudo de caso, CTTS e M ultics” e no site do livro a “Biografia, Fernando J. Corbató”).' D esde aquela época o term o processo, de certo m odo usado intercam biavelm ente com tarefa, já havia ganho muitas definições como: um program a em execução; um a atividade assíncrona; o ‘espírito anim ado’ de um procedim ento; o ‘locus de controle’ de um procedim ento em execução; aquilo que é m anifestado pela existência de uma estrutura de dados denom inada ‘descritor de processo’ ou ‘bloco de controle de processo’ no sistem a operacional; aquela entidade às quais os processadores são designados; e a unidade ‘de despacho’. Um program a é para um processo o que a partitura é para a orquestra sinfônica. R # f G oW ô 0 ^e X à ,C \0 \A<\\G Ajuiai, os clientes sjuerenc aplicações Em última instância, computa­ dores existem para executar aplica­ ções úteis. Projetistas de sistemas operacionais podem perder isso de vista porque tendem a se preocupar com questões técnicas complexas de a rq u ite tu ra e engenharia de sistem as operacionais. Mas eles não podem operar no vácuo; pre­ cisam conhecer sua comunidade de usuários; os tipos de aplicações que esses usuários estarão execu­ tando e que resultados realmente querem dessas aplicações. As lojas de hardware vendem muitas ferra­ mentas para ajudar você a cumprir tarefas comuns. O projetista de fer­ ramentas precisa estar consciente de que são poucas as pessoas interessadas em sim p le sm e n te comprar ferramentas; ao contrário, elas compram as ferramentas para as tarefas que realizam. Na verda­ de, os clientes não querem serras, m achados e fu ra d e ira s — eles querem cortar, pregar madeira e fazer orifícios. C<XGO CTTS e, M ultics No início da década de 1960, uma equipe de programadores do Projeto MAC do MIT, liderada pelo professor Fernando Corbató, desen­ volveu o sistema de tem po com ­ partilhado compatível ( C o m p a t i b l e - CTSS) que permitia aos usuários controlar a ca­ pacidade de computação de um IBM 7090 (que eventualmente tornou-se um IBM 7094) por meio de term i­ nais semelhantes a uma máquina T im e -S h a rin g S y s t e m de escrever.2-3 O CTSS executava um fluxo de lote convencional para manter o computador trabalhando enquanto dava respostas rápidas a usuários interativos que editavam e depuravam programas. As capa- (continua) Capítulos Conceito de,processos fa j (continuação) cidades de computação fornecidas pelo CTSS assem elhavam -se às fornecidas hoje aos usuários de computadores pessoais — ou seja, um ambiente altamente interativo no qual o computador dá respostas rápidas a grandes números de requi­ sições relativamente triviais. Em 1965 o mesmo grupo do MIT, em cooperação com o Bell Labs e a GE, começou a trabalhar no sistem a operacional M u ltics (Multiplexed Information and Computing Service) o sucessor do CTSS. O Multics era um sistema grande e complexo; os projetistas imagina­ ram uma utilidade de computação de uso geral que podia ser do tipo 'tudo para todos'. Embora não te­ nha alcançado sucesso comercial, foi usado por vários centros de pesquisa até que o último sistema foi desligado em 2000.4 Uma variedade de característi­ cas do Multics influenciou o desen­ volvimento de sistemas operacio­ nais futuros, entre eles o UNIX, o TSS/360, o TENEX e o TOPS-20.5 O Multics usava uma combinação de segmentação e paginação para seu sistema de memória virtual, sendo a paginação controlada somente pelo sistema operacional, enquanto seg­ mentos também eram tratados por programas de usuários.6 Foi um dos primeiros sistemas operacionais a ser escrito em uma linguagem de programação de sistemas de alto nível, a PL/I da IBM7 8. Seus projetis­ tas cunharam o termo 'processo' do modo como é usado correntemente em sistemas operacionais. O Mul­ tics foi construído para ser seguro. Possuía um mecanismo de acesso discricionário denominado A C L ( A c ­ c e s s C o n t r o l L i s t , lista de controle de acesso), uma lista de permissões em um segmento de memória que os usuários do UNIX achariam fami­ liar. Versões posteriores incluíam um controle de acesso obrigatório, AIM ( A c c e s s I s o l a t i o n M e c h a n i s m , me­ canismo de isolamento de acesso), um aperfeiçoamento do ACL pelo qual eram designados níveis de segurança a todos os usuários e objetos, o que ajudou o Multics a se tornar o primeiro sistema opera­ cional a conseguir uma classificação de segurança B2 do governo dos Es­ tados Unidos.9*10-11Em 1976 foi escri­ to o primeiro sistema comercial de banco de dados relacionai, o Multics Relational Data Store .12 H á dois conceitos fundam entais apresentados por essas definições. Primeiro, um processo é uma entidade. C ada proces­ so tem seu próprio espaço de endereço, que norm alm ente consiste em um a região de texto, um a região de dados e um a região de pilha. A região de texto arm azena o código que o processador executa. A região de dados arm azena variáveis e m em ória alocada dinam icam ente, que o processo usa durante a execução. A região de pilha arm azena instruções e variá­ veis locais para cham adas ativas ao procedim ento. O conteúdo da pilha cresce à m edida que um processo em ite chamadas aninhadas ao procedim ento, e diminui quando o procedim ento cham ado retom a.13 Segundo, um processo é ‘um programa em execução\ Um program a é uma entidade inanim ada; som ente quando um processador lhe ‘sopra vida’ é que ele se tom a a entidade ativa que cham am os de processo. Rwiião' 1. Por que o espaço de endereço de um processo é dividido em várias regiões? 2. (V/F) Os term os ‘processo’ e ‘program a’ são sinônimos. R eip o i& i 1 1) Cada região de um espaço de endereço com um ente contém inform ações que são acessadas de um modo similar. Por exemplo, a m aioria dos processos lê e executa instruções, mas não modifica suas instruções. Processos lêem e escrevem de e para a pilha, mas na ordem ‘últim o a entrar, prim eiro a sair’. Processos lêem e escrevem dados em qualquer ordem . Separar o espaço de endereço de um processo em diferentes regiões habilita o sistem a operacional a im por essas regras de acesso. 2) Falso. U m processo é um program a em execução; um program a é um a entidade inanimada. 3.2 Estudos de processo: ciclo de tridu de unoprocesso O sistem a operacional deve assegurar que cada processo receba uma quantidade suficiente de tem po de processador. Em qualquer sistema, o núm ero de processos verdadeiram ente executados em concorrência é obrigatoriam ente igual ao núm ero de processadores mas, em geral, há um núm ero m uito m aior de processos do que de processadores em um sistema. Portanto, a qualquer dado instante, alguns processos podem ser executados, outros não. Durante seu tem po de vida um processo passa por um a série de estados de processo distintos. Vários eventos podem fazer que um processo mude de estado. D iz-se que um processo está executando (ou seja, no estado de execução) se esti­ ver executando em um processador. Diz-se que um processo está pronto (ou seja, em estado ‘de pronto ’) quando podería executar em um processador se houvesse algum disponível. D iz-se que um processo está bloqueado (ou seja, no estado bloqueado) se estiver esperando que algum evento aconteça (tal com o um evento de conclusão de E/S, por exemplo) antes de poder prosseguir. Há outros estados de processo, mas, por enquanto, vam os nos concentrar nesses três. 68 Sistemas operacionais Por questão de simplicidade, considerarem os um sistema uniprocessador, em bora a extensão para o multiprocessamento (veja o Capítulo 15, “G erenciam ento de m ultiprocessador”) não seja difícil. Em um sistem a uniprocessador apenas um processo pode ser executado por vez, mas diversos outros podem estar prontos e diversos, bloqueados. O sistem a operacio­ nal mantém um a lista de prontos, de processos prontos, e um a lista de bloqueados, de processos bloqueados. A lista de prontos é organizada por ordem de prioridade, de m odo que o processo seguinte a receber o processador será o prim eiro da lista (o processo de prioridade m ais alta). A lista de bloqueados é tipicam ente desordenada — os processos não se tom am desbloqueados (ou seja, prontos) na ordem de prioridade; são desbloqueados na ordem em que ocorrem os eventos pelos quais estão esperando. Com o verem os mais adiante, nesses casos é com um priorizar os processos em espera. Ren/U ãc 1. (V/F) A qualquer dado instante som ente um processo pode executar instruções em um computador. 2. Um processo entra no estado de bloqueado quando esta esperando que um evento ocorra. Cite diversos eventos que podem fazer um processo entrar em estado de bloqueado. R cipQ étãi! 1) Falso. U m com putador m ultiprocessador pode ter tantos processos em execução quantos são os pro­ cessadores. 2) U m processo pode entrar em estado de bloqueado se em itir um a requisição de dados localizados em um dispositivo de latência alta, tal com o um disco rígido, ou requisições de um recurso que está alocado a um outro processo e indisponível naquele m om ento (por exem plo, um a im pressora). Um processo tam bém pode ficar bloqueado até que ocorra um evento, com o a utilização de teclado ou a m ovim entação do m ouse pelo usuário. 3.3 gerenciamento processo Com o o sistem a operacional intercala a execução de seus processos, deve gerenciá-los cuidadosam ente para assegurar que não ocorra nenhum erro quando eles são interrom pidos e retom ados. O s processos devem poder com unicar-se com o sistem a operacional para executar tarefas sim ples com o iniciar um novo processo ou sinalizar o fim da execução do processo. N esta seção discutirem os com o sistem as operacionais prestam certos serviços fundam entais aos processos — entre os quais criar processos, destruir processos, suspender processos, retom ar processos, alterar a prioridade de um processo, bloquear processos, acordar processos, despachar processos, capacitar processos para interagir via com unica­ ção interprocessos (Interprocess Com m unication — IPC) e outros. D iscutirem os tam bém com o sistem as operacionais gerenciam recursos de processos para perm itir que vários processos disputem ativam ente o tem po do processador ao m esm o tempo. 3.3.1 Estados de,processos e, estados d&transição Q uando um usuário executa um programa, processos são criados e inseridos na lista de prontos. U m processo vai pas­ sando para o topo da lista à m edida que outros concluem sua vez de usar o processador. Q uando um processo chega ao topo da lista e há um processador disponível, aquele processo é designado a um processador e diz-se que ele fez um a transição de estado, passando do estado de pronto para o estado de execução (Figura 3.1). O ato de designar um processador ao prim eiro processo da lista de prontos é denom inado despacho, e é realizado por um a entidade do sistem a denom inada despachante. D iz-se que processos que estão nos estados de pronto ou de execução estão acordados porque disputam ativamente tem po de processador. O sistem a operacional gerencia transições de estado para m elhor servir aos processos no sistema. Para evitar que qualquer um dos processos m onopolize o sistema, acidental ou m aliciosam ente, o sistem a operacional estabelece um relógio de interrupção em hardware (tam bém denom inado temporizador de intervalo) que perm ite que o processo execute durante um intervalo de tempo específico ou quantum. Se o processo não devolver o processador voluntariam ente antes que o intervalo de tem po expire, o relógio de interrupção gera um a interrupção, fazendo que o sistem a operacional obtenha o controle do processador (veja Seção 3.4 “Interrupções”). Então o sistem a operacional muda o estado do processo, que estava anteriorm ente em execução, para pronto e despacha o prim eiro processo da lista de prontos, m udando seu estado de pronto para em execução. Se um processo em execução iniciar um a operação de entrada/ saída antes do seu quantum expirar e, conseqüentem ente, tiver de esperar que a operação E/S seja concluída antes de poder usar o processador novamente, o processo em execução entregará voluntariam ente 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. D iz-se que processos no estado bloqueado estão adorm ecidos porque não podem executar mesmo que um processador fique disponível. O único outro estado de transição perm itido em nosso modelo de três estados ocorre quando uma operação de E/S (ou algum outro evento pelo qual o processo esteja esperando) é concluído. Nesse caso o sistem a operacional prom ove a transição do processo do estado bloqueado para o estado de pronto. Definimos quatro estados de transição possíveis. Q uando um processo é despachado, ele transita de pronto para em execução. Q uando o quantum de um processo expira, ele transita de em execução para pronto. Q uando um processo é Capítulos Acordado Conceito de processos faÇ Adormecido Despertar 1 PUjuras 3 .1 Transições de estado de processos. bloqueado, ele transita de em execução para bloqueado. Por fim, quando um processo acorda devido à conclusão de algum evento pelo qual está esperando, ele transita de bloqueado para pronto. N ote 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 sistem a operacional. N esta seção assum im os que o sistem a operacional designa um quantum a cada processo. A lguns sistem as operacionais mais antigos, que executavam com processadores que não dispunham de relógios de interrupção, em pregavam multitarefa cooperativa, significando que cada processo deve devolver voluntariam ente o processador no qual está executando antes que um outro processo possa executar. Entretanto, m ultitarefa cooperativa é raram ente usada nos sistem as atuais porque perm ite que processos monopolizem um processador, acidental ou maliciosam ente (por exemplo, entrando em laço infinito ou sim plesm ente recusando-se a entregar o processador na hora certa). R cvU cu y 1. Com o o sistem a operacional im pede que um processo m onopolize um processador? 2. Qual a diferença entre processos que estão acordados e processos que estão adorm ecidos? R d p O ità ll 1) Um relógio de interrupção gera uma interrupção após um quantum de tem po especificado, e o sistema operacional despacha um outro processo para executar. O processo interrom pido executará novam ente quando alcançar o topo da lista de prontos e um processador ficar disponível novamente. 2) Um processo acordado está disputando ativamente um processador; um processo adorm ecido não pode usar um processador mesmo que haja um disponível. 3.3.2 Blocos de, controle, de,processos ( PCBs) / Vescrctores de,processo O sistem a operacional norm alm ente executa diversas operações quando cria um processo. Prim eiro, deve ser capaz de identificar cada processo; portanto, designa ao processo um número de identificação de processo {Process Identifica­ tion N um ber - PID). Em seguida o sistem a operacional cria um bloco de controle de processo {Process Control Block - PCB), tam bém denom inado descritor de processo, que mantém as inform ações que o sistem a operacional necessita para gerenciar o processo. O s PCBs com um ente incluem inform ações como: • PID • estado do processo (por exemplo, em execução, pronto ou bloqueado) • contador de programa (um valor que determ ina qual instrução o processo deve executar em seguida) • prioridade de escalonam ento • credenciais (dados que determ inam os recursos que esse processo pode acessar) • um ponteiro para o processo-pai (o processo que criou esse processo) SUtwuis ojteraxiottabç 70 • • • ponteiros para os processos-filho (processos criados por esse processo), caso existam ponteiros para localizar os dados e instruções do processo na m em ória ponteiros para recursos alocados (tais com o arquivos) O PCB tam bém arm azena o conteúdo dos registradores, denom inado contexto de execução, do processador no qual o processo estava executando da últim a vez, quando fez a transição de saída do estado de execução. O contexto de execução de um processo é específico da arquitetura, mas inclui, tipicam ente, o conteúdo de registradores de uso geral (que contêm dados de processo que o processador pode acessar diretam ente), além de registradores de gerenciam ento de processo, com o registradores que arm azenam ponteiros para o espaço de endereço de um processo. Isso habilita o sistem a operacional a restaurar o contexto de execução de um processo quando esse voltar ao estado de execução. Q uando um processo transita de um estado para outro, o sistem a operacional tem de atualizar inform ações no PCB do processo. N orm alm ente o sistem a operacional m antém ponteiros para cada PCB do processo em um a tabela de processo no âm bito total do sistem a ou por usuário, para poder acessar o PCB rapidam ente (Figura 3.2). A tabela de processo é um a das muitas estruturas de dados dos sistem as operacionais que discutim os neste texto (veja o quadro “Reflexões sobre sistem as operacionais, Estruturas de dados em sistemas operacionais”). Quando um processo é encerrado (voluntariam ente ou pelo sistem a operacional), o sistem a operacional libera a m em ória e outros recursos do processo, retira o processo da tabela de processos e disponibiliza sua m em ória e outros recursos para outros processos. Discutirem os outras funções de manipulação de processo no m om ento oportuno.14 R evU cu r 1. Qual a finalidade da tabela de processos? 2. (V/F) A estrutura de um PCB depende da im plem entação do sistem a operacional. Reipoííài 3.3.3 1) A tabela de processos habilita o sistema operacional a localizar o PCB de cada processo. 2) Verdadeiro. Operações processo Sistemas operacionais devem ser capazes de executar certas operações de processo, entre elas: • criar um processo • destruir um processo • suspender um processo • retom ar um processo • alterar a prioridade de um processo Tabela de processo | PujurA/ 3.2 Tabela, de,processo e, blocos de, controle, de,processo. Capítulo 3 Conceito de processos yj Reflexões $o\?cz sm em Aê o^&tac\o\aa\$ Eítruturas de, dados ewosistemas opwaxiôftais E stu d a n te s de ciê ncia da com putação em geral estudam e s tru tu ra s de dados em várias disciplinas do curso, tanto como tópico principal, quanto como par­ te de vários cursos avançados de computação, como compiladores, bancos de dados, redes e sistemas operacionais. Estruturas de dados são usadas abundantem ente em sistem as operacionais. Filas são utilizadas sem pre que entidades • • • • precisam esperar — processos esperando por um processador, requisições de E/S esperando que os dispositivos fiquem disponíveis, processos esperando por acesso às suas seções críticas e assim por diante. Pilhas são usadas para suportar o mecanismo de retorno da cham ada à fu nçã o . Á rvo re s são empregadas para representar estruturas de diretório de sistemas de arquivos, para controlar a aloca­ ção de espaço em disco a arquivos, para montar estruturas hierárquicas de diretórios de página para suporte de tradução de endereços virtuais e assim por diante. Grafos são usados quando se estudam organizações de redes, grafos de alocação de recursos de deadlock (impasse) e coisas sem elhantes. Tabelas de hash são utilizadas para acessar PCBs rapidamente (usando um PI D como chave). bloquear um processo acordar um processo despachar um processo habilitar um processo a se com unicar com outro (denom inado com unicação interprocessos) U m processo pode gerar um novo processo. Se o fizer, o processo criador é denom inado processo-pai, e o processo criado é denom inado processo-filho. Cada processo-filho é criado por exatam ente um processo-pai, criação que leva a um a estrutura hierárquica de processos sem elhante à da Figura 3.3, na qual cada filho tem som ente um pai (por exem plo, A é o único pai de C; H é o único pai de I), mas cada pai pode ter m uitos filhos (por exem plo, B, C e D são os filhos de A; F e G são os filhos de C). Em sistem as baseados em U N IX , com o o Linux, são gerados m uitos processos do processo inity que é criado quando o núcleo é carregado (Figura 3.4). No Linux, entre esses processos, figuram ksw apd, xfs e Jchubd — processos que executam operações de gerenciam ento de m em ória, sistem a de arquivos e dispositivos, respectivam ente. M uitos desses processos são discutidos m ais adiante no C apítulo 20, “E studo de caso: L inux” . O pro­ cesso login autentica usuários para o sistem a operacional, o que é norm alm ente realizado solicitando-se a um usuário que digite um nom e de usuário válido e a senha correspondente. D iscutirem os outros m eios de autenticação no C apítulo 19, 0/3.3 | H ierarquia, d e criação d e processo. S is te m a s o v a c io n a is 72 PujUTA/ 3 .4 | Hierarquia^ aUprocesso no Linux.. “Segurança” . A ssim que o processo logiti autentica o usuário, ele gera um interpretador de com andos (shell), tal com o um bash (Ztoume-again s/iell), que perm ite ao usuário interagir com o sistem a operacional (Figura 3.4). Então o usuário pode em itir com andos ao interpretador de com andos para executar program as com o o vi (um editor de texto) e o fin g er (um utilitário que exibe inform ações do usuário). D estruir um processo envolve rem ovê-lo do sistem a. A m em ória e ou­ tros recursos do processo são devolvidos ao sistem a e ele é expurgado das listas ou tabelas de quaisquer sistem as, e seu bloco de controle de processo é apagado, ou seja, o espaço de m em ória do PCB é disponibilizado para outros processos no sistem a. A destruição de um processo é m ais com plicada quando ele gerou outros processos. Em alguns sistem as operacionais cada processo gerado é destruído autom aticam ente quando seu pai é destruído; em outros, processos gerados prosseguem independentem ente de seus pais, e a destruição desses não tem nenhum efeito sobre seus filhos. A lterar a prioridade de um processo norm alm ente envolve modificar o valor de prioridade no bloco de controle do processo. D ependendo de com o o sistem a operacional im plem enta o escalonam ento de processo, pode ser preciso colocar um ponteiro para o PCB em um a fila de prioridade diferente (veja o Capítulo 8, “Escalonam ento de processador” ). As outras operações citadas nesta seção serão explicadas em seções subseqüentes. R evU ão' 1. (V/F) Um processo pode ter um núm ero zero de processos-pai. 2. Por que é vantajoso criar uma hierarquia de processos em vez de um a lista encadeada? R eipaíG u l 1) Verdadeiro. O primeiro processo criado, geralm ente denom inado init em sistemas UNDÍ, não tem um pai. E também, em alguns sistemas, quando um processo-pai é destruído, seus filhos prosseguem independentes, sem seu pai. 2) U m a hierarquia de processos perm ite que o sistem a operacional controle os relacionam entos pai/filho entre processos, o que sim plifica operações com o localizar todos os processos-filho de um determ inado processo-pai quando esse for extinto. 33A Suspender &retomar M uitos sistem as operacionais perm item que adm inistradores, usuários ou processos suspendam um processo. Um processo suspenso é retirado indefinidam ente da disputa por tem po em um processador sem ser destruído. Historicam ente, essa operação perm itia que um operador do sistem a ajustasse m anualm ente a carga do sistem a e/ou reagisse a am eaças de falha de sistema. Hoje, a m aioria dos com putadores executa dem asiado rapidam ente para perm itir tais ajustes manuais. Contudo, um adm inistrador ou usuário que suspeite dos resultados parciais de um processo pode suspendê-lo (em vez de abortá-lo) até que o usuário possa certificar-se de que o processo esteja funcionando corretamente, o que é útil para detectar am eaças à segurança (como execução mal-intencionada) e para finalidades de depuração de software. A Figura 3.5 exibe o diagram a de transição de estado de processo da Figura 3.1 modificado para incluir transições de suspensão e retomada. Foram adicionados dois novos estados, suspenso-pronto e suspenso-bloqueado. A cim a da linha pontilhada da figura estão os estados ativos; abaixo estão os estados suspensos. Uma suspensão pode ser iniciada pelo processo que está sendo suspenso ou por um outro processo. Em um sistema uniprocessador, um processo em execução pode suspender a si mesmo, indicado pela Figura 3.5(a); nenhum outro processo podería estar executando no mesmo momento para em itir a suspensão. Um processo em execução também pode suspender um processo pronto ou um processo bloqueado, mostrado na Figura 3.5(b) e (c). Em um sistema multiprocessador, um processo em execução pode ser suspenso por um outro processo que esteja executando naquele momento em um processador diferente. Capítulo 3 Conceito de,processos 73 Estados ativos Estados suspensos P i^ur0 /3 .5 Transições d e estado d e processo cone suspensão &retom ada. Fica claro que um processo suspende a si mesmo somente quando estiver em estado de execução. Nessa situação, o pro­ cesso transita do estado em execução para suspenso-pronto. Quando um processo suspende um processo pronto, o processo pronto transita de pronto para suspenso-pronto. U m processo suspenso-pronto pode ser passado para pronto, ou retom ado, por um outro processo, o que causa a transição do primeiro processo de suspenso-pronto para pronto. U m processo bloqueado fará a transição de bloqueado para suspenso-bloqueado quando for suspenso por um outro processo. Um processo suspensobloqueado pode ser retomado por um outro processo e fazer a transição de bloqueado-suspenso para bloqueado. Pode-se argum entar que, em vez de suspender um processo bloqueado, é m elhor esperar até que ocorra a conclusão da E/S ou do evento e o processo tom e-se pronto; assim, ele podería ser suspenso para o estado suspenso-pronto. Infelizm ente, a conclusão pode não ocorrer nunca ou ser atrasada indefinidamente. O projetista deve escolher entre realizar a suspensão do processo bloqueado ou criar um m ecanism o pelo qual a suspensão será feita a partir do estado pronto, quando a E/S ou o evento forem concluídos. Com o a suspensão é tipicam ente um a atividade de alta prioridade, ela é executada im edia­ tamente. Q uando por fim ocorrer a conclusão da E/S ou do evento (se, de fato, ocorrer), o processo suspenso-bloqueado fará a transição de suspenso-bloqueado para suspenso-pronto. R ei/U õc 1. Q uais são as três maneiras pelas quais um processo pode chegar ao estado suspenso-pronto? 2. Em qual cenário é m elhor suspender um processo em vez de abortá-lo? R eip o itã i l l)U m processo pode chegar ao estado suspenso-pronto se for suspenso do estado em execução; se for suspenso do estado pronto por um processo em execução; ou se estiver no estado suspenso-bloqueado e ocorrer a conclusão da E/S ou do evento pelo qual está esperando. 2) Quando um usuário ou administrador de sistema suspeitar do comportamento de um processo, mas não quiser perder o trabalho realizado pelo processo, é melhor suspender o processo para poder examiná-lo. 3.3.5 CluuwMteHto d& contexto O sistem a operacional realiza um ch av eam en to de co n tex to para interrom per um processo em execução e com eçar a executar um processo previam ente pronto.15 Para realizar um chaveam ento de contexto, o núcleo deve prim eiram ente 74 S U tW iA S O jM T ílcio tU lti salvar o contexto de execução do processo em execução no PCB desse processo e, então, carregar o contexto de execução anterior do processo pronto a partir do PCB desse últim o (Figura 3.6). Chaveam entos de contexto, essenciais em am bientes de m ultiprogram ação, propõem diversos desafios ao projeto do sistem a operacional. U m a das razões é que chaveam entos de contexto devem ser essencialm ente transparentes para os processos, o que significa que os processos não percebem que foram removidos do processador. Durante o chaveam ento de contexto um processador não pode realizar nenhum a com putação ‘útil’— ou seja, ele executa tarefas essenciais para sistem as operacionais, mas não executa instruções em nom e de nenhum determ inado processo. Chaveam ento de contexto é puro custo adicional e ocorre tão freqüentem ente que os sistem as operacionais devem m inim izar o tempo de chaveam ento de contexto. O sistema operacional acessa PCBs freqüentemente; em conseqüência, muitos processadores contêm um registrador em hardware que indica o PCB do processo que esta atualmente em execução para facilitar o chaveamento de contexto. Quando o sistema operacional inicia um chaveamento de contexto, o processador armazena o contexto de execução do processo que está em execução no momento, em segurança no PCB, o que impede que o sistema operacional (ou outros processos) escrevam sobre os valores dos registradores do processo. Processadores simplificam e aceleram ainda mais o chaveamento de contexto fornecendo instruções que salvam e restauram o contexto de execução de um processo de e para seu PCB, respectivamente. N a arquitetura IA-32, o sistem a operacional despacha um novo processo especificando a localização de seu PCB na memória. Então o processador realiza um chaveamento de contexto salvando o contexto de execução do processo que estava em execução anteriorm ente. A arquitetura IA-32 não fornece instruções para salvar e restaurar o contexto de execução de um processo, porque o processador executa essas operações sem intervenção do softw are.16 R et/U ão' 1. A partir de onde um sistem a operacional carrega o contexto de execução para o processo a ser despachado durante um chaveam ento de contexto? 2. Por que um sistem a operacional deve m inim izar o tem po requerido para realizar um chaveam ento de contexto? R e ip o ifa iii) As inform ações de contexto do processo a ser despachado são arm azenadas em seu PCB. 2) Durante um chaveam ento de contexto um processador não pode executar instruções em nom e de processos, o que pode reduzir o rendimento. 3A Interrupções Com o discutido no Capítulo 2, “Conceitos de hardware e software”, interrupções habilitam o software a responder a sinais do hardware. O sistem a operacional pode especificar um conjunto de instruções, denom inado tr a ta d o r de in ter- Processo Pi executa no processador Processador nn m Após uma interrupção, o núcleo decide despachar um novo processo e inicia um chaveamento de contexto 11 m 0 núcleo armazena o contexto de execução do Processo P1 em seu PCB na memória r PCB do Processo P1 Processador PCB do processo I I I I I I I í Processador Processo P2 executa no processador .6 Cfun/eamento contexto. 0 núcleo carrega o contexto de execução do Processo P2 do seu PCB na memória P2 Capítulos Conceito de,processos 7$ ru p ç ã o , a ser executado em resposta a cada tipo de interrupção. Isso perm ite que o sistem a operacional obtenha o controle do processador para gerenciar recursos do sistema. U m processador pode gerar um a interrupção com o resultado da execução das instruções de um processo (nesse caso, geralmente, é denom inada de desvio (trap) e considerada com o sín c ro n a em relação à operação do processo). Por exemplo, ocorrem interrupções síncronas quando um processo tenta realizar um a ação ilegal, com o dividir por zero ou se referir a um a localização de m em ória protegida. Interrupções tam bém podem ser causadas por algum evento não relacionado com a instrução corrente do processo (caso em que são denom inadas assín cro n as em relação à execução do processo; veja o quadro “Reflexões sobre sistemas operacionais, A ssincronia versus sincronia”). D ispositivos de hardw are em item interrupções assíncronas para com unicar um a m udança de status ao processador. Por exem plo, o teclado gera um a interrupção quando um usuário pressiona uma tecla; o mouse gera um a interrupção ao ser m ovim entado ou quando um de seus botões é pressionado. Interrupções é um m eio de baixo custo de conseguir a atenção de um processador. U m a alternativa às interrupções é um processador inquirir repetidam ente o estado de cada dispositivo. Essa abordagem, denom inada sondagem (polling), aum enta a sobrecarga à medida que am plia a com plexidade do sistem a de computador. Interrupções eliminam a necessidade de um processador sondar dispositivos repetidamente. Um exem plo simples da diferença entre sondagem e interrupção pode ser visto nos fom os de m icroondas. Um c h e f pode regular a parada de um tem porizador após tantos minutos (o tem porizador em ite um som quando o intervalo de tem ­ po chega ao fim, interrom pendo o chef), ou inspecionar o assado periodicam ente através do vidro do fom o para verificar quando está pronto (esse tipo de m onitoração regular é um exem plo de sondagem). Sistemas orientados à interrupção podem ficar sobrecarregados — se as interrupções chegarem muito rapidamente, o sistem a poderá não conseguir acompanhá-las. U m controlador de tráfego aéreo, por exemplo, podería facilm ente ficar sobrecarregado no caso de m uitos aviões convergirem para uma área estreita. Em sistemas de rede, a interface de rede contém um a pequena quantidade de m em ória na qual arm azena cada pacote de dados que recebe de outros com putadores. Toda vez que recebe um pacote, a interface de rede gera um a interrupção para inform ar a um processador que os dados estão prontos para processam ento. Se o processador não puder processar os dados da interface de rede antes de a m em ória da interface ficar cheia, podem -se perder pacotes. Os sistem as tipicam ente organizam filas para reter interrupções que serão processadas quando o processador ficar disponível. Essas filas, é claro, consom em m em ória cujo tam anho é limitado. Subm etido a um a carga pesada, o sistem a talvez não consiga enfileirar todas as interrupções que chegam , o que significa que algum as seriam perdidas. Rm ão' 1. O que significa interrupção síncrona? 2. Cite uma alternativa para interrupção e explique por que raram ente é usada. R c f l c x c c ç $o\?C C 0 ^& C A6\0W<X\Ç AxütcroituovwsiM fütcroftuo Quando dizemos que eventos ocorrem assincronamente em re­ lação à operação de um processo significa que acontecem indepen­ dentem ente do que se passa no processo. Operações de E/S podem prosseguir concorrentem ente ou assincronamente com um proces­ so em execução. Uma vez iniciada uma operação de E/S assíncrona, o processo pode continuar executan­ do enquanto prossegue a operação de E/S. Quando a E/S é concluída, o processo é notificado. Essa notifica­ ção pode vir a qualquer instante. O processo pode tratar a interrupção naquele momento ou continuar com outras tarefas e tratar a interrupção de conclusão da E/S no momento apropriado. Por isso, interrupções são c o m u m e n te caracterizadas como um mecanismo assíncrono. A sondagem é um m ecanism o síncrono. O processador verifica um dispositivo repetidamente até que a E/S seja concluída. Mecanis­ mos síncronos podem gastar muito tem po esperando ou verificando repetidamente um dispositivo até ocorrer um evento. M ecanismos assíncronos podem continuar com outro trabalho sem perder tempo verificando eventos que não acon­ teceram, o que em geral melhora o desempenho. Sistemas oj^eraciotuiis 76 R e ip o ílã i: 1) U m a interrupção síncrona ocorre devido à execução de software. 2) Um sistem a pode executar sonda­ gem , na qual um processador verifica periodicam ente o estado dos dispositivos. Essa técnica raram ente é usada, porque cria significativa sobrecarga quando o processador sonda dispositivos cujo status não mudou. Interrupções elim inam essa sobrecarga notificando um processador som ente quando o status de um dispositivo mudar. 3.4.1 Processamento de- interrupções Exam inarem os agora a m aneira com o sistemas de com putador processam norm alm ente interrupções de hardware. (Note que existem outros esquem as de interrupção.) 1. A linha de interrupção, uma conexão elétrica entre a placa principal e um processador, fica ativa — dispositivos com o temporizadores, placas periféricas e controladores enviam sinais que ativam a linha de interrupção para inform ar a um processador que ocorreu um evento (por exemplo, um período de tempo passou ou um a requisição de EIS foi concluída). A maioria dos processadores contém um controlador de interrupção que organiza as interrupções segundo suas prioridades, para que as mais importantes sejam atendidas em primeiro lugar. Outras interrupções são enfileiradas até que todas as de prioridade mais alta tenham sido atendidas. 2. Após a linha de interrupção tom ar-se ativa, o processador conclui a execução da interrupção corrente e, então, faz um a pausa na execução do processo corrente. Para fazer essa pausa, o processador precisa salvar inform ações su­ ficientes para que o processo possa ser retom ado no lugar exato e com as inform ações do registrador corretas. Nos antigos sistem as da IBM , esses dados ficavam contidos em uma estrutura de dados denom inada palavra de estado de program a (Program Status Word — PSW ). N a arquitetura Intel IA-32, esse estado de processo é denom inado segm ento de estado de tarefa (Task State Segm ent — TSS). O TSS é tipicam ente arm azenado no PCB de um pro­ cesso.17 3. O processador, então, passa o controle ao tratador de interrupção apropriado. Para cada tipo de interrupção é de­ signado um único valor o qual o processador usa com o um índice no v e to r d e in te rru p ç ã o , que se caracteriza por um conjunto (array) de ponteiros para tratadores de interrupção. O vetor de interrupção localiza-se na m em ória a qual os processos não podem acessar, portanto, processos sujeitos a erro não podem modificar seu conteúdo. 4. O tratador de interrupção executa as ações apropriadas com base no tipo de interrupção. 5. Após o tratador de interrupção concluir, o estado do processo interrom pido (ou de algum outro ‘processo seguinte’, se o núcleo iniciar um chaveam ento de contexto) é restaurado. 6. O processo interrom pido (ou qualquer outro ‘processo seguinte’) é executado. É responsabilidade do sistem a ope­ racional determ inar se é o processo interrom pido ou algum outro ‘processo seguinte’ que é executado. Essa decisão im portante, que pode causar im pacto significativo sobre o nível de serviço que cada aplicação recebe, é discutida no Capítulo 8, “Escalonam ento de processador”. Por exemplo, se a interrupção sinalizar a conclusão de um evento de E/S que provocou a transição de um processo de alta prioridade de bloqueado para pronto, o sistem a operacional poderá preterir o processo interrom pido e despachar o processo de alta prioridade. Consideremos agora com o o sistema operacional e o hardware interagem em reposta a interrupções de relógio (Figura 3.7). A cada intervalo do temporizador, o relógio de interrupção gera uma interrupção que permite ao sistema operacional executar para realizar operações de gerenciam ento de sistema com o escalonamento de processo. Nesse caso, o processador está executando o processo P, (1), quando o relógio em ite uma interrupção (2). Ao receber a interrupção, o processador acessa a entrada do vetor de interrupção que corresponde à interrupção do temporizador (3). Então o processador salva o contexto de execução do processo na memória (4) para que o contexto de execução do processo P, não seja perdido quando o tratador de interrupção executar.18Depois, o processador executa o tratador de interrupção, que determ ina com o responder à interrupção (5). Desse modo, o tratador de interrupção pode restaurar o estado do processo que estava executando anteriorm ente (P t) ou cham ar o escalonador de processador do sistema operacional para determ inar o ‘próxim o’ processo a executar. Nesse caso o tratador cham a o escalonador de processo, que decide que o processo P2, o processo de m aior prioridade em espera, deve obter o processador (6). Então o contexto do processo P2 é carregado do seu PCB para a memória principal e o contexto de execução do processo P, é salvo no seu PCB na m em ória principal. Reviião' 1. Por que as localizações dos tratadores de interrupção geralm ente não são arm azenadas em um a lista encadeada? 2. Por que o contexto de execução do processo é salvo na m em ória enquanto o tratador de interrupção executa? R dípaifaA l 1) Para evitar que fique assoberbado por interrupções, o sistem a precisa ser capaz de processar cada in­ terrupção rapidam ente. Passar por um a lista encadeada podería aum entar significativamente o tem po de resposta de um sistema, caso o núm ero de tipos de interrupção fosse grande. Portanto, muitos dos sistem as usam um vetor de interrupção Capítulo 3 Conceito de processos 77 Controle do processador Processo P2 \ 3 .7 \ Tratamento de interrupções. (um array) para acessar rapidam ente a localização de um tratador de interrupção. 2) Se o contexto de execução do processo não for salvo na m em ória, o tratador de interrupção poderá escrever sobre os registradores do processo. 3.4.2 Classes de, interrupção O conjunto de interrupções que um com putador suporta depende da arquitetura do sistema. Diversos tipos de interrup­ ção são com uns a muitas arquiteturas; nesta seção discutirem os a estrutura de interrupção suportada pela especificação Intel IA -32,19 im plem entada nos processadores Pentium® da Intel®. (A Intel produziu m ais de 80% dos processadores de com putadores pessoais despachados em 2002.20) A especificação IA-32 distingue entre dois tipos de sinais que um processador pode receber: interrupções e exceções. In te rru p ç õ e s notificam ao processador que ocorreu um evento (por exemplo, um intervalo de tem porizador passou) ou que o status de um dispositivo externo mudou (por exemplo, conclusão de E/S). A arquitetura IA-32 tam bém fornece in te rru p ç õ e s g e ra d a s p o r so ftw are — processos podem usá-las para fazer cham adas ao sistema. Exceções indicam que ocorreu um erro, seja no hardware, seja com o resultado de um a instrução de software. A arquitetura LA-32 tam bém usa exceções para provocar pausa em um processo quando ele alcança um ponto de parada no código.21 Dispositivos que geram interrupções, tipicam ente sob a form a de sinais de E/S e interrupções de tem porizador, são externos ao processador. Essas interrupções são assíncronas em relação ao processo em execução, porque ocorrem inde­ pendentem ente das instruções que estão sendo executadas pelo processador. Interrupções geradas por software, tais com o cham adas ao sistema, são síncronas em relação ao processo em execução, porque são geradas em resposta a um a instrução. A Figura 3.8 lista diversos tipos de instruções reconhecidas pela arquitetura IA-32. A arquitetura IA-32 classifica exceções com o falh a s, desvios ou a b o rto s (Figura 3.9). Falhas e desvios são exceções às quais um tratador de exceções pode responder para perm itir que o processo continue a execução. U m a falha indica um erro que um tratador de exceções pode corrigir. Por exemplo, ocorre um a falha de página quando um processo tenta acessar dados que não estão na m em ória (discutirem os falhas de página no Capítulo 10, “O rganização da m em ória virtual”, e no Capítulo 11, “G erenciam ento de m em ória virtual”). O sistem a operacional pode corrigir esse erro colocando os dados requisitados na m em ória principal. D epois de corrigido o problem a, o processador reinicia o processo que causou o erro na instrução responsável pela exceção. Desvios não correspondem a erros corrigíveis, mas a condições com o transbordam entos ou pontos de parada. Por exemplo, quando um processo instrui um processador a increm entar o valor no acumulador, o valor pode exceder a ca- 78 S U tW iA S O p e ra c io n a is Tipo de interrupção Descrição das interrupções de cada,tipo E/S São iniciadas pelo hardware de entrada/saída. Notificam ao processador que o status de um canal ou dispositivo mudou. Interrupções de E/S são causadas quando uma operação de E/S é concluída, por exemplo. Temporizador Um sistema pode conter dispositivos que geram interrupções periodicamente. Essas interrup­ ções podem ser usadas para tarefas como controle de tem po e monitoração de desempenho. Temporizadores também habilitam o sistema operacional a determinar se o quantum de um processo expirou. Interrupções interprocessadores Essas interrupções permitem que um processador envie uma mensagem a outro em um sis­ tema multiprocessador. Figura, 3. S Tipos comuns de interrupções reconhecidospela arquitetura Intel IA-32. Ciasses da exceções Descrição das exceções d e cada classe Falha Causadas por uma vasta gama de problemas que podem ocorrer, enquanto as instruções em linguagem de máquina de um programa são executadas. Entre esses problemas, estão a divi­ são por zero, dados (que estão sendo utilizados) no formato errado, tentativa de executar um código de operação inválido, tentativa de referência a uma localização de memória que está fora dos limites da memória real, tentativa de um processo de usuário de executar uma instrução privilegiada, e tentativa de referir-se a um recurso protegido. Desvio Gerados por exceções como transbordamento (quando o valor armazenado por um registrador excede à capacidade do registrador) e quando o controle do programa chega a um ponto de parada no código. Aborto Ocorrem quando o processador detecta um erro do qual o processo não pode se recuperar. Por exemplo, quando a própria rotina de tratamento de exceções causa uma exceção, o processador pode não conseguir tratar ambos os erros seqüencialmente, o que é denominado exceção de dupla falha, que extingue o processo que lhe deu início. Figura, 3.9 Classes de exceções no Intel IA '32. pacidade do acumulador. Nesse caso, o sistem a operacional pode sim plesm ente notificar o processo de que ocorreu um transbordam ento. A pós executar o tratador de exceção do desvio, o processador reinicia o processo na instrução seguinte àquela que causou a exceção. Abortos indicam erros que o processo não pode (ou talvez nem mesmo o sistem a) recuperar, com o falhas de hardware. Nesse caso, o processador não pode salvar confiavelmente o contexto de execução do processo. N orm alm ente, resulta no encerram ento prem aturo pelo sistem a operacional do processo que causou o aborto. A maioria das arquiteturas e sistemas operacionais prioriza interrupções, porque algumas exigem ações mais imediatas do que outras. Por exemplo, responder a um a falha de hardw are é m ais im portante do que responder a um evento de conclusão de E/S. Prioridades de interrupção podem ser im plem entadas sim ultaneam ente no hardw are e no software. Ou seja, um processador podería bloquear ou enfileirar interrupções de prioridade mais baixa do que a da interrupção que o processa­ dor está tratando no momento. Às vezes o núcleo pode ficar tão sobrecarregado com interrupções que não consegue mais responder a elas. Respostas rápidas a interrupções e retom o rápido do controle a processos interrom pidos são essenciais para m axim izar a utilização de recursos e atingir um alto grau de interatividade. Portanto, grande parte dos processadores perm ite que o núcleo desative (ou mascare) um tipo de interrupção. Então o processador pode ignorar interrupções daquele tipo ou arm azená-las em um a fila de interrupções pendentes, entregues quando aquele tipo de interrupção for reativada. Na arquitetura IA-32, o processador fornece um registrador que indica se as interrupções estão desativadas.22 Capítulo 3 Conceito de,processos Rertlão' 1. N a arquitetura IA-32, quais os dois tipos de sinais que um processador pode receber? 2. N a arquitetura IA-32, qual a diferença entre um a falha e um desvio? Reípoitài: i) Um processador pode receber interrupções ou exceções. Interrupções indicam que ocorreu um evento; exceções indicam que ocorreu um erro. 2) U m a falha reinicia um processo a partir da instrução que causou a exceção. Falhas geralm ente são erros que podem ser corrigidos. Um desvio reinicia um processo na instrução seguinte à que causou a exceção. Desvios usualm ente são gerados por cham adas ao sistem a e pela chegada do controlador de program a a pontos de parada. 3.S CoMUKuação interprocessos Em am bientes m ultiprogram ação e de rede, é com um que processos se com uniquem uns com os outros. M uitos sis­ temas operacionais fornecem m ecanism os para com unicações interprocessos (Interprocess Comunication — IPC) que, por exemplo, habilitam um editor de texto a enviar um docum ento ao spooler de um a im pressora ou um navegador Web a recuperar dados de um servidor remoto. Com unicação interprocessos tam bém é essencial para processos que devem coordenar (sincronizar) atividades para alcançar um a m eta comum. O s estudos de caso do Linux (veja a Seção 20.10, “Com unicação interprocessos”) e do W indows X P (veja a Seção 21.10, “Com unicação interprocessos”) discutem com o a IPC foi im plem entada em sistem as operacionais populares. 3.5.1 Sutais Sinais são interrupções de software que notificam ao processo que um evento ocorreu. D iferentem ente de outros m eca­ nism os de IPC que discutim os, sinais não perm item que processos especifiquem dados para trocar com outros processos.23 Os sinais de um sistem a dependem do sistem a operacional e das interrupções geradas por software suportadas por um processador em particular. Quando ocorre um sinal, o sistem a operacional prim eiram ente determ ina qual processo deve receber o sinal e com o esse processo responderá ao sinal. Processos podem capturar, ignorar ou m ascarar o sinal. Um processo captura um sinal especificando um a rotina que o sistem a operacional cham a quando entrega o sinal.24 Um processo tam bém pode ignorar o sinal. Nesse caso, o processo depende da ação-padrão do sistem a operacional para tratar o sinal. U m a ação-padrão com um , por exem plo, é abortar, que faz com que o processo saia im ediatam ente. O utra ação-padrão com um , e semelhante a abortar, é a descarga de me­ mória. Essa ação faz com que um processo saia, mas, antes de fazê-lo, gera um arquivo de núcleo que contém o contexto de execução do processo e os dados de seu espaço de endereço, o que é útil para depuração. U m a outra ação-padrão é sim plesm ente ignorar o sinal. Duas outras ações-padrão são suspender e, subseqüentem ente, retom ar o processo.25 Um processo tam bém pode bloquear um sinal, mascarando-o. Q uando o processo m ascara um sinal de um tipo específico (por exemplo, sinal de suspenso), o sistema operacional não transm ite sinais daquele tipo até que o processo desbloqueie o sinal de máscara. Os processos em geral bloqueiam um tipo de sinal enquanto m anuseiam um outro sinal do mesmo tipo. Do mesmo m odo que acontece com as interrupções mascaradas, os sinais m ascarados tam bém podem ser perdidos, dependendo da im plem entação do sistem a operacional. R cviicuy 1. Qual a m aior desvantagem de usar sinais para a IPC? 2. Quais as três m aneiras pelas quais um processo pode responder a um sinal? Reipoifai 1) Sinais não suportam troca de dados interprocessos. 2) Um processo pode capturar, ignorar ou mascarar um sinal. 3.5.2 Troav mensagens Com a proem inência cada vez m aior dos sistemas distribuídos, cresceu o interesse na com unicação interprocessos baseada em m ensagens.26’27’28,29,30,31 Discutirem os com unicação baseada em m ensagens nesta seção; im plem entações particulares são discutidas nos estudos de caso do Linux e do W indows XP.32,33 M ensagens podem ser passadas em um a direção por vez — para qualquer m ensagem um processo é o emissor, o outro o receptor. A troca de m ensagens pode ser bidirecional, significando que cada processo pode agir ou com o em issor ou com o receptor enquanto participa da com unicação interprocessos. Um dos m odelos de troca de m ensagens especifica que os processos enviem e recebam m ensagens fazendo cham adas como: 80 S U tw u is o jte ra c io fu iti send( processoReceptor, mensagem ); receive( processoEmissor, m ensagem ); As cham adas de envio e recebim ento são norm alm ente im plem entadas com o cham adas ao sistem a acessíveis de m uitos am bientes de linguagem de program ação. Um envio bloqueante deve esperar que o receptor receba a mensagem, solicitando que esse notifique o em issor quando a m ensagem for recebida (essa notificação é denom inada confirmação). Um envio não bloqueante habilita o em issor a continuar com outro processam ento m esm o que o receptor ainda não tenha recebido (e confirmado) a m ensagem , o que exige um m ecanism o de buffer de m ensagens para guardar a m ensagem até que o receptor a receba. Um envio bloqueante é um exemplo de comunicação síncrona; um envio não bloqueante é um exem plo de comunicação assíncrona. A cham ada de envio pode nom ear explicitam ente um processo receptor, ou pode om itir o nome, indicando que a m ensagem é para ser difundida a todos os processos (ou a algum ‘grupo de trabalho’ com o qual o em issor geralm ente se com unica). Com unicação assíncrona com envios não bloqueantes aum enta o rendim ento reduzindo o tem po que o processo espera. Por exemplo, um em issor pode enviar um a inform ação a um servidor de im pressão que está ocupado; o sistem a faz um arm azenam ento tem porário dessa inform ação até que o servidor de im pressão esteja pronto para recebê-la, enquanto o em issor continuará a execução sem ter de esperar no servidor de impressão. Se não foi enviada nenhum a m ensagem , então uma cham ada de recepção bloqueante força o receptor a esperar; uma cham ada de recepção não bloqueante habilita o receptor a prosseguir com outro processam ento antes de tentar novamente um a recepção. Uma cham ada de recepção pode especificar que o receptor deve receber um a m ensagem de um em issor particular, ou que o receptor pode receber um a m ensagem de qualquer em issor (ou de qualquer m em bro de um grupo de em issores). U m a im plem entação popular da troca de m ensagens é um pipe — um a região da m em ória protegida pelo sistem a ope­ racional que serve com o buffer, perm itindo que dois ou mais processos troquem dados. O sistem a operacional sincroniza o acesso ao buffer— depois que um processo escritor com pletar a escrita no buffer (possivelm ente enchendo-o), o sistem a operacional faz um a pausa na execução do escritor e perm ite que um processo leitor leia os dados do buffer. A m edida que um processo lê os dados, eles são removidos do pipe. Q uando o leitor concluir a leitura dos dados do buffer (possivelmente esvaziando-o), o sistem a operacional fará uma pausa na execução do leitor e perm itirá que o escritor escreva dados para o buffer.34 Tratam entos detalhados de pipes são apresentados nos estudos de casos do Linux e do W indows X P no final do livro (veja as seções 20.10.2, “Pipes” , e 21.10.1, “Pipes”, respectivamente). Em nossas discussões sobre com unicação interprocesso entre processos no m esm o computador, sempre pressupom os um a transm issão perfeita. Por outro lado, em sistemas distribuídos as transm issões podem ser imperfeitas e até perdidas. Portanto, em issores e receptores usualm ente cooperam utilizando um protocolo de confirmação para confirm ar que cada transm issão foi adequadam ente recebida. O em issor que espera um a m ensagem de confirm ação do receptor pode usar um m ecanism o de tempo de espera; se a confirmação não tiver sido recebida quando o tempo se esgotar, o em issor pode retransm itir a mensagem. Sistem as de troca de m ensagens com recursos de retransm issão podem identificar cada nova m ensagem com um núm ero de seqüência. O receptor exam ina esses núm eros para ter certeza de que recebeu todas as m ensagens e para reorganizar as que estão fora de seqüência. Se um a m ensagem de confirm ação for perdida e o em issor decidir retransm iti-la, ele designará à m ensagem retransm itida o m esm o núm ero de seqüência da m ensagem transm itida originalm ente. O receptor que detectar diversas m ensagens com o m esm o núm ero de seqüência saberá que deve conservar som ente um a delas. U m a com plicação em sistemas distribuídos com troca de m ensagens de envio/recepção é que não pode haver nenhuma am bigüidade nos nom es dos processos, para que cham adas explícitas de envio e recepção refiram-se aos processos corre­ tos. Criação e destruição de processos podem ser coordenadas por algum m ecanism o de nom eação centralizado, mas isso pode introduzir considerável sobrecarga de transm issão, um a vez que as máquinas individuais pedem perm issão para usar novos nomes. U m a abordagem alternativa, por exemplo, é cada com putador garantir nomes exclusivos para seus próprios processos; esses podem ser endereçados com binando-se o nome do com putador com o nome do processo. E isso, é claro, requer controle centralizado para determ inar um nome exclusivo para cada com putador do sistem a distribuído, o que teria o potencial de provocar sobrecargas significativas no caso de haver adições e retiradas freqüentes de com putadores da rede. N a prática, sistemas distribuídos trocam m ensagens entre com putadores usando portas num eradas que atendem aos processos, evitando o problem a da nom eação (veja o Capítulo 16, “Introdução às redes”). Com o verem os no Capítulo 17, “Introdução a sistemas distribuídos”, a com unicação baseada em m ensagens em sis­ temas distribuídos apresenta sérios problem as de segurança. Um deles é o problema de autenticação: com o receptores e em issores sabem que não estão se com unicando com im postores que podem estar tentando roubar ou corrom per seus dados? O Capítulo 19, “Segurança”, discute diversas abordagens de autenticação. H á várias técnicas de IPC que apresentarem os m ais adiante neste livro. A lém de sinais e pipes, processos podem se com unicar via m em ória com partilhada (discutida no Capítulo 10, “Organização da m em ória virtual”), soquetes (discutidos no Capítulo 16) e cham adas a procedim ento rem oto (discutidas no Capítulo 17). Também podem se com unicar para sin­ Capítulo 3 Conceito de,processos gj cronizar atividades usando sem áforos e m onitores, que são discutidos no Capítulo 5, “Execução assíncrona concorrente” e Capítulo 6, “Program ação concorrente” , respectivamente. Revuão' 1. Por que sistem as distribuídos adotam troca de m ensagens, e não sinais? 2. Q uando um processo realiza um envio bloqueante, deve receber um a m ensagem de confirm ação para desbloquear. Qual o problem a que pode resultar desse esquem a e com o pode ser evitado? R eipO ifoi: 1) Sinais são tipicam ente específicos de um a arquitetura, o que significa que sinais suportados por um com putador podem não ser com patíveis com sinais suportados por outro computador. A lém disso, sinais não perm item que processos transm itam dados, um recurso requerido pela m aioria dos sistemas distribuídos. 2) O em issor poderá nunca receber a m ensagem de confirmação, o que significa que o processo poderá ficar bloqueado indefinidamente. Isso pode ser rem ediado com um m ecanism o de tem po — se o em issor não receber um a confirm ação após um período de tem po, o sistem a entenderá que a operação de envio falhou e poderá ser tentada novamente. 3.6 Estudo de caso:processos no Unix. Sistemas operacionais UNIX e baseados em UNIX fornecem um a im plem entação de processos tom ada em prestada por m uitos outros sistemas operacionais (veja o “M iniestudo de caso, Sistemas UNIX”). N esta seção descrevem os a estrutura dos processos UNIX, discutim os diversas características do UNIX que motivam a discussão nos capítulos seguintes e esclarecem os com o o U N IX perm ite que usuários realizem operações de gerenciam ento de processos. Cada processo deve arm azenar seu código, dados e pilha na m em ória durante a execução. Em um sistem a de m em ó­ ria real, processos localizariam tais inform ações referindo-se a um a faixa de endereços físicos. A faixa de endereços de m em ória válidos para cada processo é determ inada pelo tam anho da m em ória principal e pela m em ória consum ida por outros processos. Com o o UNIX im plem enta m em ória virtual, todos os processos UNIX têm um conjunto de endereços de m em ória denom inado espaço de endereço virtual, no qual o processo pode arm azenar inform ações. O espaço de endereço virtual contém um a região de texto, um a região de dados e um a região de pilha.35 O núcleo m antém o PCB de um processo em um a região protegida da m em ória que os processos usuários não podem acessar. Em sistem as UNIX, um PCB arm azena inform ações, incluindo os conteúdos dos registradores dos processos, o identificador do processo (PID), o contador do program a e a pilha do sistem a.36,37 Os PCBs de todos os processos estão listados na tabela de processos, que perm ite ao sistem a operacional acessar inform ações (por exemplo, prioridade) refe­ rentes a cada processo.38 Processos UNIX interagem com o sistem a operacional via cham adas ao sistema. A Figura 3.10 lista diversas delas. Um processo pode gerar um processo-filho usando a cham ada ao sistem a fo rk , que cria um a cópia do processo-pai.39,40 O processo-filho recebe uma cópia dos dados e segmentos de pilha e quaisquer outros recursos do processo-pai.41,42 O seg­ m ento de texto, que contém as instruções som ente de leitura do pai, é com partilhado com seu filho. Im ediatam ente após a cham ada fo rk , os processos-pai e filho contêm dados e instruções idênticos, o que significa que os dois processos devem realizar exatam ente as mesmas ações, a menos que o pai ou o filho possam determ inar sua identidade. Portanto, a cham ada fork ao sistem a retom a valores diferentes; o processo-pai recebe o PID do filho e o processo-filho recebe um valor de zero. Essa convenção perm ite que o processo-filho reconheça que foi recentem ente criado. Program adores de aplicações podem usar essa convenção para especificar novas instruções para o processo-filho executar. ChamaÁa,a/> sistema, Vescrição fork Gera um processo-filho e aloca àquele processo uma cópia dos recursos de seu pai. exec Carrega as instruções e dados de um processo no seu espaço de endereço em um arquivo. wait Faz com que o processo que está chamando fique bloqueado até que seu processo-filho termine. signal Permite que um processo especifique um tratador de sinal para um tipo de sinal particular. exit Termina o processo que está chamando. nice Modifica a prioridade de escalonamento de um processo. fig u ra , 3.10 Chamadas ao sistema do UNIX. 82 Sistemas oj^eraciotuiis OwM ôgWAo dô c<x$o SUtmuu UNIX Na época anterior ao W indows, Macintosh, Linux ou até mesmo ao DOS, sistemas operacionais funcio­ navam, tipicamente, em um modelo de computador, gerenciando recur­ sos do sistema, executando fluxos de lotes e pouco mais.43 De 1965 a 1969, um grupo de equipes de pes­ quisadores do Bell Laboratories, Ge­ neral Electric e ProjectMAC do MIT desenvolveu o sistema operacional Multics — um recurso de compu­ tador de uso geral, projetado para ser 'tudo para todos'.44 Era grande, caro e complexo. Em 1969, o Bell Labs saiu do projeto e sua pequena equipe, liderada por Ken Thompson, começou a projetar um sistema ope­ racional mais prático para executar máquinas no Bell Labs. T hom pson im p le m e n to u os componentes básicos do sistema operacional que Brian Kernighan cham ou de UNICS, uma brinca­ deira com o aspecto 'm u lti' do M ultics; a grafia eventualm ente mudou para UNIX. Em alguns pou­ cos anos o UNIX foi reescrito em uma implementação interpretada da linguagem B de Thompson (baseada na linguagem de programação BCPL de Martin Richard) e, logo em segui­ da, na linguagem compilada C, mais rápida, de Dennis Ritchie.45 D evido a uma ação judicial federal baseada na lei antitruste, a AT&T (proprietária do Bell Labs) foi impedida de vender produtos de computador; desse modo, dis­ tribuiu o código-fonte do UNIX às universidades mediante uma peque­ na taxa só para cobrir as despesas de produção das fitas magnéticas. Um grupo de estudantes da Univer­ sidade da Califórnia, em Berkeley, liderado por Bill Joy (mais tarde cofundador da Sun M icrosystem s), modificou o código-fonte do UNIX, desenvolvendo o sistema operacio­ nal que veio a ser conhecido como Berkeley Softw are Distribution U N IX (BSD U N IX ).46 Os desenvolvedores da indús­ tria do software foram atraídos pelo UNIX porque era gratuito, pequeno e c u s to m iz á v e l. Para tra b a lh a r com o UNIX tiveram de aprender a linguagem C, e gostaram dela. Muitos deles também a ensinaram a seus colegas, e a linguagem C gradualmente substituiu a Pascal como a linguagem preferida para ser ensinada nos cursos de pro­ gramação de universidades. A Sun M icrosystems baseou seu SunOS no BSD UNIX e, mais tarde, formou uma equipe com a AT&T para pro­ jetar o sistema operacional Solaris baseado no System V Release 4 UNIX da AT&T.47 Um outro grupo de desenvolvedores UNIX, preocu­ pado que a associação da Sun com a AT&T daria à primeira uma lideran­ ça injusta no negócio sobre outros desenvolvedores UNIX, form ou a Open Software Foundation (OSF) para produzir sua própria versão não proprietária do UNIX, denominada OSF/1; a feroz competição entre a OSF e a Sun, essa última respaldada pela AT&T, foi apelidada de Guerra dos UNIX.48 Diversos sistemas operacionais importantes são baseados na tec­ nologia UNIX. O professor Andrew Tanenbaum da Vrije Universiteit, em Am sterdã, construiu o M inix em 1987, uma versão mais simples do UNIX projetada para ensinar o bá­ sico de sistemas operacionais em alguns cursos universitários. Linus Torvalds, um estudante finlandês, usou o M inix para começar a es­ crever o famoso sistema operacio­ nal de fonte aberto Linux — agora uma família completa de sistemas por mérito próprio (veja o Capítulo 20, "Estudo de caso: Linux").49 O Linux é o sistema de fonte aberto mais popular, e empresas, entre elas a IBM, a Hewlett-Packard, a Sun M icrosystem s e a Intel, ofe­ recem versões Linux como opção de sistema operacional para seus servidores. O OpenBSD é um outro projeto de fonte aberto, liderado por Theo de Raadt, e reconhecido como o sistema operacional mais seguro disponível (veja o Capítulo 19, " Se­ gurança").50-51-52-530 FreeBSD tam­ bém é um fonte aberto conhecido por sua facilidade de utilização.54 Ainda um outro descendente do BSD, o Net-BSD, concentrou-se na portabilidade para uma variedade de sistemas.55-56 O AIXda IBM, baseado no System V e no BSD,57 executa em alguns dos servidores da IBM. A IBM afirma que o AIX tem um alto grau de compatibilidade de códigofonte com o Linux.58 O HP-UX da Hewlett-Packard está se tornando um forte concorrente do AIX e do Solaris, conseguindo as mais altas classificações em todas as cate­ gorias em um relatório de 2002 da D.H.Brown Associates, o que o coloca à frente tanto do Solaris quanto do AIX.59-60-61 Um processo pode cham ar exec para carregar um novo program a em um arquivo; exec é usualm ente executada por um processo-filho im ediatam ente depois de ele ser gerado.62 Ao criar um processo-filho, o pai pode em itir um a cham ada ao sistem a wait, que bloqueia o pai até que o processo-filho especificado term ine.63 D epois de o processo ter concluído seu trabalho, ele em ite a cham ada ao sistem a exit que inform a ao núcleo que o processo terminou; o núcleo responde liberando toda a m em ória e outros recursos do processo, com o arquivos abertos. Q uando um processo-pai sai, seus processos-filho são norm alm ente realocados na hierarquia do processo com o filhos do processo init.M'65 Se um processo-pai for terminado por um sinal kill de um outro processo, aquele sinal será enviado a seus processos-filho. Capítulo 3 Conceito de,processos 83 As prioridades de processo do UNIX são números inteiros entre -2 0 e 19 (inclusive), que o sistem a usa para determ inar qual processo é o próxim o a executar. Um valor num érico de prioridade m ais baixo indica um a prioridade de escalona­ m ento mais alta.66 Processos que pertencem ao sistem a operacional, denom inados processos de núcleo, freqüentem ente têm valores inteiros negativos e, tipicam ente, sua prioridade de escalonam ento é m ais alta do que as dos processos de usuários.67 Processos de sistemas operacionais que executam operações de m anutenção periodicam ente, denom inados daem ons, executam em geral com a prioridade m ais baixa possível. M uitas aplicações requerem que vários com ponentes independentes se com uniquem durante a execução, o que exige com unicação interprocessos (IPC). O UNIX fornece vários m ecanism os que habilitam os processos a trocar dados, tais com o sinais e pipes (veja as seções 3.4, “Com unicação interprocessos”, e 20.10.2, “Pipes”).68 Rerfião' 1. Por que um pai e seu filho podem com partilhar o segmento de texto do pai após um a cham ada ao sistem a fork? 2. Por que um processo deve usar ICP para com partilhar dados com outros processos? RcipOétãi l 1) O segmento de texto contém instruções que não podem ser modificadas por nenhum dos dois processos, o que significa que am bos os processos, pai e filho, executarão as m esm as instruções independentem ente de o sistem a operacional m anter ou não uma, ou várias, cópias do segmento na m emória. Portanto, o sistem a operacional pode reduzir o consum o de m em ória com partilhando o acesso à região de texto entre um pai e seu filho. 2) O sistem a operacional não perm ite que processos não relacionados com partilhem o segmento de dados de seus espaços de m emória, ou seja, os dados arm azenados por um processo são inacessíveis a processos não relacionados. Portanto, o sistem a operacional deve fornecer algum m ecanism o que tom e os dados de um processo disponível para outro. Resumo Um processo, ou seja, um program a em execução, é fundamental para entender com o os sistemas de com putador de hoje realizam e controlam muitas atividades simultâneas. Cada processo tem seu próprio espaço de endereço, que pode consistir em uma região de texto, uma região de dados e uma região de pilha. U m processo passa por uma série de estados distintos. Por exemplo, um processo pode estar em estado de execução, estado de pronto ou estado bloqueado. A lista de prontos e a lista de bloqueados arm azenam referências aos processos que não estão em execução. Q uando um processo chega ao topo da lista de prontos e quando um processador fica disponível, aquele processo é designado a um processador, e diz-se que ele fez um a transição do estado de pronto para o estado em execução. O ato de designar um processador ao prim eiro processo da lista de prontos é denom inado despacho. Para evitar que qualquer um dos processos m onopolize o sistema, acidental ou m aliciosam ente, o sistem a operacional estabelece um relógio de interrupção (ou tem porizador de intervalo), que perm ite que um processo execute durante um intervalo de tem po especificado ou quantum . Se um processo em execução iniciar um a operação de entrada/saída antes do seu quantum expirar, diz-se que o processo bloqueou a si m esmo, deixando em suspenso a conclusão da operação de E/S. Como alternativa, o sistema operacional pode empregar m ultitarefa cooperativa, na qual cada processo executa até concluir ou até devolver voluntariam ente seu processador, o que pode ser perigoso, porque a m ultitarefa cooperativa não impede que os processos m onopolizem um processador. O sistem a operacional norm alm ente executa diversas operações quando cria um processo, incluindo designar ao processo um núm ero de identificação de processo (PID) e criar um bloco de controle de processo (PCB), ou descritor de processo, que arm azene o contador de program a (ou seja, o ponteiro para a próxim a instrução que o processo executará), o PID, a prioridade de escalonam ento e, por fim, o contexto de execução do processo. O sistem a operacional mantém ponteiros para cada PCB de processo na tabela de processo para poder acessar o PCB rapidam ente. Quando um processo term ina (ou é term inado pelo sistem a opera­ cional), o sistem a operacional retira o processo da tabela de processos e libera todos os recursos do processo, incluindo sua memória. Um processo pode gerar um novo processo — o processo criador é denom inado processo-pai e o processo criado é denom inado processo-filho. Cada processo-filho é criado por exatam ente um processo-pai, e essa criação origina uma estrutura hierárquica de processos. Em alguns sistem as um processo gerado é destruído autom aticam ente quando seu pai é destruído; em outros, processos gerados continuam independentem ente de seus pais, e a destruição desses não tem nenhum efeito sobre os filhos dos pais destruídos. Um processo suspenso é retirado indefinidam ente da disputa por tem po em um processador sem ser destruído. Os estados suspensos são suspenso-pronto e suspenso-bloqueado. U m a suspensão pode ser iniciada pelo processo que está sendo suspenso ou por um outro processo; um processo suspenso deve ser retom ado por um outro processo. Sistemas operacioftais 84 Q uando o sistem a operacional despacha um processo pronto para um processador, ele inicia um chaveam ento de contexto. Chaveamentos de contexto devem ser transparentes para os processos. Durante um chaveam ento de contexto, um processador não pode realizar nenhum a com putação ‘útil’, portanto, sistem as operacionais devem m inim izar o tempo de chaveam ento de contexto. Algum as arquiteturas reduzem a sobrecarga executando operações de chaveamento de contexto em hardware. Interrupções habilitam o software a responder a sinais do hardware. Uma interrupção pode ser iniciada especificamen­ te por um processo em execução (caso em que geralm ente é denom inada desvio (trap) e considerada com o síncrona em relação à operação do processo), ou pode ser causada por algum evento que pode ou não estar relacionado ao processo em execução (caso em que é denom inada assíncrona em relação à operação do processo). U m a alternativa às interrupções é o processador inquirir repetidam ente o estado de cada dispositivo, um a abordagem denom inada sondagem (polling). Interrupções são essenciais para m anter um am biente de com putação protegido e produtivo. Quando ocorre uma interrupção, o processador executará uma das funções de tra­ tamento de interrupções do núcleo. O tratador de interrupção determ ina com o o sistema deve responder a interrupções. As localizações dos ponteiros de interrupções são armazenadas em um conjunto (array) de ponteiros denom inado vetor de interrupção. O conjunto de interrupções que um com putador suporta depende da arquitetura do sistema. A especificação IA-32 distingue entre dois tipos de sinais que um processador pode receber: interrupções e exceções. M uitos sistem as operacionais fornecem m ecanism os para com unicações interprocessos (IPC) que, por exemplo, habilitam um navegador Web a recuperar dados de um servidor rem oto. Sinais são interrupções de software que notificam o processo sobre a ocorrência de um evento; sinais não perm item que processos especifiquem dados para trocar com outros processos. Processos podem capturar, ignorar ou m ascarar um sinal. Com unicações interprocessos podem ocorrer em uma direção por vez ou podem ser bidirecionais. U m modelo de troca de m ensagens especifica que processos enviem e recebam m ensagens fazendo chamadas. U m a im plem en­ tação popular da troca de m ensagens é um pipe — um a região da m em ória protegida pelo sistem a operacional que perm ite que dois ou mais processos troquem dados. Uma com plicação em sistem as distribuídos no que diz respeito à troca de m ensagens do tipo envio/recepção é que não pode haver nenhum a am bigüidade nos nomes dos processos, para que cham adas explícitas de envio e recepção refiram-se aos processos corretos. Processos UNIX têm um conjunto de endereços de m e­ m ória denom inado espaço de endereço virtual que contém um a região de texto, um a região de dados e um a região de pilha. Em sistem as UNIX, um PCB arm azena inform ações, incluindo os conteúdos de registradores de processos, o identificador do processo (PID), o contador do program a e a pilha do sistema. Todos os processos são listados na tabela de processos, a qual perm ite ao sistem a operacional acessar inform ações referentes a cada processo. Processos UNIX interagem com o sistema operacional via chamadas ao sistema. Um processo pode gerar um processo-filho usando a chamada ao sistema fork, que cria uma cópia do processo-pai. As prioridades de processo do UNIX são núm eros inteiros entre -2 0 e 19 (inclusive), que o sistema usa para determ inar qual processo executará em seguida; um valor num érico de prioridade mais baixo indica um a prioridade de escalona­ m ento m ais alta. O núcleo tam bém fornece m ecanism os de IPC, tais com o pipes, que perm item que processos não relacionados transfiram dados. Exercícios 3.1 Cite diversas definições de processo. Por que você acredita que não haja nenhuma definição aceita universalmente? 3.2 Algumas vezes os termos usuário e processo são usados intercambiavelmente. Defina cada um deles. Em quais circunstâncias têm significados similares? 3.3 Por que não faz sentido manter a lista de bloqueados em ordem de prioridade? 1 int main() { 2 3 while( true ) { 4 forkO ; 5 } 6 7 } FüjUTO/ 3.11 Código para, o Exercício 3.4. 3.4 A habilidade de um processo gerar um novo processo é uma característica importante, mas não totalmente isenta de perigos. Considere as consequências de permitir que um usuário execute o processo da Figura 3.11. Suponha que forkf) seja uma chamada ao sistema que gera um processo-filho. a. Supondo que um sistema permitisse que tal processo executasse, quais seriam as conseqüências? Capítulo 3 b. Suponha que você, na qualidade de projetista de siste­ mas operacionais, tivesse de inserir salvaguardas contra tais processos. Sabemos (pelo ‘Problema da Parada [Halting]’ da teoria da computabilidade) que, no geral, é impossível prever o caminho de execução que um programa seguirá. Quais as conseqüências desse resultado fundamental da ciência da computação para a sua capacidade de impedir que processos como o apresentado anteriormente executem? c. Suponha que você decida que é inadequado rejeitar certos processos, e que a melhor abordagem é inserir nele certos controles de tempo. Quais controles o sistema operacional podería usar para detectar processos como o anterior durante o tempo de execução? d. Os controles que você propôs atrapalhariam a capacidade de um processo gerar novos processos? e. Como a implementação dos controles que você propôs afeta o projeto dos mecanismos de tratamento de processo do sistema? 3.5 Em sistemas dedicados de usuário único, geralmente é ób­ vio quando um programa entra em laço infinito. Mas em sistemas multiusuário que executam grandes números de processos, não é fácil determinar que um processo individual não está progre­ dindo. a. O sistema operacional consegue determinar que um processo entrou em laço infinito? b. Quais salvaguardas razoáveis poderíam ser construídas no sistema operacional para impedir que processos em laço infinito continuem a executar indefinidamente? 3.6 Escolher o tamanho correto do quantum é importante para o funcionamento efetivo de um sistema operacional. Mais adiante no texto vamos examinar com profundidade a questão da determinação do quantum. Por enquanto, anteciparemos alguns dos problemas. Considere um sistema de processador único de tempo comparti­ lhado que suporta um grande número de usuários interativos. Cada vez que um processo obtém o processador, o relógio de interrupção é acertado para interromper após a expiração do quantum, o que permite que o sistema operacional impeça que qualquer processo isolado monopolize o processador e, assim, dê respostas rápidas aos processos interativos. Suponha um mesmo quantum para todos os processos do sistema. a. Que efeito teria estabelecer um valor extremamente grande para o quantum, por exemplo, 10 minutos? b. E se o valor estabelecido fosse extremamente pequeno, digamos, alguns ciclos de processador? c. É óbvio que um valor apropriado para o quantum estaria entre (a) e (b). Suponha que você pudesse girar um mostra­ dor e variar o quantum começando com um valor pequeno e aumentando gradativamente. Como você sabería quando tivesse escolhido o valor ‘correto’? d. Quais fatores tomariam esse valor correto do ponto de vista do usuário? e. Quais fatores tomariam esse valor correto do ponto de vista do sistema? 3.7 Em um mecanismo de bloqueio/despertar, um processo blo­ queia a si mesmo para esperar que um evento ocorra. Um outro processo deve detectar que o evento ocorreu e acordar o processo bloqueado. É possível que um processo bloqueie a si mesmo para esperar por um evento que nunca ocorrerá. a. O sistema operacional pode detectar que um processo blo­ queado está esperando por um evento que nunca ocorrerá? b. Quais salvaguardas razoáveis poderíam ser inseridas em um sistema operacional para impedir processos de esperar indefinidamente por um evento? Conceito de,processos gg 3.8 Uma razão para usar um quantum para interromper um processo em execução após um período ‘razoável’ é permitir que o sistema operacional retome o processador e despache o próximo processo. Suponha que um sistema não tenha um relógio de inter­ rupção e que o único modo pelo qual um processo possa perder o processador seja desistir dele voluntariamente. Suponha também que o sistema operacional não disponha de nenhum mecanismo de despacho. a. Descreva como um grupo de processos de usuários podería cooperar entre si para efetuar um mecanismo de despacho controlado por usuário. b. Quais os perigos potenciais inerentes a esse esquema? c. Quais as vantagens para os usuários em relação a um mecanismo de despacho controlado pelo sistema? 3.9 Em alguns sistemas um processo gerado é destruído imedia­ tamente quando seu pai é destruído; em outros, processos gerados continuam independentemente de seus pais, e a destruição de um pai não tem efeito sobre seus filhos. a. Discuta as vantagens e desvantagens de cada aborda­ gem. b. Dê um exemplo de uma situação em que destruir um pai não deveria especificamente resultar na destruição de seus filhos. 3.10 Quando interrupções são desativadas na maioria dos dis­ positivos, elas continuam pendentes até que possam ser proces­ sadas quando forem novamente habilitadas. Não são permitidas quaisquer outras interrupções. O funcionamento dos próprios mecanismos é temporariamente interrompido. Mas, em sistemas de tempo real, o ambiente que gera as interrupções muitas vezes está dissociado do sistema do computador. Quando as interrupções são desativadas no sistema do computador, o ambiente continua gerando interrupções do mesmo jeito. Essas interrupções podem ser perdidas. a. Discuta as conseqüências de interrupções perdidas. b. Em um sistema de tempo real, é melhor perder interrup­ ções ocasionais ou parar o sistema temporariamente até que as interrupções sejam habilitadas novamente? 3.11 Como veremos repetidamente por todo este texto, o gerencia­ mento da espera é uma parte essencial de todo sistema operacional. Neste capítulo vimos diversos estados de espera, a saber, pronto, bloqueado, suspenso-pronto e suspenso-bloqueado. Para cada um desses estados, discuta como um processo podería entrar no estado em questão, o que o processo está esperando e a possibilidade de que o processo possa ‘ser perdido’ esperando indefinidamente naquele estado. Quais características os sistemas operacionais deveríam incorporar para enfrentar a possibilidade de processos começarem a esperar por um evento que talvez nunca aconteça? 3.12 Processos em espera consomem vários recursos do sistema. Alguém podería sabotar um sistema criando processos repetida­ mente e fazendo-os esperar por eventos que nunca acontecerão? Quais salvaguardas poderíam ser impostas? 3.13 Um sistema de processador único pode não ter nenhum pro­ cesso pronto e nenhum processo em execução? Esse é um sistema ‘morto’? Explique sua resposta. 3.14 Por que podería ser útil acrescentar um estado morto ao diagrama de transição de estado? 3.15 O Sistema A executa exatamente um processo por usuário. O Sistema B pode suportar muitos processos por usuário. Discuta as diferenças organizacionais entre os sistemas operacionais A e B no que se refere ao suporte de processos. 3.16 Quais as semelhanças e diferenças entre IPCs que usam sinais e troca de mensagens? S is te m a s o jw a c io tu iti 86 3.17 Como discutido na Seção 3.6, “Estudo de caso: Processos UNIX”, esses processos podem alterar suas prioridades usando a chamada ao sistema nice. Quais restrições o UNIX podería impor ao uso dessa chamada ao sistema? Por quê? Projetos sugeridos 3.18 Quais as semelhanças e diferenças entre as informações armazenadas em PCBs do Linux, do Windows XP da Microsoft, e do OS X da Apple? Quais os estados de processo definidos por cada um desses sistemas operacionais? 3.19 Pesquise as melhorias feitas no chaveamento de contexto ao longo dos anos. Como melhorou a quantidade de tempo que processadores gastam em chaveamentos de contexto? De que ma­ neira o hardware ajudou a tomar o chaveamento de contexto mais rápido? 3.20 A linha de processadores Intel Itanium, projetados para computação de alto desempenho, é implementada segundo a especificação IA-64 (64 bits). Quais as semelhanças e diferenças entre o método de processamento de interrupções da arquitetura IA-32 discutida neste capítulo e o da arquitetura IA-64 (consulte developer.intel.com/design/itanium/manuals/245318.pdf). 3.21 Discuta um esquema de interrupção que não seja o descrito neste capítulo. Compare os dois esquemas. Notas 1. 2. 3. 4. 5. 6. R. C. Daley e Jack B. Dennis, “Virtual memory, processes, and sharing in Multics”, Proceedings ofthe ACM Symposium on Operating System Principies, jan. 1967. F. Corbató, M. Merwin-Daggett e R. C. Daley, “An experi­ mental time-sharing system”, Proceedings ofthe Spring Joint Computer Conference (AFIPS), v. 21, 1962, p. 335-344. T. Van Vleck, “The IBM 7094 and CTSS”, 3 mar. 2003, 20. www.multidans.org/thw/7094.html. 23. T. Van Vleck, “Multics general information and FAQ”, 14 set. 2003, www.multicians.org/general.html. T. Van Vleck, “Multics general information and FAQ”, 14 set. 2003, www.muHicians.org/general.html. P. Green, “Multics virtual memory: tutorial and reflections”, 07/31/020731 hnstudy.xml. 21. 22. 8. T. Van Vleck, “Multics general information and FAQ”, 14 set. 2003, www.muhicians.org/general.html. P. Green, “Multics virtual memory: tutorial and reflections”, 24. 25. 10. 11. T. Van Vleck, “Multics general information and FAQ”, 14 set. 2003, www.muhicians.org/general.html. T. Van Vleck, “Multics glossary— A”, www.multicians.org/ mga. html. T. Van Vleck, “Multics glossary — B ” , www.multicians.org/ mgb. 12. html. 26. 27. 28. P. McJones, “Multics relational data store (MRDS)”, www.mcjones.org/System_R/mrck.html. 13. 14. J. L. Peterson, J. S. Quarterman e A. Silbershatz, “4.2BSD and 4.3BSD as examples of the UNIX system”, ACM Computing Surveys, v. 17, n2 4, dez. 1985, p. 388. “UNIX system calls links”, www.softpanorama.org/lnternals/ 29. 30. unix_system_calkjinks.$html. 15. 16. 17. 18. 19. B. W. Lampson, “A scheduling philosophy for multiprocessing system”, Communications o f the ACM, v. 11, n25,1968, p. 347-360. “IA-32 Intel architecture software developerís manual”, v. 3, System Programmer’s Guide, 2002. “IA-32 Intel architecture software developerís manual”, v. 3, System Programmerys Guide, 2002. “IA-32 Intel architecture software developerís manual”, v. 3, System ProgrammeFs Guide, 2002, p. 5-16. “IA-32 Intel architecture software developerís manual”, v. 3, System ProgrammeFs Guide, 2002. D. Bovet e M. Cesati, Understanding the Linux Kernel. 0 ’Reilly, 2001, p. 253. M. Bar, “Kernel Korner: the Linux Signals handling model”, Linux Journal, maio 2000, www.linuxjournal.com/ artide.php?sid=3985. 1 9 9 3 , ftp://ftp.stratus.com/pub/vos/multics/pg/mvm.html. 9. “IA-32 Intel architecture software developer’s manual”, v. 3, System ProgrammeFs Guide, 2002, p. 5-2, 5-5. “IA-32 Intel Architecture Software Developer’s Manual”, v. 3, System Programmer’s Guide, 2002, p. 2-8. M. Bar, “Kernel Korner: the Linux signals handling model”, Linux Journal, maio 2000, www.linuxjournal.com/ artide.php?sid=3985. 1 9 9 3 , ftp://ftp.stratus.com/pub/vos/multics/pg/mvm.html. 7. T. Krazit, “Study: Intel’s Q2 market share up, AMD’s down”, InfoWorld, 31 jul. 2002, archive.infoworld.com/articles/hn/xml/02/ 31. 32. 33. 34. W. M. Gentleman, “Message passing between sequential processes: the reply primitive and the administrator concept”, Software — Practice and Experience, v. 11, 1981, p. 435466. R. D. Schlichting e F. B. Schneider, “Understanding and using asynchronous message passing primitives”. In: Proceedings of the Symposium on Principies ofDistrihuted Computing, 18-20 ago. 1982, Ottawa, Canadá, ACM, Nova York, p. 141-147. J. A. Stankovic, “Software communication mechanisms: procedure calls versus messages”, Computer, v. 15, n2 4, abr. 1982. J. Staustrup, “Message passing communication versus procedure call communication”, Software — Practice and Experience, v. 12, n2 3, mar. 1982, p. 223-234. D. R. Cheriton, “An experiment using registers for fast message-based interprocess Communications”, Operating Systems Review, v. 18, n2 4, out. 1984, p. 12-20. R. Olson, “Parallel processing in a message-based operating system”, IEEE Software, v. 2, n2 4, jul. 1985, p. 39-49. G. R. Andrews, “Synchronizing resources”, ACM Transactions on Programming Languages and Systems, v. 3, n2 4, out. 1981, p. 405-430. G. Andrews e F. Schneider, “Concepts and notations for concurrent programming”, ACM Computing Surveys, v. 15, n2 1, mar. 1983, p. 3-44. D. Bovet e M. Cesati, Understanding the Linux Kernel. 0 ’Reilly, 2001, p. 524-532. Capítulo 3 35. 36. K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed., v. 2 b , jan. 1 9 7 9 , cm.bell-labs.com/7thEdMan/ 52. bswv7.html. 53. K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed., v. 2b, jan. 1979, cm.bell-labs.com/7thEdMan/ 54. FreeBSD Handbook: Processes, 2 0 0 2 , www.freebsd.org/ 39. 55. K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed.., v. 2b, jan. 1979, cm.bell-labs.com/7thEdMan/ 56. bswv7.html. 57. K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed., v. 2b, jan. 1979, cm.bell-labs.com/7thEdMan/ 58. 41. D. Ritchie e K. Thompson, ‘T he UNIX time-sharing Sys­ tem”, Communications oftheACM , jul. 1974, p. 370-372. FreeBSD Handbook: Processes, 2 0 0 2 , www.freebsd.org/ K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed., v. 2b, jan. 1979, cm.bell-labs.com/7thEdMan/ 44. 45. 46. 47. Lucent Technologies, ‘The creation of the UNIX operating system”, 2002, www.bell-labs.com/history/unix/. E. Organick, The multics system: an examination o f its structure. Cambridge, MA: MIT Press, 1972. Lucent Technologies, “The creation of the UNIX operating system”, 2002, www.bell-labs.com/history/unix/. Sun Microsystems, “Executive bios: B i l l Joy”, www.sun.com/ 60. Hewlett-Packard Company, “HP-UX 1li operating system,”, www.hp.com/productsl / unix/operating/. 61. 49. hpinfo/newsroom/press/30may02b.htm. 62. 51. FreeBSD Hypertext Man Pages, 2002 www.freebsd.org/cgi/ man.cgi?query=execve&sektion=2. aboutsun/media/ceo/mgtJoy.html. B. Calkins, “The history of Solaris”, 15 dez. 2001, unixed.com/ functions/_Exit.html. Lucent Technologies, ‘The creation of the UNIX operating system”, 2002, www.bell-labs.com/history/unix/. L. Torvalds, “Linux history”, 31 jul. 1992, w w w .li.org/ 63. 64. 65. 66. UNIXhelpfor Users, Version 1.3.2: Nice, unixhelp.ed.ac.uk/CGI/ man-cgi?nice. 67. K. Thompson, “UNIX implementation”, UNIX Programeis Manual: 7th ed., v. 2b, jan. 1979, cm.bell-labs.com/7thEdMan/ bswv7.html. linuxhistory.php. 50. Hewlett-Packard Company, “Hewlett Packard receives top UNIX ranking from D.H. Brown”, 30 maio 2002, www.hp.com/ D. Ritchie e K. Thompson, “The UNIX time-sharing Sys­ tem”, Communications o f the ACM, jul. 1974, p. 370-372. D. Ritchie e K. Thompson, “The UNIX time-sharing sys­ tem”, Communications oftheACM , jul. 1974, p. 370-372. “Exit”, The Open Group Base Specifications, Issue 6, IEEE Std 1003.1, 2 0 0 3 , www.opengroup.org/onlinepubs/007904975/ Resources/hrstoryofsolaris.pdf. 48. J. Coelho, “comp.aix.unix frequently asked questions (Part 1 of 5 ) ” , 10 out. 2 0 0 0 , www .faqs.org/faqs/aix-faq/partl/. IBM, “AIX aAffinity with Linux: technology paper,”, <www- 59. bswv7.html. 43. The NetBSD Foundation, Inc., “About the NetBSD project”, 17 jul. 2 0 0 3 , www.netbsd.org/Misc/about.html. J. Howard, “Daemon news: the BSD family tree”, abr. 2001, l.ibm.com/servers/aix/products/aixos/linux/affinity_linux.pdf>. I. Springer, I., “comp.sys.hp.hpux FAQ,”, 2 0 September 2 0 , set. 2 0 0 3 , <www.faqs.org/faqs/hp/hpux-faq/>. handbook/basics-processes.html. 42. Security Electronics Magazine, “OpenBSD: secure by default”, jan. 2002, www.semweb.com/jan02/itsecurityian.htm. J. Howard, “Daemon news: the BSD family tree”, abr. 2001, www.daemonnews.org/200104/bsd_family.html. bswv7.html. 40. D. Jorm, “An overview of OpenBSD security”, 8 ago. 2000, www.daemonnews.org/200104/bsd_family.html. handbook/basics-processes.html. 38. g j www.onlamp.com/pub/a/bsd/2000/08/08/0penBSD.html. bswv7.html. 37. Conceito de,processos www.openbsd.org/faq/faql .html. The Design and Implementation o f 4.4BSD Operating System: Interprocess Communication, 2002, www.freebsd.org/ J. Howard, “Daemon news: the BSD family tree”, abr. 2001, doc/en_US.IS08859-l/books/design-44bsd/x659.html. N. Holland, “ 1 — Introduction to OpenBSD”, 23 jul. 2003, www.daemonnews.org/200104/bsd_family.html. 68. C ix ^ m io h CoKcdtds tkrtcid 0 toque, da aranha, que, requintada, elegância,! Sente, cada, thread e, vive, ao Longo da, Linha,. A lexander Pope Não se,pode, conceber a, maioria, sem,a unidade,. Platão Homero Estar acordado é, estar vivo. Henry David Thoreau Apenas um, sinal e, uma voz, distante, na escuridão. Henry W adsworth Longfellow Este capítulo apresenta: • A motivação na criação de threads. • As semelhanças e diferenças entre processos e threads. • Os vários níveis de suporte a threads. • O ciclo de vida de um thread. • Sinalização e cancelamento de threads. • O básico sobre threads POSIX, Linux, Windows XP e Java. Capítulo 4 Conceitos d&tkrecuü 89 4.1 Introdução Sistemas operacionais m ais antigos habilitavam com putadores a executar diversos program as concorrentem ente, mas as linguagens de program ação da época não perm itiam que program adores especificassem atividades concorrentes (veja o quadro “Reflexões sobre sistem as operacionais, Concorrência”). Essas linguagens em geral forneciam apenas um conjunto sim ples de estruturas de controle que habilitava os program adores a especificar um único thread de controle. Os tipos de operações sim ultâneas que os com putadores realizavam eram geralm ente im plem entados por primitivas de sistem as operacionais, disponíveis apenas para program adores de grande experiência. A linguagem de program ação Ada, desenvolvida pelo D epartam ento de D efesa dos Estados Unidos no final da década de 1970 e início da de 1980, foi uma das primeiras a fornecer primitivas explícitas de concorrência. A Ada foi am plam ente disponibilizada para em presas contratadas, especializadas em defesa, que fabricavam sistem as m ilitares de com ando e controle. Entretanto, essa linguagem não foi extensivam ente adotada por universidades e em presas com erciais. Nos últimos anos muitas linguagens de programação de uso geral, incluido Java, C#, Visual C++ .NET, Visual Basic.NET e Python, disponibilizaram primitivas de concorrência para o program ador de aplicações. O program ador especifica que as aplicações contêm ‘threads de execução’, cada thread designando um a parte de um program a que pode executar concorrentem ente com outros threads. Essa tecnologia, denom inada m u ltith re a d in g , dá ao program ador capacidade poderosa que não está disponível diretam ente em linguagens com o C e C++, as linguagens sobre as quais a Java e a C # estão baseadas. C e C++ são denom inadas linguagens m onothread. [Nota: em muitas plataform as de computador, program as C e C++ podem realizar multithread usando bibliotecas de código específico, porém essas não fazem parte das versões padronizadas ANSI/ISO dessas linguagens.] O suporte do sistem a operacional para threads é essencial para suportar linguagens que forneçam sem ântica de multithread. Escrever programas multithread pode ser complicado. Embora a mente humana possa executar funções concorrentemente, as pessoas acham difícil alternar entre ‘correntes de pensam ento’ paralelas. Para entender por que aplicações m ultithread podem ser difíceis de program ar e compreender, experim ente fazer o seguinte: abra três livros na página 1 e tente ler os três ao mesmo tempo. Leia algum as palavras do prim eiro livro, algum as do segundo e outras do terceiro; em seguida, de onde parou, volte e leia algum as palavras do primeiro livro e assim por diante. A pós esse experim ento você vai dar valor a alguns dos desafios fundam entais do m ultithread — alternar entre livros, ler um pouco, lem brar o lugar em que parou Reflexões C o ^ ic o n ín c ia y N este livro ve re m o s num e­ rosos e xe m p lo s de coisas que podem a c o n te ce r c o n c o rre n te ­ mente. Operações de E/S podem prosseguir concorrentemente com a execução de programa; diversos processadores podem estar execu­ tando concorrentemente; diversos u su á rio s pod em e s ta r usando um sistem a co nco rre n te m e n te ; diversos processos podem estar tentando acessar dados comparti­ lhados concorrentemente; e diver­ sos com putadores podem estar funcionando concorrentemente na mesma rede. Estudamos questões de concor­ rência por todo o livro. Este capítulo e o anterior discutem processos e threads — abstrações usadas pelo sistema operacional para gerenciar atividades concorrentes. Os ca­ pítulos 5 e 6 preocupam-se com programação concorrente e com as delicadas questões de habilitar processos e threads concorrentes a trabalhar juntos para resolver pro­ blemas com uns de coordenação e com partilham ento de dados. O Capítulo 7 examina os assuntos deadlocks (impasses) e adiamento indefinido de processos e threads concorrentes. O Capítulo 8 trata do escalonamento de um proces­ sador entre processos e threads concorrentes. Os capítulos 9 e 11 abordam questões de organização e gerenciamento da memória entre processos e threads concorren­ tes. O Capítulo 15 discute sobre processos e threads concorrentes em sistemas multiprocessadores. O Capítulo 16 trata de redes de com putadores e dos fascinantes protocolos usados para garantir que c o m p u ta d o re s fu n c io n e m concorrentemente na mesma rede e não 'colidam uns com os outros'. Os capítulos 17 e 18 abordam pro­ blemas de construção de aplicações concorrentes, partes das quais são distribuídas através de uma rede de computadores. O Capítulo 19 trata de assuntos de segurança e proteção entre usuários concorren­ tes operando em com putadores individuais e em rede. Os capítulos dedicados ao estudo dos casos do Linux e do W indows XP mostram im plem entações de controle de concorrência no mundo real. 90 S U tw u is o jte ra à o fu iti em cada livro, aproxim ar o livro que está lendo para poder enxergar, afastar os que não está lendo — e, no meio de todo esse caos, tentar com preender o conteúdo dos livros! Revuão' 1. O texto m enciona que recursos de m ultithread não estão disponíveis diretam ente em linguagens com o C e C++. Com o, mesmo assim, program adores conseguem escrever códigos m ultithread nessas linguagens? 2. Qual a vantagem fundam ental que você obteria executando um a aplicação m ultithread em um sistem a multiprocessador em vez de um sistem a uniprocessador? R eip o itã i: i ) Existem bibliotecas de código específico que auxiliam o m ultithread. Todavia, elas não fazem parte dos padrões A N SI/ISO das linguagens C e C++, portanto, program as que as utilizam não são tão portáveis quanto programas ‘C ou C++ padrão’. 2) Os m últiplos threads da aplicação que realizam tarefas paralelas poderíam executar verdadeiramente de m aneira sim ultânea em processadores separados acelerando a execução da aplicação. 4.2 Üefudção d&tkrecuí Devido ao am plo suporte para m ultithread em linguagens de program ação, praticam ente todos os sistemas operacionais recentes fornecem , no mínim o, algum suporte para threads. Um thread, às vezes denom inado processo leve (Lightweight Process — LW P), com partilha m uitos atributos de um processo. Threads são escalonados em um processador, e cada thread pode executar um conjunto de instruções independentem ente de outros processos e threads. Entretanto, eles não são planejados para existir sozinhos — norm alm ente pertencem a processos tradicionais, às vezes denom inados processos pesados (H eavyweight Processes — H W P ). Os threads de um processo com partilham m uitos dos seus recursos — mais notavelm ente seu espaço de endereçam ento e arquivos abertos — para m elhorar a eficiência com que realizam suas tarefas. O nom e ‘thread’ refere-se a um fluxo único de instruções ou fluxo de controle; threads em um processo podem executar concorrentem ente e cooperar para atingir um a m eta com um. Em um sistem a m ultiprocessador, m últiplos threads são capazes de executar sim ultaneamente. Threads possuem um subconjunto dos recursos contidos em um processo. Recursos com o registradores de proces­ sador, a pilha e outros dados específicos de threads (Thread-Specific D ata — TSD ) tais com o m áscaras de sinal (dados que descrevem quais sinais um thread não receberá, discutidos na Seção 4.7.1, “Entrega de sinal de thread”) são locais a cada thread, enquanto o espaço de endereçam ento pertence ao processo que contém os threads e é global para os threads (Figura 4.1). D ependendo da im plem entação de thread para determ inada plataform a, os threads podem ser gerenciados pelo sistem a operacional ou pela aplicação de usuário que os cria. Em bora m uitos sistem as operacionais suportem threads, as im plem entações variam consideravelm ente. Threads Win 32,1C-threads2 e threads PO SIX 3 são exemplos de bibliotecas de suporte a threads com APIs díspares. T h re a d s W in32 são usados nos sistem as operacionais W indows de 32 bits da M icrosoft; C -th re a d s são criados por meio de uma biblioteca de In fo rm a ç ã o g lo b a l p a ra to d o s o s th r e a d s d e u m p ro c e s s o r In fo rm a ç ã o local p a ra c a d a th re a d \ 'UTOy 4 .1 1 ReíatMH/LHimto entre, tkreruí e,processo. Capítulo 4 Conceitos d&threads 91 suporte a threads no m icronúcleo M ach (sobre o qual é construído o M acintosh OS X) e também suportados pelos sistem as operacionais Solaris e W indows NT. A especificação POSIX fornece o padrão P th read s. O objetivo primordial dos Pthreads é perm itir a portabilidade de program as m ultithread por m eio de m últiplas plataform as de sistemas operacionais. O POSIX foi im plem entado em um a variedade de sistem as operacionais, incluindo o Solaris, o Linux e o W indows XP. Ret/Uão' 1. Por que os processos tradicionais são cham ados de processos pesados? 2. Porque é difícil escrever aplicações m ultithread portáveis? R e ip o itã i: i ) A distinção prim ária entre ‘pesos’ relativos de processos tradicionais e threads está no modo com o os espaços de endereçam ento são alocados. Q uando um processo é criado, recebe um espaço de endereçam ento alocado exclusivam ente a ele. Q uando um thread é criado ele com partilha o espaço de endereçam ento do processo, portanto, threads são mais ‘leves’ do que processos. 2) N ão existe nenhum a biblioteca de suporte a threads padronizada que seja im plem entada em todas as plataform as. 43 Motivação fuv criação de, threads N o capítulo anterior apresentam os o conceito de processo e descrevem os com o sistem as de com putador se benefi­ ciam de m elhores eficiência e desem penho quando vários processos executam concorrentem ente. Q uando o conceito de processo foi introduzido pelo projeto M ultics na década de 1960, com putadores continham , tipicam ente, um único processador, e as aplicações eram relativam ente pequenas.4 Os processos daquela época eram projetados para executar um único thread de controle em um processador por vez. Tendências subsequentes no projeto de softw are e hardw are indicaram que sistem as poderíam se beneficiar de m últiplos threads de execução por processo. Eis alguns fatores que m otivaram o m ultithread: • Projeto de software — Devido à m odularidade e ao projeto de com piladores, muitas das aplicações atuais contêm segm entos de código que podem ser executados independentem ente do restante da aplicação. Isolar segm entos de códigos independentes em threads individuais pode melhorar o desempenho da aplicação e fazer com que fique mais sim ples exprim ir tarefas inerentem ente paralelas em código (veja o quadro “Reflexões sobre sistem as operacionais, Paralelism o”). • D esem penho — Um problem a das aplicações m onothread é que atividades independentes não podem ser escalo­ nadas para executar em m últiplos processadores. Em um a aplicação multithread, os threads podem com partilhar um processador (ou conjunto de processadores) para que várias tarefas sejam realizadas em paralelo. Execução concorrente paralela pode reduzir significativamente o tempo requerido para um a aplicação m ultithread concluir sua tarefa, especialm ente em sistemas m ultiprocessadores, em com paração com um a aplicação m onothread que pode executar som ente em um processador por vez e deve realizar suas operações em seqüência. E mais, em processos multithread, threads prontos podem executar enquanto outros estão bloqueados (isto é, esperando conclusão de E/S). • Cooperação — M uitas aplicações dependem de com ponentes independentes para com unicar e sincronizar ativi­ dades. A ntes dos threads, esses com ponentes executavam com o m últiplos processos ‘pesados’ que estabeleciam canais de com unicação interprocessos via núcleo.5,6 O desem penho com um a abordagem de m últiplos threads leves norm alm ente é m elhor do que com um a abordagem de m últiplos processos pesados, porque os threads de processo podem se com unicar usando seu espaço de endereçam ento com partilhado. Hoje, aplicações m ultithread são com uns nos sistem as de com putadores. Um servidor Web é um dos am bientes em que os threads podem m elhorar extraordinariam ente o desem penho e a interatividade. Servidores Web tipicam ente recebem requisições de aplicações rem otas para páginas Web, imagens e outros arquivos. É com um que servidores Web atendam a cada requisição com um thread separado. O processo que recebe requisições pode conter um thread que atende a requi­ sições da Internet. Para cada requisição recebida, é gerado um novo thread que interpreta a requisição, recupera a página Web e a transm ite ao cliente (tipicam ente um navegador Web). A pós a geração de um novo thread, seu pai pode continuar a atender novas requisições. Com o muitos servidores Web são sistemas m ultiprocessadores, diversas requisições podem ser recebidas e atendidas concorrentem ente por diferentes threads, m elhorando am bos, o rendim ento e o tempo de resposta. A sobrecarga incorrida pela criação e destruição de um thread para atender a cada requisição é substancial. Em conseqüência, a m aioria dos servidores Web de hoje mantém um conjunto de threads destinados a atender a novas requisições à m edida que elas chegam. Esses threads não são destruídos após atender à requisição; ao contrário, voltam ao conjunto e são no­ vam ente designados para requisições que estão entrando. Discutirem os agrupam entos de threads m ais detalhadam ente na Seção 4.6.3, “Com binação de threads de usuário e de núcleo”. 92 S U tw u is o p e ra c ío fta ls Paralelismo Um m odo de im p le m e n ta r p a ra le lis m o é fa z ê -lo na m á­ quina local com té cnicas com o m ultip ro gra m a ção , m u ltith re a d , multiprocessamento e paralelismo maciço. O hardware de computa­ dor é construído para poder realizar processam ento em paralelo com entrada/saída. Multiprocessadores são construídos para ter diversos p ro cessa d ores trabalhando em paralelo — paralelismo maciço leva isso ao extremo com centenas, mi­ lhares ou até mais processadores trabalhando em paralelo. Hoje, um outro tipo de paralelis­ mo está se tornando proeminente, a saber, computação distribuída em redes de computadores. Estudare­ mos com putação distribuída nos capítulos 16 a 18, nos quais exami­ namos redes de computadores e as questões da construção de sis­ temas operacionais distribuídos. Um sistema operacional é, primariamen­ te, um administrador de recursos. Durante anos esses recursos foram o hardware, o software e os dados de um sistema de computador lo­ cal. Hoje, um sistema operacional distribuído deve gerenciar recursos onde quer que eles residam, seja no sistema do com putador local, seja em sistemas de computado­ res distribuídos em redes como a Internet. Processadores de texto usam threads para aum entar a produtividade do usuário e m elhorar a interatividade. Cada vez que o usuário digita um caractere no teclado, o sistem a operacional recebe um a interrupção de teclado e em ite um sinal para o processador de texto. Esse responde arm azenando o caractere na m em ória e exibindo-o na tela. C om o os com putadores atuais podem executar centenas de m ilhões de instruções de processador entre digitações sucessivas, processadores de texto podem executar diversos outros threads entre as interrupções do teclado. P or exem plo, m uitos dos processadores de hoje detectam erros de grafia nas palavras à m edida que são digitadas e salvam periodicam ente um a cópia do docum ento para um disco para evitar perda de dados. C ada característica é im plem entada com um thread separado — consequentem ente, o processador de texto pode responder às interrupções do teclado m esm o que um ou m ais de seus threads estejam bloqueados devido a um a operação de E/S (por exem plo, salvar um a cópia do arquivo em disco). Revuão' 1. Como um projeto de software melhorado ajuda a fazer que aplicações multithread executem mais rapidamente? 2. Por que threads do mesmo processo em geral se comunicam mais eficientemente do que em processos separados? R eip o ità i: 1) M uitas aplicações contêm segm entos de código que podem executar independentem ente uns dos ou­ tros. Q uando designados para threads separados, esses segmentos de código podem, por exemplo, executar em m últiplos processadores sim ultaneam ente. 2) Threads do m esm o processo podem se com unicar por seu espaço de endereçam ento com partilhado e não precisam depender de m ecanism os de IPC que invoquem o núcleo. 4.4 Estados threads: ciclo d&rida, d&UJUbthread Com o discutido na Seção 3.2, “Estados de processo: ciclo de vida de um processo”, cada processo pode ser visto com o transitando entre um a série de estados discretos de processo. N esse m odelo, cada processo contém um único thread de controle; portanto, poderiam os ter dito tam bém que cada thread de controle passa por um a série de estados discretos. Quando processos contêm m últiplos threads de controle podem os considerar cada thread com o transitando entre um a série de estados de th re a d discretos. Assim , grande parte da discussão dos estados de processo e de transições de estado da Seção 3.2 aplica-se a estados e a transições de estado de threads. Por exemplo, considere o seguinte conjunto de estados baseado, em grande parte, na im plem entação de threads no Java (Figura 4.2).7Em Java, um novo thread inicia seu ciclo de vida no estado nascido {bom ). Perm anece no estado nascido até que o program a inicie o thread, o que o coloca no estado p ro n to — às vezes cham ado de estado executável {runnable). Em outros sistem as operacionais um thread é iniciado na sua criação, elim inando o estado nascido. O thread pronto de prioridade m ais alta entra no estado em execução (com eça a executar) quando obtém um processador. Um thread em execução entra no estado m orto (dead) quando conclui sua tarefa ou term ina de algum m odo qual­ quer. A lgum as bibliotecas de suporte a threads perm item que um thread term ine outro thread, o que força esse últim o a Capítulo 4 fig u r a , 4.2 Conceitos d&tkrecuü 93 Ciclo devida, do tkreazí. passar para o estado m orto. U m a vez que um thread entre no estado m orto seus recursos são liberados e ele é rem ovido do sistem a. U m thread entra no estado bloqueado quando deve esperar pela conclusão de uma requisição de E/S (ler dados de um disco). U m thread bloqueado não é despachado para um processador até que sua requisição de E/S tenha sido concluída. Nesse ponto, o thread retom a ao estado pronto, para que possa retom ar a execução quando um processador estiver dis­ ponível. Q uando um thread deve esperar por um evento (por exem plo, m ovim ento do m ouse ou um sinal de outro thread) pode entrar no estado de espera. U m a vez nesse estado, ele volta ao estado pronto quando um outro thread o n o tificar (o termo a c o rd a r tam bém é usado). Quando um thread em espera recebe um evento de notificação, ele transita do estado em espera para o estado pronto. Um thread em execução pode entrar no estado adorm ecido durante um período de tempo especificado (denom inado p erío d o d e sono). U m thread adorm ecido volta ao estado pronto quando seu intervalo designado de sono expira. Threads adorm ecidos não podem usar um processador, mesmo que haja um disponível. Os threads adorm ecem quando não têm, m om entaneam ente, nenhum trabalho a realizar. Por exem plo, um processador de texto pode conter um thread que grave periodicam ente um a cópia do docum ento corrente em disco para recuperação posterior. Se o thread não dorm isse entre backups sucessivos, exigiría um laço no qual ele testasse continuam ente se deve ou não gravar um a cópia do docum ento no disco. Esse laço consum iría tempo de processador sem realizar trabalho produtivo, reduzindo o desem penho do sistema. Nesse caso, é m ais eficiente que o thread especifique um intervalo de sono (igual ao período entre backups sucessivos) e entre no estado adorm ecido. O thread adorm ecido volta ao estado pronto quando seu intervalo de sono expira, m omento em que grava um a cópia do docum ento em disco e retom a ao estado adormecido. Revuão' 1. Com o um thread entra no estado m orto? 2. Q uais as semelhanças entre os estados de espera, bloqueado e adorm ecido? Q uais as diferenças? 94 S istem as o p e ra cio n a is R e ip o ifa i: d Um thread entra no estado morto quando conclui sua tarefa ou quando um outro thread o term ina. 2) Esses estados são sem elhantes porque quando os threads estão neles não podem usar um processador mesmo que esteja disponível. U m thread bloqueado não pode ser despachado, pois está esperando por um a operação de E/S requisitada. Nesse caso, o sistem a operacional é responsável por eventualm ente desbloquear o thread. U m thread em espera não pode ser despachado até receber um evento do hardw are ou do software que não é iniciado pelo sistem a operacional (por exem ­ plo, utilização do teclado ou um sinal de um outro thread). N esse caso o sistem a operacional não pode controlar se, ou quando, um thread em espera eventualm ente será acordado. Um thread adorm ecido não pode executar porque notificou explicitam ente ao sistem a que ele não deve executar até que seu intervalo de sono expire. 4.5 Operações de thread Threads e processos têm muitas operações em com um, como: • criar • sair (ou seja, terminar) • suspender • retom ar • dorm ir • acordar Sob m uitos aspectos, a criação de threads é semelhante à criação de processos. Quando um processo gera um thread, a biblioteca de suporte a threads inicia estruturas de dados específicas de thread que arm azenam inform ações com o con­ teúdo de registradores, o contador do program a e um identificador de thread (ID). D iferentem ente da criação de processo, a de thread não requer que o sistem a operacional inicialize recursos com partilhados entre o processo-pai e seus threads (por exemplo, o espaço de endereçam ento). M uitos sistem as operacionais requerem um núm ero m enor de instruções para com partilhar recursos do que para inicilizá-los, portanto, nesses sistemas, a criação de thread é mais rápida do que a de processo.8 Do mesmo modo, o término de um thread geralm ente é m ais rápido do que o de um processo. A redução da sobrecarga decorrente da criação e térm ino de threads incentiva os desenvolvedores de software a im plem entar tarefas paralelas usando m últiplos threads em vez de m últiplos processos quando isso for possível. Algum as operações de threads não correspondem exatam ente às operações de processos, com o as seguintes: • c a n c e la r — Um thread ou processo pode fazer com que um thread term ine prem aturam ente, cancelando-o. D i­ ferentem ente do térm ino de um processo, o cancelam ento de um thread não garante que ele termine. Isso porque threads podem desativar ou m ascarar sinais; se um thread m ascarar o sinal de cancelam ento, ele não receberá o sinal até que o sinal de cancelamento seja reabilitado pelo thread.9 Entretanto, um thread não pode mascarar um sinal de abortar. • asso ciar — E m algum as im plem entações de thread (por exemplo, W indows XP), quando um processo é iniciado, ele cria um th re a d p rim á rio . O thread prim ário age com o qualquer outro thread, exceto que, se ele voltar, o pro­ cesso termina. Para evitar que um processo term ine antes que todos os seus threads concluam a execução, o thread prim ário tipicam ente dorme até que cada thread que ele criar tenha concluído a execução. N esse caso, diz-se que o thread prim ário se associa a cada um dos threads que cria. Q uando um thread se associa a outro thread, o primeiro não executa até que o últim o term ine.10 Em bora a m aioria das im plem entações de thread suporte as operações discutidas nesta seção, outras operações são específicas de bibliotecas de suporte a threads particulares. Nas seções a seguir apresentam os diversas im plem entações populares de thread e discutim os questões que o projetista deve abordar ao criar um a biblioteca de suporte a threads. Reviião' 1. Qual a diferença entre um sinal de cancelam ento e um sinal de abortar, discutidos na Seção 3.5.1, “ Sinais” ? 2. Por que a criação de threads requer, tipicam ente, um núm ero m enor de ciclos de processo do que a criação de processos? R eA p a ifa i l 1) Q uando um thread recebe um sinal de abortar, ele é term inado im ediatam ente (ou seja, threads não podem m ascarar sinais de abortar). Q uando um thread é cancelado, ele pode continuar existindo até desm ascarar o sinal de cancelam ento. 2) D iferentem ente da criação de processos, a criação de threads requer que o sistem a operacional inicie som ente recursos locais do thread de controle. R ecursos globais (por exem plo, o espaço de endereçam ento do processo) podem ser com partilhados usando ponteiros, o que requer um núm ero significativam ente m enor de ciclos do que a inicialização. Capítulo 4 Conceitos d&threads 95 4-6 Modelos d&thread A s im plem entações de threads variam entre sistem as operacionais, mas quase todos os sistem as suportam um dos três sistem as prim ários de funcionam ento de threads. Esta seção estuda os três m odelos m ais populares: threads de usuário, threads de núcleo e um a com binação desses dois. 4.6.1 ThreaM usuário Sistemas operacionais m ais antigos suportavam processos que continham apenas um único contexto de execução.11 Conseqüentem ente, cada processo m ultithread era responsável por m anter inform ações de estado de thread, escalonar threads e fornecer primitivas de sincronização de threads. Os th re a d s de u su á rio executam operações de suporte a threads no espaço do usuário, o que significa que os threads são criados por bibliotecas em tem po de execução que não podem executar instruções privilegiadas nem acessar as primitivas do núcleo diretam ente.12Threads de usuário são transparentes para o sistem a operacional — esse trata cada processo m ultithread com o um único contexto de execução, o que significa que o sistem a operacional despacha o processo m ultithread com o um a unidade, ao contrário de despachar cada thread individual. Por essa razão, im plem entações de thread de usuário tam bém são denom inadas m apeam entos de thread m uito s-p a ra -u m porque o sistem a operacional m apeia todos os threads de um processo m ultithread para um único contexto de execução (Figura 4.3). Q uando um processo em prega threads de usuário, são as bibliotecas de nível de usuário que realizam operações de escalonam ento e despacho nos threads do processo, pois o sistem a operacional não está ciente de que o processo contém m últiplos threads. O processo m ultithread continua a executar até que seu quantum expire ou até sofrer preem pção pelo núcleo.13 A im plem entação de threads em espaço de usuário em vez de em espaço de núcleo traz diversos benefícios. Threads de usuário não precisam que o sistem a operacional suporte threads, logo, são m ais portáveis porque não dependem da API de gerenciam ento de threads de um sistem a operacional particular. Uma outra vantagem é que, com o é a biblioteca de suporte a threads, e não o sistem a operacional, que controla o escalonam ento de threads, os desenvolvedores de apli­ cações podem ajustar o algoritm o de escalonam ento da biblioteca de suporte a threads para atender às necessidades de aplicações específicas.14 E mais, threads de usuário não invocam o núcleo para escalonam ento de decisões ou procedim entos de sincronização. Lembre-se, da Seção 3.4.1, “Processam ento de interrupções”, que um sistem a perde um certo número de ciclos de proces­ sador com o sobrecarga quando ocorre um a interrupção, tal com o uma cham ada ao sistema. Portanto, processos m ultithread de usuário que realizam operações freqüentes de suporte a threads (escalonam ento e sincronização) beneficiam-se da baixa sobrecarga, com parados a threads que dependem do núcleo para tais operações.15 O desem penho do thread de usuário varia dependendo do sistem a e do com portam ento do processo. M uitas das defi­ ciências de threads de usuário estão relacionadas com o fato de que, para o núcleo, um processo m ultithread é um único thread de controle. Por exemplo, threads de usuário não escalam bem para sistem as m ultiprocessadores, porque o núcleo não pode despachar os threads de um processo para m últiplos processadores sim ultaneam ente, portanto, threads de usuário podem resultar em desem penho abaixo do ótimo em sistemas m ultiprocessadores.16Em um mapeam ento de threads muitos- U m p ro c e s s o A T h re a d £11 l ü i ü ' T o d o s o s th re a d s d e u m p ro c e s s o m a p e ia m p a ra u m ú n ic o c o n t e x t o de execução fig u ra / 4 3 | Threads d&usudrío. E spaço d o u s u á rio A E spaço d o n ú c le o C o n te x to de execução S U tw u is o jte ra à o tu u s 96 para-um, todo o processo fica bloqueado quando algum de seus threads requisita um a operação bloqueante de E/S, pois o processo m ultithread inteiro é o único thread de controle que o sistema operacional reconhece. M esm o que o processo m ultithread contenha threads no estado pronto, nenhum de seus threads pode executar até que o thread bloqueado passe para pronto, o que pode fazer que o progresso da execução se arraste no caso de processos m ultithread que bloqueiam freqüentem ente. Após o bloqueio de um thread de usuário, o núcleo despachará um outro processo que pode conter threads de prioridade mais baixa do que a dos threads prontos contidos no processo bloqueado. Por conseguinte, threads de usuário tam bém não suportam escalonam ento de prioridades no âm bito do sistema, o que pode ser particularm ente prejudicial para processos multithread de tem po real.17 N ote que algum as bibliotecas de suporte a threads traduzem cham adas bloqueantes ao sistem a para cham adas não bloqueantes para enfrentar esse problem a.18 Rerfião' 1. Explique por que im plem entações de thread de usuário prom ovem a portabilidade. 2. Por que, em m apeam entos de thread muitos-para-um , o sistem a operacional bloqueia o processo m ultithread inteiro quando um único thread fica bloqueado? R eip o étã i 1 1) Threads de usuário apresentam uma A PI às aplicações que é independente da API do sistema operacional. 2) Para o sistem a operacional, o processo m ultithread inteiro é um único thread de controle. Portanto, quando o sistema operacional recebe um a requisição de E/S bloqueante, ele bloqueia todo o processo. 4.6.2 ThvejuU núcleo Threads de núcleo tentam resolver as limitações dos threads de usuário mapeando cada thread para seu próprio contexto de execução. Consequentem ente, threads de núcleo em geral são descritos com o mapeamento de thread um-para-um (Figura 4.4). Esses m apeam entos requerem que o sistem a operacional forneça a cada thread de usuário um thread de núcleo que o sistem a operacional pode despachar. Threads de núcleo são diferentes de processos pesados porque com partilham o espaço de endereçam ento do seu processo. Cada thread de núcleo tam bém arm azena dados específicos de thread, com o conteúdos de registradores e um identificador de thread para cada thread do sistema. Q uando um processo de usuário requisita um thread de núcleo por meio de cham adas ao sistem a definidas pela API do sistem a operacional, o sistem a operacional cria um thread de núcleo que executa as instruções do thread de usuário. O mapeamento um-para-um oferece muitos benefícios. O núcleo pode despachar os threads de um processo para diversos processadores ao mesmo tem po, o que pode m elhorar o desem penho de aplicações projetadas para execução concorrente.19 E mais, o núcleo pode gerenciar cada thread individualm ente, o que significa que o sistem a operacional pode despachar os threads prontos de um processo m esm o que um de seus threads esteja bloqueado. Portanto, aplicações que realizam bloqueio de E/S podem executar outros threads enquanto esperam que a operação E/S seja concluída, m elhorando, assim, a interatividade para aplicações que devem responder a entradas de usuário e increm entando o desem penho em geral, contanto que a aplicação possa se beneficiar de execução concorrente. Threads de núcleo habilitam o despachante do sistema operacional a reconhecer cada thread de usuário individualmente. Se o sistem a operacional im plem enta um algoritmo de escalonamento por prioridade, um processo que usa threads de núcleo Um processo r------------\ \ - Thread Espaço do usuário Espaço do núcleo figura/ 4.4 |TkruuU núcleo. Contexto de execução Capítulo 4 Conceitos d&tkrecuü 97 pode ajustar o nível de serviço que cada thread recebe do sistem a operacional designando prioridades de escalonam ento a cada um de seus threads.20 Por exemplo, um processo pode m elhorar sua interatividade designando um a prioridade alta a um thread que responda a requisições de usuário e prioridades m ais baixas para seus outros threads. Threads de núcleo nem sempre são a solução ótim a para aplicações multithread. Implem entações de thread de núcleo tendem a ser menos eficientes do que as de usuário, pois as operações de escalonamento e sincronização envolvem o núcleo, o que aum enta a sobrecarga. E mais, softwares que empregam thread de núcleo norm alm ente são menos portáveis do que os que em pregam thread de usuário — o program ador de aplicações que usar threads de núcleo deve modificar o programa para usar a API de thread para cada sistema operacional em que executar.21 Sistemas operacionais em conformidade com interfaces padronizadas com o POSIX reduzem esse problem a (veja o quadro “Reflexões sobre sistemas operacionais, Conform idade com padrões”)- Uma outra desvantagem é que threads de núcleo tendem a consum ir mais recursos do que threads de usuário.22 Por fim, threads de núcleo requerem que o sistema operacional gerencie todos os threads do sistema. Enquanto um a biblioteca de nível de usuário pode ser solicitada a gerenciar dezenas ou centenas de threads, o sistema ope­ racional pode ser solicitado a gerenciar milhares. Consequentemente, o desenvolvedor de aplicações deve estar seguro de que os subsistemas de gerenciam ento da memória e de escalonamento do sistema operacional tenham boa capacidade de escalagem para grandes números de threads. RevU cuy 1. Em quais cenários threads de núcleo são m ais eficientes do que threads de usuário? 2. Por que um a aplicação de software escrita para threads de núcleo é m enos portável do que um software escrito para threads de usuário? R e íp o ità i: i ) Se um a aplicação contiver threads que bloqueiam ou que podem executar suas instruções em paralelo, threads de núcleo são mais eficientes do que threads de usuário. 2) Software de aplicação que usa threads de núcleo depende da API de thread de um sistem a operacional particular. 4.6.3 Combinação d&threaM usuário c de, núcleo Alguns sistem as operacionais com o o Solaris e o W indowes X P vêm tentando cobrir a lacuna entre m apeam entos muitos-para-um e um -para-um criando um a im plem entação híbrida de threads. A com binação da im plem entação de threads de usuário e de núcleo é conhecida com o mapeam ento de thread muitos-para-muitos (m-to-m) (Figura 4.5).23 Com o seu nome sugere, essa im plem entação m apeia m uitos threads de usuário para um conjunto de threads de núcleo. Essa técnica R e fle x õ e s G\$\CmckÇ 0V&TAô\0\AAÍ$ c o n v p a c lr õ e * Imagine tentar acessar a Inter­ net sem os protocolos padronizados de rede. Ou imagine comprar uma lâmpada se os bocais não fossem padronizados. E até mais fundamen­ talmente, imagine o que seria dirigir se cada cidade resolvesse atribuir às luzes verde e vermelha dos se­ máforos significados diferentes dos padrões correntes de 'pare' e 'siga'. Há diversas organizações importan­ tes, nacionais e internacionais, que promovem padrões para a indústria de computadores, tais como POSIX, ANSI (American National Standards Institute), ISO (International Orga- nization for Standardization), OMG (Object Management Group), W3C (World W ide W eb Consortium) e muitas mais. Um projetista de sistemas ope­ racionais deve estar a par dos mui­ tos padrões aos quais um sistema deve obedecer. Muitas vezes esses padrões não são estáticos; pelo con­ trário, evoluem conforme mudam as necessidades da comunidade mun­ dial dos usuários de computadores e de comunicação. Padrões também têm desvanta­ gens — podem retardar ou até mes­ mo sufocar a inovação. Eles forçam as organizações de desenvolvimento de sistemas operacionais (e outras) a gastar significativas quantidades de tempo e dinheiro para obedecera um vasto conjunto de padrões, muitos dos quais obscuros e até desatua­ lizados. Referimo-nos a padrões e a organizações de padrões por todo o livro e consideramos cuidadosa­ mente o significado e o impacto da conformidade aos padrões. 98 Sistemas operacionais Processo Pi Processo P2 Processo P3 í Espaço u do usuário Cada thread de núcleo pode mapear para um ou mais threads de usuário -T hread - Contexto de execução Espaço do núcleo - Figura, 4-5 Modelo de, operação de thread, híbrido. também é denom inada mapeamento de thread m -to-n , porque o núm ero de threads de usuário e o núm ero de threads de núcleo não precisam ser iguais.24 M apeam entos de threads um -para-um requerem que o sistema operacional aloque estruturas de dados que representam threads de núcleo. Conseqüentemente, a quantidade de memória consum ida pelas estruturas de dados do núcleo pode se tom ar significativa à m edida que cresce o número de threads no sistema. O mapeam ento de threads m uitos-para-m uitos reduz essa sobrecarga im plem entando o reservatório de threads (thread pooling). Essa técnica perm ite que um a aplicação especifique o número de threads de núcleo que requer. Por exemplo, na Figura 4.5, o processo P, requisitou três threads de núcleo. Note que os threads T, e T 2 são m apeados para um único thread de núcleo — um mapeam ento m uitos-para-um — , o que exige que a aplicação mantenha inform ação de estado para cada um de seus threads. A conselham os os desenvolve­ dores de aplicações a usar mapeam ento muitos-para-um para threads que exibem um baixo grau de paralelismo (ou seja, não podem se beneficiar da execução simultânea). Os outros threads do processo Pl (T3e T4) são m apeados para um thread de núcleo. Esses threads são gerenciados pelo sistem a operacional com o discutido na seção anterior. A existência de um reservatório de threads pode reduzir significativamente o núm ero de custosas operações de criação e destruição de threads. Por exemplo, a Web e sistem as de banco de dados criam com ffeqüência um thread para responder a cada requisição de serviço que chega. O reservatório de threads perm ite que os threads de núcleo continuem no sistem a depois que um thread de usuário morra. Então o thread de núcleo pode ser alocado a um novo thread de usuário que é criado m ais tarde. Isso m elhora os tem pos de resposta do sistem a em am bientes com o o de servidores Web, porque as requisições podem ser designadas para threads que já existam no reservatório. Esses threads de núcleo persistentes são denom inados threads operários, pois executam, tipicam ente, diversas funções diferentes, dependendo dos threads a eles designados.25 U m a vantagem do mapeam ento de thread m uitos-para-um é que as aplicações podem m elhorar seu desem penho per­ sonalizando o algoritm o de escalonam ento da biblioteca de suporte a threads. Todavia, com o discutido na Seção 4.6.1, “Threads de usuário” , se um único thread de usuário ficar bloqueado, o sistem a operacional bloqueia todo o processo multithread. U m a outra lim itação do mapeam ento de threads m uitos-para-um é que os threads de um processo não podem executar sim ultaneam ente em processadores múltiplos. Ativações de escalonador tentam resolver essas lim itações dos threads de usuário. U m a ativação de escalonador é um thread de núcleo que pode notificar eventos a um a biblioteca de suporte a threads de nível de usuário (por exemplo, um thread bloqueou ou um processador está disponível). Esse tipo de thread de núcleo é denom inado ‘ativação de escalonador’, porque a biblioteca de suporte a threads de usuário pode executar operações de escalonam ento de thread quando ‘ativada’ por um a notificação de evento às vezes denom inada upcall. Q uando um processo m ultithread é gerado, o sistem a operacional cria um a ativação de escalonador que executa o código de inicialização da biblioteca de suporte a threads de usuário do processo, que cria threads e requisita processa­ dores adicionais para seus threads se necessário. O sistem a operacional cria um a ativação do escalonador adicional para cada processador alocado a um processo, habilitando a biblioteca de usuário a designar diferentes threads para executar sim ultaneam ente em processadores múltiplos. Q uando um thread de usuário bloqueia, o sistema operacional salva o estado do thread para sua ativação de escalonador e cria um a ativação de escalonador para notificar a biblioteca de usuário que um de seus threads bloqueou. Então a biblio­ teca de suporte a threads de usuário pode salvar o estado do thread bloqueado da sua ativação de escalonador e designar um thread diferente para aquela ativação de escalonador. Esse m ecanism o im pede que o processo m ultithread inteiro fique bloqueado por causa do bloqueio de um de seus threads.26 Capítulo 4 Conceitos d&tkreads 99 A lim itação prim ordial do modelo de thread m uitos-para-m uitos é que ele com plica o projeto do sistem a operacional e não há um m odo-padrão para im plem entá-lo.27 Por exemplo, o modelo m uitos-para m uitos do sistem a Solaris 2.2 perm itia que aplicações de usuário especificassem o núm ero de threads de núcleo designados para cada processo; o Solaris 2.6 introduziu as ativações de escalonador. O interessante é que o Solaris 8 abandonou o m apeam ento de thread muitos-param uitos de seus predecessores em favor de um esquem a de m apeam ento de thread um -para-um m ais sim ples e escalável.28 O W indows XP, que não suporta ativações de escalonador, ajusta dinam icam ente o núm ero de threads operários de seus reservatórios de threads em resposta à carga do sistem a.29,30 Revíião' 1. Por que é ineficiente um a aplicação especificar um tam anho de reservatório de threads m aior do que o núm ero máxim o de threads de usuário prontos em qualquer instante durante a execução da aplicação? 2. Com o as ativações de escalonador m elhoram o desem penho em um mapeam ento de thread m uitos-para-m uitos? ReLpoStõn: D Cada thread operário do reservatório de threads consom e recursos do sistema, tal com o m emória. Se o núm ero de threads operários for m aior do que o de threads de usuário prontos, o sistem a incorre em sobrecarga devido à criação desnecessária de threads e à alocação ineficiente de memória. 2) Ativações de escalonador permitem que a aplicação indique com o os threads devem ser escalonados para m axim izar o rendimento. 4.7 Considerações sobre>implementações d&threads N esta seção discutirem os diferenças entre im plem entações de threads relativas à entrega de sinal de thread e cancela­ m ento de thread. Essas diferenças destacam questões fundam entais relativas a operações e gerenciam ento de threads. 4.7.1 Entrega/d&suiald&thretul Sinais interrom pem a execução do processo do m esm o m odo que interrupções de hardware, porém são gerados por software — ou pelo sistem a operacional ou pelos processos de usuários. Sinais tom aram -se um m ecanism o-padrão de com unicação interprocessos depois que apareceram no sistem a operacional UNIX. O sistem a operacional U N IX original não suportava threads, de m odo que sinais foram projetados para utilização com processos.31 Com o discutido na Seção 3.5.1, “Sinais” , quando o sistem a operacional entrega um sinal a um processo, esse faz uma pausa na sua execução e invoca um a rotina de tratamento de sinal para responder ao sinal. Quando o tratam ento de sinal é concluído, o processo retom a a execução (supondo que o processo não tenha saído).32 H á dois tipos de sinais: síncrono e assíncrono. Um sinal síncrono ocorre com o resultado direto de um a instrução execu­ tada pelo processo ou thread. Por exemplo, se um processo ou thread executar um a operação ilegal de m em ória, o sistem a operacional envia ao processo um sinal síncrono indicando a exceção. Um sinal assíncrono ocorre devido a um evento não relacionado com a instrução corrente; esses sinais devem especificar um identificador (ID) de processo para indicar o receptor do sinal. Sinais assíncronos são com um ente usados para notificar a conclusão de um processo E/S, suspender um processo, continuar um processo ou indicar que um processo deve term inar (consulte a Seção 20.10.1, “Sinais”, para um a lista de sinais POSIX). Q uando cada processo de um sistem a contém um único thread de controle, a entrega do sinal é direta. Se o sinal for síncrono (por exemplo, um a operação ilegal de m emória), ele será entregue ao processo que está executando correntem ente no processador que iniciou o sinal (pela geração de um a interrupção). Se o sinal for assíncrono, o sistem a operacional poderá entregá-lo ao processo ao qual se destina se esse estiver executando correntem ente, ou poderá adicionar o sinal a um a fila de sinais pendentes para ser entregue quando o processo receptor entrar em estado de execução. A gora considere o caso de um processo multithread. Se o sinal for síncrono será razoável entregá-lo ao thread que estiver executando correntem ente no processador que iniciou o sinal (pela geração de um a interrupção). Contudo, se ele for assíncrono, será preciso que o sistema operacional possa identificar o receptor do sinal. U m a solução é solicitar ao em issor que especifique um thread ID. Entretanto, se o processo em pregar um a biblioteca de threads de usuário, o sistema operacional não poderá determ inar qual thread deverá receber o sinal. Com o alternativa, o sistem a operacional pode im plem entar sinais de modo tal que o em issor especifique um ID de processo. Nesse caso o sistem a operacional deve decidir se entrega o sinal para todos os threads, para diversos threads ou para um thread do processo. Pode parecer estranho, mas, na verdade, esse é o m odelo de sinal que os sistem as UNIX e a especificação POSIX em pregam, e o objetivo é proporcionar com patibilidade com aplicações escritas originalm ente para o sistem a operacional UNIX (veja no site deste livro: “Curiosidades, Engenharia”). Segundo a especificação POSIX, processos enviam sinais especificando um identificador de processo, e não um iden­ tificador de thread. Para resolver o problem a da entrega do sinal de thread o POSIX usa mascaram ento de sinal. Uma máscara de sinal perm ite que um thread desabilite sinais de um tipo particular para não receber sinais daquele tipo. Assim, 100 Sistemas operaxionads um thread pode m ascarar todos os sinais, exceto os que quiser receber (Figura 4.6). N essa abordagem , quando o sistema operacional recebe um sinal para um processo, ele o entrega a todos os threads do processo que não estão mascarando sinais daquele tipo. D ependendo do tipo de sinal e da ação-padrão (veja a Seção 3.5.1, “Sinais”), os sinais podem ser enfileirados para entrega após o thread desm ascarar o sinal, ou o sinal pode ser sim plesm ente descartado. Por exemplo, na Figura 4.6 cada form a geom étrica representa um sinal de um tipo diferente (suspender, retomar, term inar). N esse caso, o sistem a operacional tenta entregar o sinal triangular a um processo multithread. N ote que am bos os threads 1 e 3 estão mascarando o sinal triangular. O thread 2 não o está mascarando; portanto, o sistem a operacional entrega o sinal triangular ao thread 2 que então invoca a rotina de tratam ento de sinais correspondente do processo. M ascaram ento de sinais perm ite que um processo divida a manipulação de sinais entre diferentes threads. Por exemplo, um processador de texto pode conter um thread que m ascara todos os sinais, exceto eventos de teclado. O único propósito desse thread seria gravar toques de teclado do usuário. M ascaram ento de sinais tam bém habilita o sistem a operacional a controlar qual thread recebe um sinal. Ao im plem entar um m ecanism o POSIX de entrega de sinal, o sistem a operacional tem de ser capaz de localizar uma m áscara de sinal para cada thread. Um mapeam ento de thread um -para-um sim plifica esse problem a porque o sistema operacional pode afixar um a m áscara de sinal a cada thread de núcleo, que corresponde exatam ente a um thread de usuá­ rio. Contudo, se o sistem a em pregar o modelo m uitos-para-m uitos, o m ascaram ento de sinais pode se tom ar complexo. Considere o caso em que um sinal assíncrono é gerado por um processo e o único thread que não m ascara o sinal não está correntem ente em execução. Nesse caso o sistem a operacional pode optar por adicionar o sinal a um a lista de sinais pendentes ou descartá-lo. Com o regra geral, com o os sinais são com um ente usados para notificar eventos im portantes a processos e threads, o sistem a operacional não deve descartar sinais [Nota: A especificação POSIX determ ina que o sis­ tema operacional pode descartar um sinal se todos os threads do processo o tiverem mascarado, e a ação correspondente da rotina de tratam ento de sinais for ignorar o sinal.33] Um modo de im plem entar sinais pendentes para um modelo de thread m uitos-para-m uitos é criar um thread de núcleo para cada processo m ultithread que m onitora e entrega seus sinais assíncronos. O sistem a operacional Solaris 7 em pregava um thread denom inado A synchronous Signal Lightw eight Process (ASLWP) que m onitorava sinais e gerenciava sinais pendentes para que fossem entregues ao thread apropriado, m esm o que o thread não estivesse executando no instante da em issão do sinal.34 HWP (processo pesado) 'ura, 4.6 Mascaramento de, sinal. Capítulo 4 Conceitos threads JQJ Se um processo m ultithread em pregar uma biblioteca de nível de usuário, o sistema operacional sim plesm ente entregará todos os sinais ao processo porque não pode distinguir threads individuais. A biblioteca de nível de usuário registrará trata­ dores de sinais no sistema operacional que serão executados m ediante o recebim ento de um sinal. A biblioteca de threads de usuário do processo poderá, desse modo, entregar o sinal a qualquer um de seus threads que não o mascaram.35*36 R ev u ã a 1. Por que a entrega de um sinal síncrono é mais simples do que a entrega de um sinal assíncrono? 2. Explique como o ASLWP resolve o problema do tratamento de sinais em um modelo de thread muitos-para-muitos. R e ip o itã i: i ) D iferentem ente de um sinal assíncrono, um sinal síncrono é gerado devido a um processo ou thread que está executando correntem ente em um processador. O sistem a operacional pode identificar facilm ente o receptor do sinal determ inando qual processo ou thread está correntem ente executando no processador que gerou a interrupção correspon­ dente ao sinal. 2) U m sistem a operacional pode criar um thread que arm azena cada sinal assíncrono até que seu receptor entre no estado em execução (nesse instante o sinal é entregue). 4 .7 .2 T é r m in o d & th r e a M Quando um thread termina, concluindo a execução norm alm ente (por exemplo, por um a cham ada de saída a uma biblio­ teca de suporte a threads ou por sair do método que contém o código do thread), o sistem a operacional pode remover o thread do sistem a im ediatam ente. Threads tam bém podem term inar prem aturam ente devido a um a exceção (um a referência ilegal à m em ória) ou a um sinal de cancelam ento de um processo ou thread. Pelo fato de os threads cooperarem por meios com o modificação de dados com partilhados, um a aplicação pode produzir resultados errados im perceptíveis quando um de seus threads term inar inesperadam ente. Consequentem ente, bibliotecas de suporte a threads devem determ inar cuidadosam ente com o e quando rem over o thread do sistema. Um thread pode optar por desabilitar o cancelam ento mascarando o sinal de cancelam ento. N orm alm ente ele som ente fará isso enquanto estiver realizando um a tarefa que não deva ser interrom pida antes do término, com o concluir um a modificação em um a variável com partilhada.37 R m ão' 1. Cite três m odos pelos quais um thread pode terminar. 2. Por que se deve perm itir que um thread desabilite seu sinal de cancelam ento? R e lp o ità í: 1) Um thread pode term inar concluindo a execução, provocando um a exceção fatal ou recebendo um sinal de cancelam ento. 2) U m thread que modifica um valor no espaço de endereçam ento com partilhado de seu processo pode deixar dados em um estado inconsistente se term inar prem aturam ente. 4.8 POSIX &Pthreads POSIX (Portable O perating System s Interface for Com puting Environments) é um conjunto de padrões para interfaces de sistem as operacionais publicado pelo Portable A pplication Standards Com m ittee (PASC) do IEEE baseados, em grande parte, no UNIX System V.38 A especificação POSIX define um a interface-padrão entre threads e sua biblioteca de suporte a threads (veja no site deste livro: “Curiosidades, Padrões e conform idade: com patibilidade plugue-a-plugue”. Threads que usam a A PI de thread POSIX são denom inados Pthreads (às vezes tam bém denom inados threads POSIX ou threads POSIX 1003.1c).39 A especificação POSIX não se preocupa com os detalhes da im plem entação da interface de suporte a threads — Pthreads podem ser im plem entados no núcleo ou por bibliotecas de nível de usuário. POSIX determ ina que os registradores do processador, a pilha e a m áscara de sinal sejam m antidos individualm ente para cada thread, e que qualquer outro recurso deva ser acessível globalm ente a todos os threads no processo.40 Também define um modelo de sinal que aborda muitas das preocupações discutidas na Seção 4.7, “Considerações sobre im plem entação de threads. D e acordo com o POSIX, quando um thread gerar um sinal síncrono devido a um a exceção, tal com o uma operação ilegal de m emória, o sinal será entregue som ente àquele thread. Se o sinal não for específico para um thread, tal com o um sinal para m atar um processo, a biblioteca de suporte a threads entregará o sinal a um thread que não o mascare. Se houver m últiplos threads que não m ascaram o sinal de matar, ele será entregue a um desses threads. M ais importante, não se pode usar o sinal de m atar para term inar determ inado thread - quando um thread age obedecendo a um sinal de matar, o processo inteiro, incluindo todos os seus threads, term inarão. Esse exemplo dem onstra um a outra propriedade im portante do modelo de sinal POSIX: em bora as m áscaras de sinais sejam arm azenadas individualm ente em cada thread, as rotinas de tratam ento de sinais são globais para todos os threads de um processo.41*42 102 Sistemas ojteraciofuus Para term inar um thread particular, o POSIX fornece um a operação de cancelam ento que especifica um thread visado e cujo resultado depende do m odo de cancelam ento desse thread. Se o thread visado preferir cancelamento assíncrono, ele poderá ser terminado a qualquer m om ento durante sua execução. Se o thread adiar o cancelamento, ele não será cancelado até verificar, explicitam ente, se há um a requisição de cancelam ento. O cancelam ento adiado perm ite que um thread conclua um a série de operações antes de ser abruptam ente term inado. Um thread tam bém pode desabilitar o cancelamento, o que significa que ele não é notificado sobre um a operação de cancelam ento ter sido requisitada.43 Além das operações com uns discutidas na Seção 4.5, “Operações de thread”, a especificação POSIX fornece funções que suportam operações mais avançadas. Ela permite que programas especifiquem vários níveis de paralelismo e im plem en­ tem um a variedade de políticas de escalonam ento, entre elas algoritm os definidos por usuário e escalonam ento em tempo real. A especificação tam bém aborda sincronização usando travas, semáforos e variáveis de condição (veja o Capítulo 5, “Execução assíncrona concorrente”).44,45,46 Hoje, poucos dos sistem as operacionais m ais populares fornecem im plem entações Pthread nativas com pletas, ou seja, no núcleo. Todavia, as bibliotecas de suporte a threads do POSIX existem para fornecer um a am pla faixa de suporte para vários sistem as operacionais. Por exemplo, em bora o Linux não esteja em conform idade com o padrão POSIX por defi­ nição, o projeto Native POSIX Thread Library (NPTL) visa a fornecer um a biblioteca de suporte a threads conform e o padrão POSIX que em prega threads de núcleo no Linux.47 Similarmente, a interface para a linha de sistem as operacionais M icrosoft W indows (API Win 32) não segue o padrão POSIX, mas os usuários podem instalar um subsistem a POSIX. [Nota: O sistem a operacional Solaris 9 da Sun M icrosystem s fornece duas bibliotecas de suporte a threads: um a biblioteca de Pthreads em conform idade com o padrão POSIX e um a biblioteca de threads herdada do Solaris (denom inada threads de interface do usuário (UI). Há pouca diferença entre Pthreads e threads Solaris — esse últim o foi projetado para que cham adas a funções de thread Pthreads e Solaris vindas de dentro da m esm a aplicação fossem válidas.48 RevU cuy 1. Qual a razão prim ária para criar interfaces de thread padronizadas, com o Pthreads? 2. Q uais m odelos de funcionam ento de threads o padrão POSIX exige? R eipO ifai l 1) Interfaces de thread padronizadas permitem a portabilidade de aplicações, o que reduz o tempo de desen­ volvimento de software para aplicações que devem operar sobre várias plataformas. 2) O padrão POSIX não requer uma im ­ plementação específica. Portanto, os threads podem ser implementados com o threads de usuário, de núcleo ou híbridos. 4.9 Tkreads Lutux, O suporte para threads no sistem a operacional Linux foi introduzido com o threads de usuário na versão 1.0.9 e com o threads de núcleo na versão 1.3.56.49 Em bora o Linux suporte threads, é im portante observar que m uitos dos seus subsistemas de núcleo não distinguem entre threads e processos. De fato, o Linux aloca o m esm o tipo de descritor de processo a processos e threads, am bos denom inados tarefas. O Linux usa a cham ada ao sistem a baseada no UNIX, denom inada fork, para criar tarefas-filha. O Linux responde à cham ada ao sistem a fork criando um a tarefa que contém um a cópia de todos os recursos de seu pai (por exemplo, espaço de endereçam ento, conteúdos de registradores, pilha). Para habilitar o funcionam ento de threads, o Linux fornece um a versão modificada da cham ada ao sistem a fo rk deno­ m inada clone. Sim ilarm ente à fo rk , clone cria um a cópia da tarefa que está cham ando — na hierarquia do processo a cópia se tom a um a filha da tarefa que em itiu a cham ada ao sistem a clone. Diferentem ente de fo rk , clone aceita argum entos que especificam quais recursos com partilhar com o processo-filho. No nível m ais alto de com partilham ento de recursos, as tarefas criadas por clone correspondem aos threads discutidos na Seção 4.2 “Definição de thread” . A partir da versão 2.6 do núcleo, o Linux fornece um m apeam ento de thread um -para-um que suporta um núm ero arbitrário de threads no sistema. Todas as tarefas são gerenciadas pelo m esm o escalonador, o que significa que processos e threads de igual prioridade recebem o m esm o nível de serviço. O escalonador foi projetado para escalar bem até um grande núm ero de processos e threads. A com binação de um m apeam ento um -para-um com um algoritm o de escalona­ m ento eficiente oferece ao Linux um a im plem entação de thread de alta escalabilidade (veja o quadro “Reflexões sobre sistem as operacionais, Escalabilidade”). Em bora não suporte threads POSIX por definição, o Linux é distribuído com um a biblioteca de suporte a threads POSIX. No núcleo 2.4 uma biblioteca de suporte a threads, denom inada LinuxThreads, fornecia funcionalidade POSIX, mas não estava totalm ente em conform idade com a especificação POSIX. Um projeto mais recente, Native POSIX Thread Library (NPTL), atingiu um a conform idade quase com pleta com o POSIX e provavelmente se tom ará a biblioteca de suporte a threads padrão para o núcleo 2.6.50 Cada tarefa da tabela de processo armazena informações sobre seu estado corrente (por exemplo, em execução, parada, morta). U m a tarefa que está no estado de execução pode ser despachada para um processador (Figura 4.7). U m a tarefa entra no estado adormecido quanto está dormindo, bloqueada ou não pode executar em um processador por qualquer outra razão. Capítulo 4 Conceitos de, threads JQ3 criaçao Nova época Figura, 4 .7 1Diagrama,de, trarsição de, estado de, tarefa, do Louve. Ela entra no estado parado quando recebe um sinal de parada (isto é, de suspensão). O estado zum bi indica que um a tarefa foi terminada, mas ainda não foi rem ovida do sistema. Por exemplo, se uma tarefa contiver diversos threads, ela entrará em estado zum bi enquanto notifica seus threads que recebeu um sinal de término. U m a tarefa no estado morto pode ser removida do sistema. Esses estados são discutidos mais detalhadamente na Seção 20.5.1, “Organização de processos e threads” . R e rfiã o ' 1. Explique a diferença entre as cham adas ao sistem a fork e clone no Linux. 2. Qual a diferença entre o estado zum bi e o estado m o rta l EsadabiliílaÁes As necessidades de capacida­ de de com putação dos usuários tendem a aumentar com o tempo. Sistemas operacionais precisam ser escaláveis, ou seja, devem poder se ajustar dinamicamente à medida que mais capacidades de software e hardware são adicionadas a um sistema. Um sistema operacional m ultiprocessador, por exem plo, deve escalar suavemente do ge­ renciamento de uma configuração de dois processadores para o ge­ renciamento de uma configuração de quatro processadores. Veremos que, hoje, a maioria dos sistemas emprega uma arquitetura de dri­ vers de dispositivos que facilita a adição de novos tipos de disposi­ tivos, mesmo os que não existiam quando o sistema operacional foi implementado. Por todo este livro discutirem os técnicas para tornar sistemas operacionais escaláveis. Concluiremos com discussões de escalabilidade no Linux e no W in­ dows XP. 104 Sistemas operacionais R e ip o ifa i: 1) Quando um a tarefa em ite um a cham ada ao sistem a fo rk , ela gera um a tarefa-filha e aloca um a cópia dos recursos de seu pai a ela. Quando um a tarefa em ite um a cham ada ao sistem a clone, ela especifica os recursos que com ­ partilha com a tarefa que gera. Tarefas criadas com a cham ada ao sistem a clone são análogas a threads. 2 ) U m a tarefa no estado zum bi não é rem ovida do sistem a e, por isso, outros threads podem ser notificados de seu térm ino. U m a tarefa no estado m orta pode ser im ediatam ente rem ovida do sistem a. 4.10 Threads do Windows XP No W indows X P um processo consiste em um código de programa, um contexto de execução, recursos (por exemplo, arquivos abertos) e um ou m ais threads associados. O contexto de execução contém itens com o o espaço virtual de endereçam ento do processo e vários atributos (por exem plo, atributos de segurança). Threads são, na verdade, a unidade de execução; executam um a parte do código de um processo no contexto do processo, usando recursos do processo. Além do contexto do seu processo, um thread contém seu próprio contexto de execução que inclui sua pilha de tem po de execução, o estado dos registradores da m áquina e diversos atributos (por exemplo, prioridade de escalonam ento).51 Quando o sistema inicializa um processo, ele cria um thread primário que age com o qualquer outro thread, exceto que, se o thread prim ário retom ar, o processo termina, a m enos que o thread prim ário determ ine explicitam ente que o processo não deva terminar. Um thread pode criar outros threads pertencentes a seu processo.52 Todos os threads pertencentes ao m esm o processo com partilham o espaço de endereçam ento virtual daquele processo. Threads podem m anter seus próprios dados privados em armazenamento local de threads (Thread Local Storage — TLS). Libra* Threads podem criar fibras; elas são sem elhantes a threads, exceto que é escalonada para execução pelo thread que a cria, e não pelo escalonador. Fibras facilitam aos desenvolvedores portar aplicações que empregam threads de usuário. U m a fibra executa no contexto do thread que a cria.53 A fibra deve m anter inform ação de estado, com o a próxim a instrução a executar nos registradores do processador. O thread arm azena essa inform ação de estado para cada fibra. O próprio thread tam bém é um a unidade de execução e, por isso, deve converter-se a si m esm o em um a fibra para separar sua própria inform ação de estado de outras fibras que execu­ tam em seu contexto. De fato, a API do W indows força um thread a se converter em um a fibra antes de criar ou escalonar outras fibras. O contexto da fibra perm anece, e todas as fibras associadas àquele thread executam naquele contexto.54 Sem pre que o núcleo escalonar um thread que foi convertido a um a fibra para execução, a fibra convertida ou uma outra fibra pertencente àquele thread executará. U m a vez obtido o processador, a fibra executa até que o thread em cujo contexto está executando sofra preem pção, ou até passar a execução para um a outra fibra dentro daquele thread. Do m esm o m odo que threads possuem seu próprio arm azenam ento local de threads (TLS), fibras possuem seu armaze­ namento local de fibras (Fiber L ocal Storage — FLS) que funciona para elas exatam ente com o o TLS funciona para um thread. U m a fibra tam bém pode acessar os TLSs de seus threads. Se um a fibra se destruir (term inar), seu thread tam bém term inará.55 Reservatório detkreaÁs O W indows X P tam bém fornece um reservatório de thread (thread poot) para cada processo. Esse reservatório con­ siste em vários threads operários, ou seja, threads de modo núcleo que executam funções especificadas pelos threads de usuários. Com o o número de funções especificadas por threads de usuários pode exceder o núm ero de threads operários, o W indows X P m antém as requisições para executar funções em um a fila. O reservatório de threads consiste em threads operários que dorm em até que uma requisição entre na fila do reservatório.56 O thread que colocar um a requisição em fila deve especificar a função a executar e fornecer inform ação de contexto.57 O reservatório de threads é criado na prim eira vez que um thread apresentar um a função ao reservatório. O reservatório de threads tem muitas finalidades. Servidores Web e bancos de dados podem usá-lo para m anipular requisições de clientes (por exemplo, navegadores Web). Em vez de incorrer na sobrecarga dispendiosa de criar e destruir um thread para cada requisição, o processo sim plesm ente enfileira a requisição no seu reservatório de threads operários. E mais, diversos threads que passam a m aior parte do seu tem po dorm indo (esperando que ocorram eventos) podem ser substituídos por um único thread operário que acorda toda vez que um desses eventos ocorrer. Além disso, aplicações podem usar o reservatório de threads para executar E/S assíncrona enfileirando um a requisição no seu reservatório de threads operários para executar as rotinas de conclusão da E/S. Usar reservatório de threads pode tom ar uma aplicação mais eficiente e simples, porque os desenvolvedores não têm de criar e destruir um núm ero tão grande de threads. Contudo, os reservatórios de threads transferem um certo controle do program ador para o sistema, o que pode introduzir ineficiência. Por exemplo, o sistem a aum enta e reduz o tam anho do reservatório de threads de um processo em resposta a um volume de requisições; em alguns casos, o program ador pode estim ar m elhor quantos threads são necessários.58 Capítulo 4 Conceitos de, threads JQ $ Estudos de, threads N o W indows XP, threads podem estar em qualquer um de oito estados (Figura 4.8). U m thread com eça no estado inicializado durante a criação do thread. U m a vez concluída a inicialização, o thread entra no estado pronto. Threads no estado pronto estão esperando para usar um processador. U m thread que o despachante decidiu que executará em seguida entra no estado de reserva enquanto espera sua vez para obter um processador. U m thread está no estado de reserva, por exemplo, durante o chaveamento de contexto de um thread que estava executando anteriorm ente para aquele thread. Uma vez obtido o processador, o thread entra no estado de execução. Um thread sai do estado de execução se concluir a execução, exaurir seu quantum , sofrer preem pção, for suspenso ou esperar um objeto. Q uando um thread conclui suas instruções, ele entra no estado terminado. O sistem a não precisa necessariam ente elim inar um thread term inado im ediatam ente, o que pode reduzir a sobrecarga de criação do thread se o processo reinicializá-lo. O sistem a elim ina um thread após a liberação de seus recursos. Se um thread em execução sofrer preem pção ou exaurir seu quantum , voltará ao estado de pronto. Um thread em execução entra no estado de espera enquanto estiver no aguardo por um evento (por exemplo, um even­ to de conclusão de E/S). E um outro thread (com suficientes direitos de acesso), ou o sistema, tam bém 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, retom ará ao estado de pronto ou entrará em estado de transição. O sistem a colocará um thread em estado de transição se seus dados não estiverem disponíveis correntem ente (por exemplo, porque o thread não executou recentem ente e o sistema necessitou de sua m em ória para outras finalidades) mas, fora isso, o thread está pronto para executar. O thread entrará em estado pronto assim que o sistem a devolver a pilha do núcleo do thread à memória. O sistem a coloca um thread no estado desconhecido quando o estado do thread não estiver claro (usualm ente devido a um erro).59,60 R ertião1. Qual a finalidade das fibras no W indows XP? 2. Qual a diferença entre o thread prim ário e os outros threads? R e ifjo itã i: d Fibras existem para m elhorar a com patibilidade com aplicações que escalonam seus próprios threads (por exemplo, threads de usuário). 2) D iferentem ente de outros threads, quando um thread prim ário retom a, o processo ao qual pertence termina. 'itra , 4. 8 | Diagrama, de, transição de, estado de, thread do Windows XP. 106 S titw u u operaciôKAà 4.11 Estudo de, caso do Java, M ultithread, Parte I: introdução cuthreadsJava, Com o veremos em capítulos subseqüentes, a concorrência introduzida por processos e threads causou um impacto significativo no projeto de software. N este estudo de caso e em outros seguintes, darem os exemplos de program as reais que dem onstram e resolvem problem as introduzidos pela concorrência. O ptam os por im plem entar esses program as em Java devido à sua portabilidade através das plataform as mais populares. Este estudo de caso presum e um conhecim ento básico de Java. N esta seção revisam os vários m étodos relativos a threads na API Java. Usam os m uitos desses m étodos em exemplos de códigos vivos. O leitor deve consultar diretam ente a API Java para m ais detalhes na utilização de cada m étodo, espe­ cialm ente as exceções apresentadas por cada um deles (consulte java.sun.com/j2se/l.4/docs/api/java/IangAtiread.html). A Classe Thread (package.java.lang) tem diversos construtores. O construtor public Threadf String threadName) constrói um objeto Thread cujo nom e é threadName. O construtor public Threadf ) constrói um Thread cujo nome é "Thread-" concatenado com um número, com o Thread-1, Thread-2 e assim por diante. O código que ‘faz o trabalho real’ de um thread é colocado em seu método run. O m étodo run pode ser deixado de lado em um a subclasse de Thread ou im plem entado em um objeto Runnable; Runnable é um a interface Java que perm ite que o pro­ gram ador controle o ciclo de vida de um thread com o método run em um objeto de um a classe que não estenda Thread. Um program a lança a execução de um thread cham ando o método sfarf do thread, o qual, por sua vez, cham a o método run. Depois de start ter lançado o thread, o método retom a im ediatam ente para quem o chamou. Desse modo, aquele que o cham ou executa concorrentem ente com o thread lançado. O método static sleep é cham ado com um argum ento que especifica quanto tem po (em m ilissegundos) o thread que está executando correntemente deve dormir; enquanto um thread dorme, ele não disputa um processador, portanto outros threads podem executar, o que dá aos threads de prioridade m ais baixa um a chance de executar. O método setName determ ina o nome de um thread, o que facilita a depuração perm itindo que o program ador identifique qual thread está executando. O método getName devolve o nom e do Thread. O método toString devolve um a String consistindo no nome do thread, na prioridade do thread e no ThreadGroup desse (análogo ao processo-pai de um grupo de threads). O método static current Thread retom a uma referência ao Thread que está em execução correntemente. O método join espera que o Thread para o qual a m ensagem é enviada term ine antes que o Thread cham ador possa prosse­ guir; nenhum argum ento ou um argum ento de 0 m ilissegundo para um método join indica que o Thread corrente esperará etem am ente que o Thread visado morra, antes que o Thread prossiga. Tal espera pode ser perigosa; pode levar a dois proble­ mas particularm ente sérios denom inados deadlock e adiamento indefinido — discutirem os esses conceitos no Capítulo 7, “Deadlock e adiamento indefinido” . O Java im plem enta sinalização de thread usando o método interrupt. C ham ar o m étodo interrupt em um thread que está bloqueado (porque o método wait, join ou sleep foi cham ado) ativa (lança) seu tratador de exceções InterruptedException. O m é­ todo static interrupt retom a true se o thread corrente tiver sido interrom pido; caso contrário, retorna false. U m program a pode invocar o método islnterrupted específico de um thread para determ inar se esse foi interrompido. Criação e, execução de, tkreaM A Figura 4.9 dem onstra técnicas básicas de funcionam ento de threads, com o construir objetos Thread e usar o método Thread sleep. O program a cria três threads de execução. Cada um deles exibe um a mensagem indicando que está indo dorm ir durante um intervalo aleatório de 0 a 5000 milissegundos e, depois, vai dormir. Quando cada thread acorda, exibe seu nome, indica que parou de dormir, term ina e entra no estado morto. Você verá que o método main (o principal thread de execução) term ina antes que a aplicação se encerre. O program a consiste em duas classes — ThreadTester (linhas 4-23), que cria os três threads, e PrintThread (linhas 25-59), que contém em seu método run as ações que cada PrintThread executará. A Classe PrintThread (linhas 25-59) estende Thread, de modo que cada objeto PrintThread possa executar concorrentem ente. A classe consiste em um a variável de instância sleepTime (linha 27), um construtor (linhas 29-36) e um método run (linhas 38-57). A variável sleepTime arm azena um valor inteiro aleatório escolhido quando um novo construtor de objeto PrintThread é chamado. Cada thread controlado por um objeto PrintThread dorme pelo tempo especificado pelo sleepTime do objeto PrintThread correspondente e, então, apresenta seu nome. O construtor PrintThread (linhas 2 9 -3 6 ) inicializa sleepTime para um núm ero inteiro aleatório de 0 a 5 0 00 . Quando um Print­ Thread é designado a um processador pela prim eira vez, seu método run com eça a executar. As Linhas 4 3 -4 4 exibem um a m ensagem indicando o nome do thread que está em execução e determ inando que o thread durm a por um certo número Capítulo 4 1 // Fig. 4.9: ThreadTester.java 2 // Múltiplos threads imprimindo em intervalos diferentes. 3 4 public class ThreadTester { 5 6 public static void main( String [) args ) 7 { 8 // criar e dar nome a cada thread 9 PrintThread threadl = new PrintThread( "th re a d l" ) 10 PrintThread thread2 = new PrintThread( "th re a d 2 ") 11 PrintThread thread3 = new PrintThread( "th re a d 3 ") 12 13 System.err.println( "Ativando threads" ); 14 15 threadl .startO; // ative th re a d l; coloque-o no estado pronto 16 thread2.start(); // ative thread2; coloque-o no estado pronto 17 thread3.start(); // ative thread3; coloqu-o no estado pronto 18 19 System.err.printlní "Threads ativados, main termina\n" ); 20 21 } / / termine main 22 23 } // temine classe ThreadTester 24 25 // classe PrintThread controla execução do thread 26 classe PrintThread estende Thread { 27 private int sleepTlme; 28 29 // designe nome ao thread chamando construtor superclasse 30 public PrintThread( String name ) 31 { 32 super( n a m e ); 33 34 // escolha tem po de sono aleatório entre 0 e 5 segundos 35 sleepTime = ( in t ) ( M ath.random () * 5001 ); 36 } // termine construtor PrintThread 37 38 // método run é o código a ser executado pelo novo thread 39 public void ru n () 40 { 41 // ponha thread para dormir por período de tem po sleepTlme 42 try { 43 44 System.err.printlní getNameO + "vai dormir por" + sleepTime + " m ilissegundos"); 45 46 Thread.sleepí sleepTime); u ra , 4.9 | ThreadsJoà/ o, sendo criados, ativados, dorm indo e, im prim indo ( Parte, 1 d& 2). Conceitos d&threads 10 7 108 47 Sistemas ojteraxioftaòs } // termine try 48 49 // se thread interrompido durante o sono, imprima cópia da pilha ( stack trace ) 50 catch ( InterruptedException exception ) { 51 52 exception.printStackTraceO; } // termine catch 53 54 // imprima nome do thread 55 System.err.println( getNameO + "term inou de d o rm ir"); 56 57 } // termine método run 58 59 } // termine classe PrintThread Amostra, de, resultado 1: Ativando threads Threads ativados, main termina threadl vai dormir por 1217 milissegundos thread2 vai dormir por 3989 milissegundos thread3 vai dormir por 662 milissegundos thread3 terminou de dormir threadl terminou de dormir thread2 terminou de dormir Amostra/die,resultado 2 : Ativando threads threadl vai dormir por 314 milissegundos thread2 vai dormir por 1990 milissegundos Threads ativados, main termina thread3 vai dormir por 3016 milissegundos threadl terminou de dormir thread2 terminou de dormir thread3 terminou de dormir F üjura, 4.9 | TkreadsJava, sendo criados, ativados, dorm indo e, im prim indo (Parte, 2 de, 2). de milissegundos. A Linha 43 usa o método geíName do thread que está em execução para obter o nom e do thread que foi especificado, com o um argumento de tipo cadeia de caracteres, para o construtor PrintThread e passado para o construtor superclasse Thread na linha 32. Note que a linha 43 usa System.err para im prim ir a m ensagem porque o System.err não tem buffer, o que significa que ele im prim e seu argum ento im ediatam ente depois de ser chamado. A Linha 46 invoca o método Thread estático sleep para colocar o thread no estado adormecido. Nesse ponto, o thread perde o processador, e o sistem a perm ite que outro thread execute. Q uando o thread acorda, entra novamente no estado pronto no qual espera até que o sistema lhe designe um processador. Q uando o objeto PrintThread entra novamente no estado em execução, a linha 55 apresenta o nome do thread em um a m ensagem que indica que o thread term inou de dorm ir; então o método run termina, o que coloca o thread no estado m orto, ponto em que seus recursos podem ser liberados. Capítulo 4 Conceitos dbtkrecuU JQÇ O método ThreadTester main (linhas 6-21) cria e dá nome a três objetos PrintThread (linhas 9-11). Ao depurar um programa multithread, esses nomes identificam quais threads estão em execução. As linhas 15-17 invocam o método start de cada thread para fazer a transição de todos os três objetos PrintThread do estado nascido para o estado pronto. O m étodo start re­ tom a im ediatam ente de cada invocação; desse m odo a linha 19 apresenta um a m ensagem indicando que os threads foram ativados. N ote que todo o código desse programa, exceto o do método run, executa no thread main. O construtor PrintThread tam bém executa no thread main, pois cada objeto PrintThread é criado no método main. Q uando o método main term ina (linha 21), o program a em si continua executando, porque ainda há threads vivos (threads que foram ativados e ainda não che­ garam ao estado morto) e que não são daemon. O program a term ina quando seu últim o thread morre. Q uando o sistem a designa um processador para um PrintThread pela prim eira vez, o thread entra no estado em execução e o método run do thread com eça a executar. As am ostras de resultados desse program a m ostram o nome de cada thread e o tem po de sono quando vai dormir. O thread que tem o m enor tem po de sono norm alm ente acorda prim eiro, indica que acabou de dorm ir e termina. N ote que, na segunda am ostra de resultado, o thread 1 e o thread2 apresentam , cada um, seu nom e e tem po de sono antes que o método main conclua sua execução. Essa situação dem onstra que, um a vez que m últiplos threads estejam no estado pronto, o pro­ cessador pode ser designado para qualquer um deles. RcvU cuy 1. Por que program adores devem dar nom es a threads Java? 2. Com o Java perm ite que program adores criem threads por meio de objetos que não estendem Thread? Relpoitãi: 1) Dar nomes a threads Java perm ite que o program ador identifique cada thread durante a depuração. 2) U m a classe pode im plem entar a interface Runnable para que objetos da classe possam controlar os ciclos de vida de threads com seus m étodos run. R e s iu tio Nos últim os anos diversas linguagens de program ação de uso geral com o Java, C#, V isual C ++ .NET, Visual Basic.NET e Python disponibilizaram primitivas de con­ corrência para o program ador de aplicações. O program ador especifica que as aplicações contêm threads de execução, cada thread designando um a parte de um program a que pode executar concorrentem ente com os outros threads. Essa tec­ nologia, denom inada m ultithreading, dá ao program ador capacidades poderosas. O suporte do sistem a operacional a threads é essencial para suportar linguagens que fornecem sem ântica de multithread. Threads, às vezes denom inados processos leves (LWP), com partilham muitos recursos — mais notavelm ente o es­ paço de endereçam ento de seus processos — para melhorar a eficiência com que realizam suas tarefas. O nom e ‘thread’ refere-se a um único thread de instruções ou thread de con­ trole; threads dentro de um processo podem executar concor­ rentem ente para atingir um a m eta com um. Recursos com o registradores de processador, a pilha e outros dados especí­ ficos de threads (Thread-Specific D ata — TSD ) são locais de cada thread, enquanto todos os threads com partilham o espaço de endereçamento de seus processos. Dependendo da im plem entação de thread, os threads podem ser gerenciados pelo sistem a operacional ou por um a aplicação de usuário. Em bora m uitos sistemas operacionais suportem threads, as im plem entações variam consideravelmente. Threads ganharam notoriedade devido a tendências no projeto de softw are, escalabilidade e cooperação. Cada thread transita entre uma série de estados distintos. Threads e processos têm muitas operações em com um, tais com o criar, sair, retomar, suspender. D iferentem ente da criação de processo, a criação de thread não requer que o sistema operacional inicialize recursos que são com partilhados entre o processo-pai e seus threads (por exemplo, o espaço de endereçam ento). Isso reduz a sobrecarga decorrente da criação e térm ino de threads em com paração com criação e térm ino de processos. Algum as operações de thread não correspondem precisamente às operações de processo, como cancelar e unir. As im plem entações de threads variam entre sistemas operacionais, mas quase todos suportam threads de usuário, threads de núcleo ou um a com binação dos dois. Os threads de usuário executam operações de suporte a threads em espaço de usuário, o que significa que os threads são cria­ dos por bibliotecas de tempo real que não podem executar instruções privilegiadas nem acessar as primitivas do núcleo diretam ente. Implem entações de thread de usuário tam bém são denom inadas m apeam entos de thread muitos-para-um , porque o sistem a operacional m apeia todos os threads de um processo m ultithread para um único contexto de execução. Em bora o desem penho dos threads de usuário variem entre aplicações, muitas de suas deficiências estão relacionadas ao fato de que, para o núcleo, um processo m ultithread é um único thread de controle. Threads de núcleo tentam resolver as lim itações dos threads de usuário m apeando cada thread para seu próprio 110 Sistemas ojteracioiuiis contexto de execução. Conseqüentemente, threads de núcleo fornecem mapeam ento de thread um-para-um. Entre seus benefícios estão m aiores escalabilidade, interatividade e rendim ento. Entretanto, devido à sobrecarga e à portabili­ dade reduzida, threads de núcleo nem sempre representam a solução ótim a para aplicações multithread. A com binação da im plem entação de threads de usuá­ rio e de núcleo é conhecida com o mapeam ento de thread m uitos-para-m uitos (m-to-m), denom inada tam bém m ape­ am ento de thread m -to-n, porque o núm ero de threads de usuário e o núm ero de threads de núcleo não precisam ser iguais. M apeam entos de threads m uitos-para-m uitos redu­ zem a sobrecarga decorrente de m apeam entos um-para-um im plem entando reservatório de threads (thread pooling), que perm ite que um a aplicação especifique o núm ero de threads de núcleo que requer. Threads persistentes de nú­ cleo que ocupam o reservatório de threads são denominados threads operários. U m a técnica que habilita um a biblioteca de suporte a threads de usuário a executar operações de es­ calonam ento é denom inada ‘ativação de escalonador’, que ocorre quando o sistem a operacional cham a um a biblioteca de suporte a threads de usuário que determ ina se quaisquer de seus threads precisam de reescalonam ento. Ativações de escalonador podem reduzir a sobrecarga de chaveamento de contexto decorrente de decisões de escalonam ento inade­ quadas no núcleo, perm itindo que a biblioteca de suporte a threads determ ine a política de escalonam ento que m elhor atenda às necessidades da aplicação. Q uando o sistem a operacional entrega um sinal a um processo, esse faz um a pausa na sua execução e invoca um a rotina de tratamento de sinal para responder. H á dois tipos de sinais: síncrono (que ocorre com o resultado direto de uma instrução executada) e assíncrono (que ocorre com o resulta­ do de um evento não relacionado com as instruções que estão em execução). A entrega de sinais introduz diversos desafios de projeto às im plem entações de operações de suporte a threads. A biblioteca de suporte a threads deve determ inar o receptor de cada sinal para que os sinais assíncronos sejam entregues adequadam ente. Cada thread usualm ente está associado a um conjunto de sinais pendentes que são entregues quando ele executa. Um modo de controlar quais threads recebem sinais de determ inado tipo é requerer que cada thread especifique uma m áscara de sinal que desabilita todos os sinais, exceto os que ele quer receber. Térm ino ou cancelam ento de threads tam bém são di­ ferentes entre im plem entações de thread. Com o m últiplos threads com partilham o mesmo espaço de endereçam ento, term inar um thread prem aturam ente pode causar erros im perceptíveis em processos. A lgum as im plem entações de thread perm item que um thread determ ine quando pode ser term inado para im pedir que o processo entre em estado inconsistente. Threads que usam a API de suporte a threads POSIX são denom inados Pthreads (às vezes tam bém cham ados de threads PO SIX ou threads PO SIX 1003.1c). PO SIX determ ina que os registradores do processador, a pilha e a m áscara de sinal sejam m antidos individualm ente para cada thread e que quaisquer outros recursos de inform ação devam estar globalm ente acessíveis a todos os threads do processo. POSIX especifica como sistemas operacionais devem entre­ gar sinais a Pthreads, além de especificar diversos modos de cancelamento de threads. O Linux aloca o m esm o tipo de descritor de processo a processos e threads, am bos denom inados tarefas. O Linux usa a cham ada ao sistem a baseada no U N IX , cham ada fork, para criar tarefas-filha. Para habilitar as operações de su­ porte a threads, o Linux fornece um a versão denom inada clone que aceita argumentos que especificam quais recursos com partilhar com a tarefa-filha. N o nível m ais alto de com partilham ento de recursos, as tarefas criadas por clone correspondem aos threads discutidos na Seção 4.2 “Defi­ nição de thread”. No W indows XP, threads — e não processos — são des­ pachados para um processador; threads executam um a parte do código de um processo no contexto do processo usando recursos do processo. Além do contexto do seu processo, um thread contém seu próprio contexto de execução que inclui sua pilha de tempo de execução, o estado dos registradores da m áquina e diversos atributos (por exemplo, prioridade de escalonam ento). Q uando o sistem a inicializa um processo, ele cria um thread prim ário que, tipicam ente, term ina o processo assim que é concluído. Threads do W indows XP podem criar fibras, sem elhantes a threads, exceto que uma fibra é escalonada para execução pelo thread que a cria, e não pelo escalonador. O W indows XP tam bém fornece um reservatório de threads para cada processo, que consiste em vários threads operários, ou seja, threads de núcleo que exe­ cutam funções especificadas pelos threads de usuário. A linguagem de program ação Java perm ite que o pro­ gram ador da aplicação crie threads portáveis para muitas plataform as de com putação. A Java usa classe Thread para criar threads, os quais executam código especificado em um método run de um objeto Runnable. Java suporta operações com o nom eação, ativação e união de threads. Exercícios 4.1 Quais as semelhanças e diferenças entre o despacho de threads em threads de núcleo e em threads de usuário? 4.2 Um algoritmo que execute diversos cálculos independentes concorrentemente (por exemplo, multiplicação de matrizes) seria mais eficiente se usasse threads ou se não os utilizasse? Por que essa é uma pergunta difícil de responder? 4 3 Cite duas situações, que não um servidor Web ou de banco de dados, nas quais o reservatório de threads podería ser útil. Uma outra possibilidade é um jogo interativo on-line com múltiplos jogadores. Vários desses jogos podem ter centenas de jogadores ativos simul­ taneamente e cada um pode ser representado por um thread. Nesses ambientes os usuários entram e saem do jogo frequentemente, o que 110 Sistemas ojteracioiuiis contexto de execução. Conseqüentemente, threads de núcleo fornecem mapeam ento de thread um-para-um. Entre seus benefícios estão m aiores escalabilidade, interatividade e rendim ento. Entretanto, devido à sobrecarga e à portabili­ dade reduzida, threads de núcleo nem sempre representam a solução ótim a para aplicações multithread. A com binação da im plem entação de threads de usuá­ rio e de núcleo é conhecida com o mapeam ento de thread m uitos-para-m uitos (m-to-m), denom inada tam bém m ape­ am ento de thread m -to-n, porque o núm ero de threads de usuário e o núm ero de threads de núcleo não precisam ser iguais. M apeam entos de threads m uitos-para-m uitos redu­ zem a sobrecarga decorrente de m apeam entos um-para-um im plem entando reservatório de threads (thread pooling), que perm ite que um a aplicação especifique o núm ero de threads de núcleo que requer. Threads persistentes de nú­ cleo que ocupam o reservatório de threads são denominados threads operários. U m a técnica que habilita um a biblioteca de suporte a threads de usuário a executar operações de es­ calonam ento é denom inada ‘ativação de escalonador’, que ocorre quando o sistem a operacional cham a um a biblioteca de suporte a threads de usuário que determ ina se quaisquer de seus threads precisam de reescalonam ento. Ativações de escalonador podem reduzir a sobrecarga de chaveamento de contexto decorrente de decisões de escalonam ento inade­ quadas no núcleo, perm itindo que a biblioteca de suporte a threads determ ine a política de escalonam ento que m elhor atenda às necessidades da aplicação. Q uando o sistem a operacional entrega um sinal a um processo, esse faz um a pausa na sua execução e invoca um a rotina de tratamento de sinal para responder. H á dois tipos de sinais: síncrono (que ocorre com o resultado direto de uma instrução executada) e assíncrono (que ocorre com o resulta­ do de um evento não relacionado com as instruções que estão em execução). A entrega de sinais introduz diversos desafios de projeto às im plem entações de operações de suporte a threads. A biblioteca de suporte a threads deve determ inar o receptor de cada sinal para que os sinais assíncronos sejam entregues adequadam ente. Cada thread usualm ente está associado a um conjunto de sinais pendentes que são entregues quando ele executa. Um modo de controlar quais threads recebem sinais de determ inado tipo é requerer que cada thread especifique uma m áscara de sinal que desabilita todos os sinais, exceto os que ele quer receber. Térm ino ou cancelam ento de threads tam bém são di­ ferentes entre im plem entações de thread. Com o m últiplos threads com partilham o mesmo espaço de endereçam ento, term inar um thread prem aturam ente pode causar erros im perceptíveis em processos. A lgum as im plem entações de thread perm item que um thread determ ine quando pode ser term inado para im pedir que o processo entre em estado inconsistente. Threads que usam a API de suporte a threads POSIX são denom inados Pthreads (às vezes tam bém cham ados de threads PO SIX ou threads PO SIX 1003.1c). PO SIX determ ina que os registradores do processador, a pilha e a m áscara de sinal sejam m antidos individualm ente para cada thread e que quaisquer outros recursos de inform ação devam estar globalm ente acessíveis a todos os threads do processo. POSIX especifica como sistemas operacionais devem entre­ gar sinais a Pthreads, além de especificar diversos modos de cancelamento de threads. O Linux aloca o m esm o tipo de descritor de processo a processos e threads, am bos denom inados tarefas. O Linux usa a cham ada ao sistem a baseada no U N IX , cham ada fork, para criar tarefas-filha. Para habilitar as operações de su­ porte a threads, o Linux fornece um a versão denom inada clone que aceita argumentos que especificam quais recursos com partilhar com a tarefa-filha. N o nível m ais alto de com partilham ento de recursos, as tarefas criadas por clone correspondem aos threads discutidos na Seção 4.2 “Defi­ nição de thread”. No W indows XP, threads — e não processos — são des­ pachados para um processador; threads executam um a parte do código de um processo no contexto do processo usando recursos do processo. Além do contexto do seu processo, um thread contém seu próprio contexto de execução que inclui sua pilha de tempo de execução, o estado dos registradores da m áquina e diversos atributos (por exemplo, prioridade de escalonam ento). Q uando o sistem a inicializa um processo, ele cria um thread prim ário que, tipicam ente, term ina o processo assim que é concluído. Threads do W indows XP podem criar fibras, sem elhantes a threads, exceto que uma fibra é escalonada para execução pelo thread que a cria, e não pelo escalonador. O W indows XP tam bém fornece um reservatório de threads para cada processo, que consiste em vários threads operários, ou seja, threads de núcleo que exe­ cutam funções especificadas pelos threads de usuário. A linguagem de program ação Java perm ite que o pro­ gram ador da aplicação crie threads portáveis para muitas plataform as de com putação. A Java usa classe Thread para criar threads, os quais executam código especificado em um método run de um objeto Runnable. Java suporta operações com o nom eação, ativação e união de threads. Exercícios 4.1 Quais as semelhanças e diferenças entre o despacho de threads em threads de núcleo e em threads de usuário? 4.2 Um algoritmo que execute diversos cálculos independentes concorrentemente (por exemplo, multiplicação de matrizes) seria mais eficiente se usasse threads ou se não os utilizasse? Por que essa é uma pergunta difícil de responder? 4 3 Cite duas situações, que não um servidor Web ou de banco de dados, nas quais o reservatório de threads podería ser útil. Uma outra possibilidade é um jogo interativo on-line com múltiplos jogadores. Vários desses jogos podem ter centenas de jogadores ativos simul­ taneamente e cada um pode ser representado por um thread. Nesses ambientes os usuários entram e saem do jogo frequentemente, o que Capítulo 4 significa que reservatórios de threads podem proporcionar um meio eficiente de alocar threads. Em geral, qualquer ambiente em que threads são criados e destruídos rapidamente, mas a variância do número total de threads no sistema a qualquer instante determinado é pequena, pode se beneficiar de reservatórios de threads. 4.4 Por que ativações de escalonador são menos portáveis do que threads de usuário ou threads de núcleo? 4.5 Na Seção 4.7.1, “Entrega de sinal de thread”, explicamos como sinais podem especificar seus alvos usando identificadores de threads ou identificadores de processos. Sugira uma maneira alternativa de implementar sinais para resolver o problema da entrega de sinal assíncrono. Conceitos d&tkruuü 111 4.6 A Seção 4.7.1 discute como o Solaris 7 empregou um thread denominado processo leve assíncrono (ASLWP) para monitorar e entregar sinais assíncronos pendentes. Como essa solução pode ser simplificada se o sistema operacional representar threads usando mapeamentos de thread um-para-um? 4.7 Quais as semelhanças e diferenças entre cancelamento assíncrono, protelado e desabilitado nos Pthreads? 4.8 Quais as diferenças entre as chamadas ao sistema fo rk e clone do Linux? Quais as semelhanças? 4.9 Segundo a discussão da Seção 4.10, “Threads do Windows XP”, quais mapeamentos de thread o Windows XP suporta? Projetos sugeridos 4.10 Pesquise como são implementados threads no Windows XP, no OS X e no Linux. Quais as semelhanças e diferenças entre as implementações? Quais as diferenças entre elas e os Pthreads POSIX? 4.11 Elabore um relatório de pesquisa sobre a implementação de threads Java. Quais informações a Java Virtual Machine controla para cada thread? A implementação depende da plataforma sobre a qual a JVM está executando? 4.12 Pesquise a Biblioteca de Threads compatível do Solaris. Ela­ bore um relatório de pesquisa sobre o modo como essa biblioteca funciona. Como ela trata os problemas de entrega de sinal e término de threads mencionados no texto? Ela segue o padrão POSIX? 4.13 Pesquise três tipos de sistemas que usam reservatório de threads. Qual o número médio de threads que cada um desses sistemas usa? 4.14 Pesquise como threads são gerenciados em sistemas multiprocessador e sistemas distribuídos. Notas 1. 2. 3. 4. 5. 6. 7. 8. 9. “Process and thread functions”, MSDN Library, fev. 2003, msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/ process_and_thread_functions.asp. Manuel Pavón Valderrama, “The unofficial GNU mach IPCBcginncris guide’’, 19 ago. 2002, www.nongnu.org/hurdextras/ ipc_guide/machJpc_cthreads.html. IEEE Standards Press, 1996, 9945-1:1996 (ISO/IEC) [IEEE/ANSI Std 1003.11996 Edition] Information Technology-PortableOperating System Interface (POSÍX)-Part 1: System Application:Program Interface (API) [C Language] (ANSI). Robert C. Daley e Jack B. Dcnnis, “Virtual memory, pro­ cesses, and sharing in Multics”, Proceedings o f the ACM Symposium on Operating System Principies, jan. 1967. “Multithreading in the Solaris operating environment, a technical white paper”, Sun Microsystems, 2002. B. 0 ’Sullivan, “Answers to frcqucntly askcd qucstions for comp.programming.threads: part 1 of 1”, rev. 1.10, modifi­ cado em: 3 set. 1997, www.serpentine.com/~bos/threads-faq/. “Lesson: threads: doing two or more tasks at once”, The Java Tutorial, Sun Microsystems, Inc., java.sun.com/doc/books/ tutorial/essential/threads/index.html. R. Appleton, “Understanding a context switching benchmark’’, modificado em: 23 out. 2001, cs.nmu.edu/~randy/Research/Papers/ Scheduler/understanding.html. “pthread_cancel’\ Documentation OverView, Glossary, and Master Index, © Digital Equipment Corporation 1996, All RightsReserved; Product Version: Digital UNIX Version 4.0 or highcr, March 1996, www.c.arizona.edu/computer.help/ policy/D IG ITAL_unix/AA-Q 2D PC -TKTl_htm l/thrd0115.htm l#pt_cancel_13. 10. “2.1.4 Waiting for a Thread to Terminate,” Documen­ tation OverView, Glossary, and Master Index, Product Version: Digital UNIX Version 4.0 or higher, March 1996, <www.cs.arizona.edu/computer.help/policy/DIGnAL_unix/AA-Q2DPCrKTl_ html/thrd0021.html#join_thread_sec>. 11. “Comp.os.research: frequently answered questions, the history of threads”, modificado em: 13 ago. 1996, www.faqs.org/ faqs/os-research/partl /sedion-10.html. 12. 13. T. E. Anderson, B. N. Bershad, E. D. Lazowska e H. M. Levy, “Scheduler activations: effective Kemel support for user-level management of parallelism”, ACM Transactions on Computer Systems, v. 10, nfi 1, fev. 1992, p. 54. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 06.html. 14. 15. 16. T. E. Anderson, B. N. Bershad, E. D. Lazowska e H. M. Lcvy, “Scheduler activations: effective Kemel support for user-level management of parallelism”, ACM Transactions on Computer Systems, v. 10, nfi 1, fev. 1992, p. 54. D. G. Feitelson, “Job scheduling in multiprogrammed parallel systems”, IBM Research Report R C 19790, out. 1994 e ago. 1997 (2d rev.), p. 121. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 06.html. 17. 18. D. G. Feitelson, “Job scheduling in multiprogrammed parallel systems”, IBM Research Report RC 19790, out. 1994 e ago 1997 (2d rev.), p. 121. “Packagc java.nio.channcls”, Java 2 Platform SE vl.4.2, 2003, java.sun.eom /j2se/l .4.2/docs/api/java/nio/channels/packagesummary.html#multiplex. m 19. S is te m a s o j^ e ra c io tu iti C. Benjamin, “The fibers of threads”, Compile Time (.Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 39. 06.html. 20. 21. 22. 23. D. G. Feitelson, “Job scheduling in multiprogrammed parallel Systems”, IBM Research Report R C 19790, out. 1994 e ago. 1997 (2d rev.), p. 121. D. G. Feitelson, “Job scheduling in multiprogrammed parallel Systems”, IBM Research Report RC 19790, out. 1994 e ago. 1997 (2d rev.), p. 121. T. E. Anderson, B. N. Bershad, E. D. Lazowska e H. M. Levy, “Scheduler activations: effective Kemel support for user-level management of parallelism”, ACM Transactions on Computer Systems, v. 10, nQ1, fev. 1992, p. 54. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 40. 41. 42. posixsignal-model.xml. 43. 44. 06.html. 24. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 45. 06.html. 25. 26. 27. J. Richter, “New Windows 2000 pooling functions greatly simplify thread management”, Microsoft Systems Journal, abr. 1999, www.microsoft.com/msi/0499/pooling/pooling.tKpx. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/ compile_06.html. C. Benjamin, “The fibers of threads”, Compile Time (Linux Magazine), maio 2001, www.linux-mag.com/2001-05/compile_ 29. “Multithreading in the Solaris operating environment, a technical white paper”, Sun Microsystems, 2002. “I’ve got work to do — worker threads and work queues”, NTInsider, v. 5, ns 5, out. 1998, atualizado em: 20 ago. 2002, 46. 47. 48. 49. 50. 51. “System worker threads”, MSDN Library, 6 jun. 2003, 52. msdn.microsoft.com/en-usAmarch/hhAmarch/synchro_9ylz.asp. 31. 32. 33. D. McCracken, “POSIX threads and the Linux Kemel”, Proceedings o f the Ottawa Linux Symposium 2002, p. 335. E. Troan, “A look at the signal API”, Linux Magazine, jan. 2000, www.linux-mag.com/2000-01/compile_01 .html. Ulrich Drepper, “Requirements of the POSIX signal model”, modificado em: 17 maio 2003, people.redhat.com/drepper/ 53. 54. 35. 36. “Multithreading in the Solaris operating environment, a technical white paper”, Sun Microsystems, 2002. “Multithreading in the Solaris operating environment, a technical white paper”, Sun Microsystems, 2002. Ulrich Drepper, “Requirements of the POSIX signal model”, modificado em: 17 maio 2003, people.redhat.com/drepper/ 55. 56. 38. David R. Butenhof, Programming with POSIX Threads. Boston, MA: Addison Wesley, 1997, p. 144. “POSIX thread API concepts”, IBM iSeries information Center, publib-boulder.ibm.com/iseries/v5rl/ic2924/index.htm?info/ apis/whatare.htm, modificado em: 16 out. 2002. msdn.microsoft.com/library/en-us/dllprocAase/about_processes_and_ threads.asp. “Fibers”, MSDN Library, fev. 2003, msdn.microsoft.comAbrary/enus/dlIprocAase/fibers.asp. “Convert thread to fiber”, MSDN Library, fev. 2003, “Fibers”, MSDN Library, fev. 2003, msdn.microsoft.comAbrary/enus/dlIprocAase/fibers.asp. “Thread pooling”, MSDN Library, fev. 2003, msdn.microsoft.com/ library/en-us/dllprocAase/thread_pooling.asp. 57. “Queue user worker item”, MSDN Library, fev. 2003, msdn.microsoft.com/library/en-us/dllproc/base/queueuserworkitem.asp. 58. posixsignal-model.xml. 37. “About processes and threads”, MSDN Library, fev. 2003, msdn.microsoft.com/library/en-us/dllproc/base/convertthreadtofiber.asp. posixsignal-model.xml. 34. “Threads Index”, The Open Group Base Specifications, Issue 6 , 2003, www.opengroup.org/onlinepubs/007904975/idx/threads.html. U. Drepper e I. Moinar, “The native POSIX thread library for Linux”, 30 jan. 2003, people.redhat.com/drepper/nptl-design.pdf. “Multithreaded programming guide”, Sun Microsystems, maio 2002, p. 11,175. S. Walton, “Linux threads frequently asked questions”, 21 jan. 1997, www.tldp.org/FAQ/Threads-FAQ/. U. Drepper e I. Moinar, “The native POSIX thread library for Linux”, 30 jan. 2003, people.redhat.com/drepper/nptl-design.pdf. “Processes and threads”, MSDN Library, fev. 2003, msdn.microsoft.com/library/en-us/dllprocAase/about_processes_and_ threads.asp. www.osronline.com/article.cfm?id=65. 30. David R. Butenhof, Programming with POSIX threads. Boston, MA: Addison Wesley, 1997, p. 143-144. G. E. Blelloch e G. J. Narlikar, “Pthreads for dynamic and irregular parallelism”, Conference on High Performance Networking and Computing, Proceedings o f the 1998 ACM/IEEE Conference on Supercomputing, San Jose, CA, 1998. K. Rangaraju, “Unravel the complexity of thread program­ ming”, w w w .faw cette.com /javapro/2002_02/m agazine/features/ krangaraju/. 06.html. 28. B. 0 ’Sullivan, “Answers to frequently asked questions for comp.programming.threads: part 1 of l”,rev. 1.1, modificado em: 3 set. 1997, www.serpentine.com/~bos/threads-faq/. D. McCracken, “POSIX threads and the Linux Kemel”, Proceedings o f the Ottawa Linux Symposium 2002, p. 332. David R. Butenhof, Programming with POSIX Threads. Boston, MA: Addison Wesley, 1997, p. 214-215. Ulrich Drepper, “Requirements of the POSIX signal model”, modificado em: 17 maio 2003, people.redhat.com/drepper/ 59. J. Richter, “New Windows 2000 pooling functions greatly simplify thread management”, Microsoft Systems Journal, abr. 1999, www.microsoft.com/msj/0499/pooling/pooling. aspx. “Win_32 thread”, MSDN Library, jul. 2003, msdn.mkrosoft.com/ Iibrary/en-us/wmisdk/wmi/win32_thread.asp. 60. D. Solomon e M. Russinovich, Inside Windows 2000, 3ed. Redmond: Microsoft Press, 2000, p. 348-349. Epcecnção assÍKcmta concorrente Não m e,provoque,, p o is o que, m a is sou, é, crítico. W illiam Shakespeare Q urm te m u m relógio sabe, que, horas são; q u em te m dois, nunca, te m certeza,. Provérbio Laner ocupado. Johann Elias Schlegel Uma,pessoa, rea lm en te ocupada, nunca, sabe seu,peso. Edgar Watson Howe Atrasosg e ra m perigos. John Lyly Procrastinando ele preservou, o estado. Quintus Ennius Objetivos Este capítulo apresenta: • Os desafios de sincronizar processos e threads concorrentes. • Seções críticas e a necessidade de exclusão mútua. • Como implementar primitivas de exclusão mútua em software. • Primitivas de exclusão mútua em hardware. • Utilização e implementação de semáforos. 114 S U tw u is o j m m ío h a j U 5. 1 Introdução N os dois capítulos anteriores apresentam os o conceito de unidades de execução — processos e threads. M ais uma vez, concentrarem os nossa discussão em threads, mas a m aior parte do que abordarem os aqui tam bém pode ser aplicada a processos. Se existir mais de um thread em um sistem a ao mesmo tempo, diz-se que os threads são concorrentes.1-2’3 Dois threads concorrentes podem executar independentem ente um do outro ou cooperativamente. Q uando threads operam independentem ente um do outro, mas ocasional m ente devem se com unicar e se sincronizar para executar tarefas coope­ rativas, diz-se que executam assincronamente.4 5A ssincronism o é um tópico com plexo — este capítulo e o Capítulo 6, “Program ação concorrente” , discutem a organização e o gerenciam ento de sistem as que suportam threads concorrentes assíncronos. Com eçam os com um exem plo em Java que dem onstra a dificuldade de escrever program as corretos mesmo com apenas dois threads concorrentes assíncronos. Se codificados de m odo inadequado, esses program as podem produzir resultados indesejáveis e imprevisíveis. No restante do capítulo, discutirem os vários m ecanism os que os program adores podem usar para criar program as corretos com threads concorrentes assíncronos. No capítulo seguinte apresentarem os dois problemas clássicos de assincronism o e im plem entarem os sua solução em Java. Revíião' 1. (V/F) Com unicação e sincronização são necessárias apenas para threads que executam assincronam ente. 2. (V/F) D iz-se que threads que se com unicam ocasionalm ente, m esm o que em geral operem independentem ente um do outro, executam sincronamente. R eip o ità i 1 1) Falso. Com unicação e sincronização são necessárias para executar threads e processos assincronam ente. 2) Falso. D iz-se que tais threads executam assincronam ente. 5.2 Exclusão tuútuu Considere um servidor de correio eletrônico que processa e-m ails para um a organização. Suponha que queiram os que o sistem a m onitore continuam ente o núm ero total de e-mails enviados desde o início do dia. Suponha que o recebim ento de um e-mail seja tratado por um dos vários threads concorrentes. Cada vez que um desses threads receber um e-mail de um usuário, increm entará, 1, a um a variável com partilhada no âm bito do processo, m a ilío u n t. Considere o que acontece se dois threads tentarem increm entar mailCount sim ultaneam ente. Prim eiro, suponha que cada thread execute o seguinte código em linguagem de montagem: LOAD mailCount ADD 1 STORE mailCount Suponha que a instrução LOAD copie mailCount da m em ória para um registrador, a instrução ADD adicione a constante im e­ diata 1 da m em ória para o valor no registrador, e a instrução STORE copie o valor do registrador para a memória. Considere que mailCount correntem ente seja 21687. E que o prim eiro thread execute as instruções LOAD e ADD deixando, portanto, 21688 no registrador (mas ainda sem atualizar o valor de mailCount na memória, que continua sendo 21687). Então, devido a um a expiração de quantum, o prim eiro thread perde o processador, e o contexto do sistem a é chaveado para o segundo thread. O segundo thread agora executa todas as três instruções deixando assim mailCount em 21688. Esse thread perde o processador, e o contexto do sistem a é chaveado de volta para o primeiro thread que então continua executando a instrução STORE — também colocando 21688 em mailCount. Devido ao acesso não controlado à variável com partilhada mailCount, o sistem a essencialm ente perdeu o controle de um dos e-m ails — mailCount deveria ser 21689. No caso de uma aplicação de gerenciam ento de e-mail, tal erro pode parecer insignificante, mas um erro semelhante ocorrendo em um a aplicação de m issão crítica, com o controle de tráfego aéreo, pode custar vidas. A causa desse resultado incorreto é a escrita da variável com partilhada mailCount. É claro que muitos threads concorrentes podem ler dados sim ultaneam ente sem essa dificuldade. M as quando um thread lê dados que um outro thread esteja es­ crevendo, ou quando um thread escreve dados que um outro thread tam bém esteja escrevendo, poderão ocorrer resultados indeterm inados.6*7>8 Podem os resolver esse problem a concedendo a cada thread acesso exclusivo a mailCount. Enquanto um thread incrementa a variável com partilhada, todos os outros threads que desejam fazer o m esm o terão de esperar. Quando o thread que está executando term inar de acessar a variável com partilhada, o sistem a perm itirá que um dos processos à espera prossiga. Essa operação é denom inada serialização do acesso à variável com partilhada. Dessa m aneira, threads não poderão acessar üifHtulo 5 Execução mltocrona, concorrente J fô dados com partilhados sim ultaneamente. Enquanto cada thread estiver atualizando a variável com partilhada, todos os outros serão impedidos de fazê-lo sim ultaneam ente, o que é denom inado exclusão mútua.9,10-11 Com o veremos neste capítulo e nos subseqüentes, threads em espera devem ser cuidadosam ente gerenciados para garantir que poderão prosseguir dentro de um período de tempo ‘razoável’. Ret/Uão' 1. No exemplo da m ailC ount seria aceitável que diversos threads lessem sim ultaneam ente o valor sem atualizá-lo? 2. (V/F) Suponha que cada um de dois threads que com partilham uma variável precise atualizá-la em algum m omento durante a execução do thread. Se os threads não forem obrigados a se excluir m utuam ente durante a atualização da variável com partilhada, o sistem a falhará sem pre que houver um a execução de dois threads. R eip o ítã i l 1) Sim, exclusão m útua som ente é necessária quando threads atualizam a variável com partilhada. 2) Falso. É possível que threads tentem atualizar a variável com partilhada em mom entos diferentes e, assim, o program a poderá funcionar corretamente. 5.2.1 Estudo de, caso do JaAmniuUtthreasL, Parte II: um relasioKamerto jwodLutor/consumldor emJava, Em um relacionamento produtor/consumidor, a parte da aplicação referente ao produtor gera dados e os arm azena em um objeto com partilhado, e a parte do consumidor lê dados do objeto com partilhado. Um exemplo de relacionam ento produtor/consum idor com um é o spooling de impressão. Um processador de texto passa (spools) os dados para um buffer (norm alm ente um arquivo), e os dados são subseqüentem ente consum idos pela im pressora enquanto ela im prim e o docu­ mento. Similarmente, um a aplicação que copia dados para discos com pactos coloca dados em um buffer de tam anho fixo que é esvaziado à m edida que o drive do CD-RW grava os dados no disco compacto. Considere um relacionam ento produtor/consum idor m ultithread im plem entado em Java, no qual um thread produtor gera dados e os coloca em um buffer que só pode reter um único valor, e um thread consumidor lê os dados do buffer. Se o produtor que estiver esperando para colocar os próxim os dados no buffer determ inar que o consum idor ainda não leu os dados que já estavam anteriorm ente no buffer, ele deve cham ar wait para que o consum idor tenha a chance de ler os dados não consum idos antes que outros dados sejam gravados sobre eles. Q uando o consum idor acabar de ler os dados deve cham ar notify para perm itir que o produtor (que possivelm ente estará esperando) arm azene o próxim o valor. O m é­ todo notify de Object faz a transição de um thread do estado em espera para o estado pronto. Se o consum idor encontrar o buffer vazio (porque o produtor ainda não produziu seu prim eiro dado) ou descobrir que os dados anteriores já foram lidos, deverá cham ar wait para se colocar no estado de espera, caso contrário poderá ler o ‘lixo’ de um buffer vazio ou processar erroneam ente os mesmos dados novamente. Q uando o produtor colocar os próxim os dados no buffer, deve cham ar notify para perm itir que o thread consum idor (que possivelm ente estará esperando) prossiga, para que possa ler os novos dados. Note que notify não tem efeito quando nenhum dos threads de um a aplicação estiver esperando. Vamos im plem entar esse exem plo em Java para entenderm os com o podem surgir erros de lógica se não sincronizar­ mos o acesso entre os m últiplos threads que m anipulam os dados com partilhados. O exemplo a seguir (figuras 5.1 a 5.5) im plem enta um relacionam ento produtor/consum idor no qual um thread produtor escreve núm eros seqüencialm ente ( l a 4) em um buffer com partilhado — um a localização de m em ória com partilhada entre dois threads (um a variável in t única denom inada buffer na Figura 5.4). O thread consum idor lê esse dado no buffer com partilhado e o exibe. O resultado do program a (três am ostras são exibidas na Figura 5.5) apresenta os valores que o produtor escreve (produz) no buffer com ­ partilhado e os valores que o consum idor lê (consome) no buffer compartilhado. Cada valor que o produtor escrever no buffer com partilhado deverá ser consum ido exatam ente um a vez (e na ordem) pelo thread consumidor. Contudo, os threads desse exemplo não são sincronizados, significando que não cooperam quando executam suas tarefas (o que, com o vimos, é especialm ente im portante quando um dos threads está escrevendo no buffer). Portanto, dados (possivelmente m últiplos valores) podem ser perdidos, se o produtor colocar novos dados no buffer com ­ partilhado antes que o consum idor consum a os anteriores, e podem ser incorretam ente duplicados (possivelmente muitas vezes) se o consum idor consum ir dados novamente antes que o produtor produza o próxim o valor. A conseqüência da falta de sincronização do acesso a dados com partilhados é, de certo modo, semelhante à da falta de sincronização de um sem áforo em um cruzam ento movimentado. Para m ostrar essas possibilidades, no exem plo seguinte o consum idor acum ula um total de todos os valores que lê. O produtor produz, em ordem, valores de 1 a 4. No relacionam ento produtor/consum idor tradicional, o consum idor lê cada valor produzido um a vez e som ente uma vez. Além do mais, o consum idor não pode ler cada valor até que o produtor o tenha produzido. Portanto, o produtor deve sempre produzir um valor antes de o consum idor ler esse valor, e o total dos valores consum idos em nosso exemplo deve ser 10. Entretanto, se você executar esse program a várias vezes (consulte as 116 S U tw u is o jte ra à o fu iti am ostras de resultados da Figura 5.5), verá que o total raram ente (se é que algum a vez) é igual a 10. Cada um dos threads produtor e consum idor do exemplo dorm e por intervalos de tempo aleatórios de até três segundos entre a realização de suas tarefas, sim ulando alguns atrasos longos, com o esperar por um a entrada de usuário ou esperar que algum evento ocorra. Assim, não sabemos exatam ente quando o produtor tentará escrever um novo valor, nem sabem os quando o consum idor tentará ler um valor. O program a Java consiste em um a interface Buffer (Figura 5 . 1 ) e quatro classes — Producer (Figura 5 . 2 ) , Consumer (Figura 5 . 3 ) , UnsychronizedBuffer (Figura 5 . 4 ) e SharedBufferTest (Figura 5 . 5 ) . A interface Buffer declara m étodos set e get que um Buffer deve implementar, para habilitar um thread Producer a colocar um valor no Buffer e habilitar um thread Consumer a recuperar um valor do Buffer, respectivamente. Essa interface está im plem entada na Figura 5 . 4 (linha 4 ) . A classe Producer (Figura 5.2) — um a subclasse de Thread (linha 5) — contém o campo sharedLocotion (linha 7), um constru­ tor (linhas 9-14) e um método run (linhas 18-40). O construtor inicializa a referência Buffer sharedLocation (linha 13) com uma referência a um objeto que im plem enta a interface Buffer. Esse objeto é criado em main (Figura 5.5; linhas 6-18) e passado para o construtor com o o parâm etro shared (Figura 5.2; linha 10); o construtor inicializa Buffer sharedLocation (linha 13) para ser um a referência ao parâm etro shared. O thread produtor desse program a executa as tarefas especificadas no método run (linhas 18-40). O com ando fo r nas linhas 20-35 executa um laço quatro vezes. Cada iteração do laço invoca o método Thread.sleep (linha 25) para colocar o thread produtor no estado adorm ecido por um intervalo de tempo aleatório entre 0 e 3 segundos (simulando um a operação dem orada). [Nota: N orm alm ente um thread acorda quando seu tem po de sono expira. Um thread adorm ecido pode ser acordado cedo se um outro thread cham ar o método interrupt do thread adorm ecido. Se isso ocorrer, sleep ‘lança’ um a exceção (do tipo InterruptedException) para indicar que o thread foi interrom pido antes de seu tempo de sono expirar. Em Java essa exceção deve ser ‘m anipulada’, o que requer que a cham ada ao método sleep apareça em um bloco try , o qual é seguido de um m anipulador catch. O bloco try contém o código que podería lançar um a exceção. O m anipulador catch especifica o tipo de exceção que manipula. N esse exem plo, o m anipulador catch im prim e um a stack trace (cópia da pilha) e o program a continua com o com ando seguinte após a seqüência try...catch]. Q uando o thread acorda, a linha 2 6 passa o valor da variável de controle count para o método set do objeto Buffer para m udar o valor do buffer com partilhado. Q uando o laço conclui, as linhas 37-38 exibem uma m ensagem na janela do console indicando que o thread term inou de produzir dados e que ele está encerrando. Em seguida o m étodo run term ina (linha 4 0 ) e o thread produtor entra no estado m orto. É im portante notar que qualquer m étodo cham ado por m eio do método run de um thread (como o método set do Buffer na linha 2 6 ) executa com o parte da execução daquele thread. De fato, cada thread tem sua própria pilha de cham ada ao método. A classe Consumer (Figura 5.3) contém a variável de instância sharedLocation (linha 7), um construtor (linhas 9-14) e um método run (linhas 16-41). O construtor inicializa a referência sharedLocation de Buffer (linha 13) com uma referência a um objeto que im plem enta a interface Buffer. A quele objeto é criado em main (Figura 5.5) e passado ao construtor com o o parâm etro shared (Figura 5.3; linha 10). Com o veremos (Figura 5.5; linhas 12-13), esse é o mesmo objeto UnsynchronizedBuffer usado para inicializar o objeto Producer; assim, os threads produtor e consum idor com partilham o objeto. O thread consum idor nesse program a realiza as tarefas especificadas no método run (Figura 5.3; linhas 16-41). O laço nas linhas 22-36 executa quatro vezes. Cada iteração do laço invoca o m étodo sleep de Thread (linha 27) para colocar o thread consum idor no estado adorm ecido durante um intervalo de tem po aleatório entre 0 e 3 segundos. Em seguida a linha 28 usa o método get de Buffer para recuperar o valor do buffer com partilhado e adiciona o valor à variável sum. Q uando o laço conclui, as linhas 38-39 exibem um a linha na jan ela do console indicando a som a dos valores consum idos e o fato de o thread consum idor estar terminando. Então o método run term ina (linha 41), e o thread consum idor entra no estado morto. [Nota: Usam os um intervalo gerado aleatoriam ente com o método sleep no método run de ambas as classes Producer e Consumer para enfatizar o fato de que, em aplicações multithread, não fica claro quando e por quanto tempo cada thread 1 2 // Fig. 5.1: Buffer.java // interface Buffer especifica métodos para acessar dados do buffer. 3 4 5 6 7 8 public interface Buffer { public void set( int value ); // coloque valor em Buffer public int g e t(); // retorne valor de Buffer } Fiyuras 5. 1 1Interface Buffer utculas um, exemfUor jtroduiôr/Mnátmádôr. Capitulo S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Execução ccssíncrona, concorrente. 117 // Fig. 5.2: Producer.java // método run de Producer controla um thread produtor que // armazena valores de 1 a 4 em Buffer sharedLocation. public class Producer extends Thread { private Buffer sharedLocation; // referência a objeto compartilhado // construtor Producer public Producer! Buffer shared ) { superf "P ro d u c e r"); // cria thread chamado "Producer" sharedLocation = shared; // inicialize sharedLocation } // termine construtor Producer // método run de Producer armazena valores de // 1 a 4 em Buffer sharedLocation public void run!) { for ( int count = 1; count <= 4; count++ ) { // dorme de 0 a 3 segundos, então coloca valor em Buffer try { Thread.sleep! ( in t) ( M ath.random !) * 3001 )); sharedLocation.set( c o u n t); // escreve para o buffer } / / termine try // se thread adormecido for interrompido, imprima cópia da pilha catch ( InterruptedException exception ) { exception.printStackTrace!); } / / termine catch } / / termine for System.err.printlnf getN am e!) + " done producing." + "XnTerminating " + getN am e!) + " . " ) ; } // termine o método run } // termine a classe Producer Figura/ 5.Z | A classe, Producer representa, o thread,produtor em um relacionamento produtor/consumidor. realizará sua tarefa. Essas questões de escalonam ento de threads norm alm ente são de responsabilidade do sistem a opera­ cional. Nesse programa, as tarefas de nosso thread são bastante simples — para o produtor, executar o laço quatro vezes estabelecendo a cada vez um valor no buffer com partilhado; para o consum idor, executar o laço quatro vezes, recuperando a cada vez um valor do buffer com partilhado e adicionando o valor à variável sum. Sem a cham ada ao método sleep, e se o produtor executasse primeiro, m uito provavelmente ele concluiría sua tarefa antes de o consum idor ter um a chance de executar; se o consum idor executasse primeiro, m uito provavelmente ele consum iría o valor ‘null* (-1, especificado em UnsynchronizedBuffer, linha 6 da Figura 5.4) quatro vezes e term inaria (exibindo um a som a inválida -4 ) antes que o produtor produzisse até m esm o seu prim eiro valor]. A classe UnsychronizedBuffer (Figura 5.4) im plem enta a interface Buffer (linha 4) definida na Figura 5.1 e declara a variável buffer (linha 6) com partilhada entre Producer e Consumer. A variável buffer é inicializada com o valor -1. Esse valor é usado para dem onstrar o caso em que Consumer tenta consum ir um valor antes que Producer coloque um valor em bu ffer. Os m étodos set (linhas 8-15) e get (linhas 17-24) não sincronizam acesso ao campo buffer (logo veremos como fazer isso). O método sei apenas designa seu parâm etro a buffer (linha 14) e o método get apenas retom a o valor de buffer (linha 23). N ote que cada método 118 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Sistemas operacionais // Fig. 5.3: Consumer.java // método run de Consumer controla um thread que executa um laço quatro //vezes e lê um valor de sharedLocation cada vez. public class Consumer extends Thread { private Buffer sharedLocation; // referência a objeto compartilhado // construtor Consumer public Consumer( Buffer shared ) { super( "C o n s u m e r"); // crie o thread chamado "Consumer" sharedLocation = shared; // inicialize sharedLocation } // termine o construtor Consumer // leia o valor de sharedLocation quatro vezes e some os valores public void ru n () { int sum = 0; 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 // alterne entre valor sleeping e getting Buffer for ( int count = 1; count <= 4; + + c o u n t) { // durma 0-3 segundos, leia o valor de Buffer e adicione ao total try { Thread.sleep( ( in t ) ( M ath.random f) * 3001 )); sum += sharedLocation.get(); } //s e thread adormecido interrompido, imprima cópia de pilha catch ( InterruptedException exception ) { exception.printStackTracef); } } // termine for System.err.printlnf getN am ef) + " read values totaling: " + sum + "AnTerminating " + g e tN a m e l) + " . " ) ; } // termine o método run } // termine a classe Consumer Pujurto S.3 | A classe, Consumer representa, o tkread, consumidor em um relacionamento produtor/consumidor. usa o método estático currentThread da classe Thread para obter um a referência ao thread que está em execução no momento, e usa o método getName daquele thread para obter o nome do thread para propósitos de resultado (linhas 11 e 20). A classe SharedBufferTest (Figura 5.5) contém o m étodo main (linhas 6-18), que lança a aplicação. A linha 9 instancia um objeto UnsynchronizedBuffer com partilhado e o designa à referência sharedLocation de Buffer. E sse objeto arm azena os dados que serão com partilhados entre os threads produtor e consum idor. A s linhas 12-13 criam o objeto producer de Producer e o objeto consumer de Consumer. C ada um a das cham adas ao construtor nessas linhas passa sharedLocation com o o argum ento para o construtor (linhas 9-14 da Figura 5.2 para Producer, e linhas 9-14 da F igura 5.3 para Consumer), de m odo que cada thread acessa o m esm o Buffer. Em seguida, as linhas 15-16 da F igura 5.5 invocam o m étodo start dos threads producer e consumer, respectivam ente, para colocá-los no estado pronto. Isso lança a execução desses threads fazendo um a cham ada im plícita ao m étodo run de cada thread. O m étodo run de um thread será cham ado quando o thread for despachado para um processador p ela prim eira vez. D epois de ativados os threads producer e consumer, o m étodo main (o thread principal de Capítulo S 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 Execução assíncrona, concorrente, JJÇ // Fig. 5.4: UnsynchronizedBuffer.java // UnsynchronizedBuffer representa um único inteiro compartilhado. public class UnsynchronizedBuffer implements Buffer { private int buffer = -1; // compartilhado por Producer e Consumer // coloque valor no buffer public void set( int value ) { System.err.printlnl Thread.currentThreadl ).getNam e() + " writes " + value ); buffer = value; } // termine o método set // retorne o valor do buffer public int g e t() { System.err.printlnl Thread.currentThreadl ).getNam e() + " reads " + b u ffe r); 22 23 24 25 26 return buffer; } // termine o método get } // termine a classe UnsynchronizedBuffer Fujura, 5 .4 A daose, UnsynchronizedBuffer m antém o inteiro compartilhado que, í acusado por um thread,produtor e, um, thread, consumidor iria, métodos set e,get. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // Fig. 5.5: SharedBufferTest.java // SharedBufferTest cria threads produtor e consumidor. public class SharedBufferTest { public static void mainl String [] args ) { // crie objeto compartilhado usado por threads Buffer sharedLocation = new UnsynchronizedBuffer!); // crie objetos produtor e consumidor Producer producer = new Producer! sharedLocation ); Consumer consumer = new Consumer! sharedLocation ); producer.start!); // inicie thread produtor consum er.start!); // inicie thread consumidor } //te rm in e main } // termine a classe SharedCell .5 A ciasse, SharedBuffer habilita, threads a, modificar u m objeto compartilhado sem sincronização (parte, 1 de, 2). 120 Sistemas operaxionati A w côstríu de, K & suitaxío 1: Consumidor lê -1 Produtor escreve 1 Consumidor lê 1 Consumidor lê 1 Consumidor lê 1 Consumidor lê valores totalizando: 2. Terminando Consumidor. Produtor escreve 2 Produtor escreve 3 Produtor escreve 4 Produtor terminou de produzir. Terminando Produtor. Amostrcu cie, KesbdtaAo 2: Produtor escreve 1 Produtor escreve 2 Consumidor lê 2 Produtor escreve 3 Consumidor lê 3 Produtor escreve 4 Produtor terminou de produzir. Terminando Produtor. Consumidor lê 4 Consumidor lê 4 Consumidor lê valores totalizando: 13. Terminando Consumidor. Awiostra, RzstdtaAo 3: Produtor escreve 1 Consumidor lê 1 Produtor escreve 2 Consumidor lê 2 Produtor escreve 3 Consumidor lê 3 Produtor escreve 4 Produtor terminou de produzir. Terminando Produtor. Consumidor lê 4 Consumidor lê valores totalizando: 10. Terminando Consumidor. ura/ S .S A cicusse/ SharedBuffer habilita/ tkreaAs a, uw difiaur mm, objeto com partílkaJx sem/ sUuronizaçÃo (parte/ 2 de/ 2 ). execução) term ina, e o thread principal entra no estado m orto. A ssim que am bos os threads producer e consumer entrarem no estado m orto (que ocorre quando seus m étodos run term inam ), o program a encerra. Lem bre-se, na visão geral desse exemplo, de que o thread Producer deve produzir um valor antes que o thread Consumer consum a um valor, e cada valor produzido pelo produtor deve ser consumido exatamente uma vez pelo consumidor. Todavia, quando estudam os o prim eiro resultado da Figura 5.5, vem os que o consum idor recuperou o valor -1 antes mesmo de o produtor colocar um a valor no buffer. O primeiro valor produzido (1) foi consum ido três vezes. A lém disso, o consum idor terminou a execução antes que o produtor tivesse uma oportunidade de produzir os valores 2, 3 e 4, portanto esses três valores foram perdidos. Foi produzido um total 2, incorreto. No segundo resultado vem os que o valor 1 foi perdido, porque os valores 1 e 2 foram produzidos antes que o thread consum idor pudesse ler o valor 1 (desse modo, o valor 2 foi gravado sobre o valor 1 no buffer); e o valor 4 foi consum ido duas vezes. M ais uma vez foi produzido um valor incorreto. A últim a am ostra de resultado dem onstra que é possível, com algum a sorte, obter um resultado apropriado; e é claro que esse com portam ento não pode ser garantido. üLpítulo 5 Execuç&oMsíncroHa,c0HCôrreHt& J2J Esse exemplo dem onstra que o acesso a um objeto com partilhado por threads concorrentes deve ser controlado cui­ dadosam ente; caso contrário, um program a pode produzir resultados incorretos. Dam os a solução para esse problem a no próxim o capítulo. O restante deste capítulo discute com o threads controlam o acesso concorrente a dados com partilhados im pondo acesso m utuam ente exclusivo àqueles dados. Ret/Uão' 1. (V/F) No exemplo produtor/consum idor m ostrado nas figuras 5.1 a 5.5 o resultado seria correto e consistente se as cham adas à sleep fossem removidas. 2. Q uais os m enores e os m aiores valores possíveis de sum ao final da execução do exem plo m ostrado nas figuras 5.1 a 5.5 e com o esses valores seriam obtidos? R e íp o itã i: 1) Falso. As cham adas a sleep foram incluídas ali apenas para enfatizar o fato de haver incerteza dentro de um sistem a quanto à ordem e ao m omento em que as instruções são executadas. A inda assim, não podem os prever as velocidades com que esses threads avançarão, portanto os resultados ainda poderíam ser incorretos. 2) O m enor valor ocorrería se o consum idor tentasse consum ir quatro valores antes que o produtor produzisse algum. Nesse caso, sum seria -4 . O m aior valor ocorrería se o produtor produzisse quatro valores antes de o consum idor ter consum ido qualquer um. Nesse caso, o consum idor consum iría o valor quatro vezes, e sum seria 16. 5.2.2 Seções críticas A exclusão m útua precisa ser imposta som ente quando threads acessam dados que podem ser modificados. Quando threads realizam operações que não conflitam uma com a outra (por exem plo, leitura de variáveis), o sistem a deve perm itir que os threads prossigam concorrentem ente. Quando um thread acessa dados modificáveis, diz-se que está em um a seção crítica (ou região crítica).12Para evitar os tipos de erros que encontram os anteriorm ente, o sistem a deve garantir que so­ m ente um thread por vez possa executar instruções na sua seção crítica para um recurso particular. Se um thread qualquer tentar entrar em sua seção crítica enquanto outro estiver em sua própria seção crítica, o prim eiro thread deve esperar até que o thread que está em execução saia da seção crítica. Assim que um thread sair de sua seção crítica, um thread que está à espera (ou um dos threads à espera, se houver vários) poderá entrar e executar sua seção crítica. Q ualquer thread que não precise entrar na sua seção crítica poderá executar independentem ente de a seção crítica estar ocupada. Um sistem a que im põe exclusão m útua deve controlar cuidadosam ente o acesso e a execução em seções críticas. Um thread que estiver em um a seção crítica tem acesso exclusivo aos dados com partilhados, modificáveis, e todos os outros threads que estão requisitando concorrentem ente acesso àqueles dados m antêm -se à espera. Portanto, um thread deve executar uma seção crítica o mais rapidam ente possível. Um thread não deve ficar bloqueado dentro de sua seção crítica, e seções críticas devem ser cuidadosamente codificadas para evitar — por exemplo — a possibilidade de laços infinitos. Se um thread que estiver dentro de um a seção crítica terminar, voluntária ou involuntariam ente, o sistem a operacional, ao realizar sua limpeza final, deverá liberar a exclusão m útua para que outros threads possam entrar em suas seções críticas. Im por acesso m utuam ente exclusivo a seções críticas é um dos principais problem as na program ação concorrente, e muitas soluções foram concebidas: algumas de software e outras de hardware; algum as de nível bastante baixo e outras de alto nível; algumas exigindo cooperação voluntária entre threads e outras, rígida aderência a protocolos estritos. Exa­ minarem os um a variedade dessas soluções nas próxim as seções. R m m 1. Por que é im portante que um thread execute um a seção crítica tão rapidam ente quanto possível? 2. O que pode acontecer se o sistem a operacional não realizar a lim peza final? R e ip o ità i: 1) Se outros threads estiverem esperando para executar suas seções críticas, eles sofrerão atraso enquanto houver qualquer outro thread em sua seção crítica. Se as seções críticas não executarem rapidam ente, o desem penho geral do sistem a poderá ser prejudicado. 2) U m thread podería term inar enquanto estivesse em sua seção crítica e não liberar a exclusão m útua, e os threads que estivessem esperando nunca conseguiríam entrar em suas seções críticas. Com o veremos no Capítulo 7, “D eadlock e adiam ento indefinido” , esses threads ficarão travados. 5.2.3 P ruiutivas d e exclusão m útua, O seguinte pseudocódigo descreve adequadam ente o m ecanism o de contagem de e-m ail da Seção 5.2, “E xclusão m útua” . N ote que usam os as palavras enterMutualExdusion() e exitMutualExclusion(). Essas palavras são construções que encapsulam a seção crítica do thread — quando um thread quiser entrar em sua seção crítica, deverá prim eiram ente m Sistemas ojMCüúoHAis executar enterMutualExdusionO; quando um thread sair da seção crítica, executará exitMutualExdusion(). C om o essas constru­ ções invocam as operações m ais fundam entais inerentes à exclusão m útua, às vezes são denom inadas primitivas de exclusão mútua. while (true) { f í e c e i v e e -m a il // enterMutualExdusionO I n c r e m e n t mailCount exitMutualExclusionf) I I q u e r e n t r a r n a s e ç ã o c r ít ic a e x e c u t a n d o fo r a d a s e ç ã o c r ític a I I e x e c u t a n d o d e n t r o d a s e ç ã o c r ít ic a II s a i n d o d a s e ç ã o c r ític a Considerem os com o essas prim itivas podem fornecer exclusão mútua. Por questão de sim plicidade, no exemplo apre­ sentado nesta e nas diversas seções seguintes, assum irem os que haja apenas dois threads concorrentes e um processador. M anusear n processos ou threads concorrentes é um tópico consideravelm ente m ais com plexo que discutirem os na Seção 5.4.3, “Exclusão m útua de n-threads: o algoritm o da padaria de Lam port”. Também discutirem os com o a exclusão m útua é im posta em sistemas m ultiprocessadores. Suponha que os threads T ( e T 2do mesmo processo estejam am bos executando no sistema. Cada thread gerencia m en­ sagens de e-m ail e cada thread contém instruções que correspondem ao pseudocódigo anterior. Quando chega à linha enterMutualExdusionO, o sistem a deve determ inar se T 2 já está em sua seção crítica. Se T 2 não estiver em sua seção crítica, T, entrará em sua própria seção crítica, increm entará a variável com partilhada mailCount e executará exitMutualExdusionO para indicar que T, saiu de sua seção crítica. Se, por outro lado, quando T, executar enterMutualExdusionO, T 2estiver em sua seção crítica, T, deverá esperar até q u eT 2execute exitMutualExdusionO. Então som ente um dos threads terá perm issão para prosseguir e um ficará esperando. Por enquanto, adm itirem os que o sistem a escolhe aleatoriam ente o thread que prosseguirá. [Como veremos, tal política pode levar a adiam ento indefinido de um dos threads se o outro sem pre for selecionado quando os threads tentarem entrar, repetidas vezes, em suas seções críticas.] Nas seções seguintes discutirem os diversos m ecanism os para im plem entar as primitivas de exclusão m útua enterMutualExdusionO e exitMutualExdusionO. R eM cur 1. O que acontecerá se um thread não cham ar enterMutualExdusionO antes de acessar variáveis com partilhadas em uma seção crítica? 2. O que acontecerá se um thread que está em sua seção crítica não cham ar exitMutualExdusion? R eip o ifa i • 1) Se outros threads tam bém entrarem em suas seções críticas, poderá haver resultados indeterm inados com sérias conseqüências. 2) Todos os outros threads que estão esperando para entrar em suas seções críticas nunca teriam perm issão para fazê-lo. Com o veremos no Capítulo 7, “D eadlock e adiam ento indefinido”, todos esses outros threads eventualm ente entrariam em um a situação de impasse. S.3 IvHplemeMttiçâô {trimiturns exclusão \MÁtiuu Cada um a das soluções iniciais de exclusão m útua que discutim os fornece um a im plem entação de enterMutualExdusionO e exitMutualExdusionO que exibe as seguintes propriedades: 1. A solução é implementada puramente em software, em uma máquina sem instruções de exclusão mútua, em linguagem de máquina, projetadas especificamente. Cada instrução em linguagem de m áquina é executada indivisivelmente — uma vez iniciada, vai até o final sem interrupção. Se um sistem a contiver m últiplos processadores, vários threads poderíam tentar acessar o m esm o item de dados sim ultaneam ente. Com o verem os, muitas soluções de exclusão m útua para sistem as uniprocessadores dependem de acesso a dados com partilhados, o que significa que poderíam não funcionar em sistemas multiprocessadores (veja a Seção 15.9 “Exclusão m útua em m ultiprocessadores”). Por questão de sim plicidade, suporem os que o sistem a contenha um processador. Tratarem os de sistem as m ultiproces­ sadores m ais adiante. 2. Não se pode fazer nenhum a suposição sobre as velocidades relativas de threads assíncronos concorrentes, o que significa que qualquer solução deve supor que um thread pode sofrer preem pção ou ser retom ado a qualquer instante durante sua execução e que a velocidade de execução de cada thread pode não ser constante nem previsível. 3. Um thread que estiver executando instruções fora da sua seção crítica não pode evitar que quaisquer outros threads entrem em suas seções críticas. 4. Um thread não deve ser im pedido indefinidam ente de entrar em sua seção crítica \Notci: U m a vez dentro de uma seção crítica codificada inadequadamente, um thread pode ‘com portar-se m al’ de tal m odo que levaria ao adiam ento indefinido ou até ao deadlock. Discutirem os essas questões detalhadam ente no Capítulo 7]. CafUtulo S Execução assÍKcroKu concorrente* J% 2 RevUcur 1. Por que, na sua opinião, não podem os prever as velocidades relativas de threads assíncronos concorrentes? 2. Com o um thread inadequadam ente codificado pode causar adiamento indefinido ou deadlock? R eip o ifa i 1 1) U m a razão é que interrupções de hardware, distribuídas aleatoriam ente, podem corrom per a execução do thread a qualquer instante. Em qualquer período de tem po, essas interrupções podem perm itir que alguns threads execu­ tem durante m ais tempo do que outros. A lém disso, situações desfavoráveis em algoritm os de escalonam ento de recursos podem favorecer certos threads. 2) Um thread que nunca saiu de sua seção crítica (por exem plo, entrando em laço infinito) eventualm ente adiaria de m odo indefinido ou causaria deadlock em todos os outros threads quando esses tentassem entrar em suas seções críticas. 5A Soluções de*software*povo*problema* de*exclusão mútua* U m a elegante im plem entação de exclusão m útua foi apresentada pela prim eira vez pelo m atem ático holandês Dekker. N a seção seguinte acom panharem os o desenvolvim ento de D ijkstra para o algoritmo de Dekker, um a im plem entação de exclusão m útua para dois threads.13Os argumentos apresentados introduzem muitas das sutilezas da program ação concor­ rente que fazem dela um cam po tão interessante de estudo. Em seguida discutirem os algoritm os m ais simples e eficientes desenvolvidos por G.L. Peterson14 e L .Lam port.15 5.4-1 O algoritmo de, Dekker N esta seção exam inam os diversas tentativas de im plem entar exclusão mútua. Cada im plem entação contém um proble­ m a que a subseqüente im plem entação irá resolver. O ápice da seção é a apresentação de um a im plem entação de software correta para exclusão m útua livre de deadlock e adiam ento indefinido. Primeira* versão (af>resenta*ção da*sincronização intertravaAa* e*da*espera* ociosa*) A Figura 5.6 m ostra um prim eiro esforço para especificar um código para im por exclusão m útua entre dois threads. O pseudocódigo é apresentado usando um a sintaxe baseada na linguagem C. C ada um a das instruções do thread pode ser subdividida em três partes: instruções não críticas (instruções que não m odificam dados com partilhados), instru­ ções críticas (instruções que m odificam dados com partilhados) e instruções que garantem a exclusão m útua (instruções que im plem entam enterMutualExdusionO e exitMutualExdusion(). C ada thread entra e sai repetidam ente de sua seção crítica até concluí-la. Nessa versão da exclusão m útua o sistem a utiliza um a variável denom inada threadNumber à qual am bos os threads têm acesso. A ntes de o sistem a com eçar a executar os threads, threadNumber é colocada em l (linha 3). Então o sistem a inicia am bos os threads. A prim itiva enterMutualExdusionO é im plem entada com o um único laço while que executa indefinidamente até que a variável threadNumber fique igual ao núm ero do thread (veja as linhas 13 e 3 1 nos threads T, e T 2, respectivamente). A prim itiva exitMutualExdusionO é im plem entada com o um a instrução única que coloca em threadNumber o núm ero do outro thread (veja as linhas 17 e 35 nos threads T, e T 2, respectivamente). Considere um m odo com o a execução podería proceder segundo essa im plem entação. Suponha que T, com ece a exe­ cutar prim eiro. O thread executa o laço while (linha 13) que age com o enterMutualExdusionO. Com o threadNumber é inicialm ente 1, T, entra em sua seção crítica (o código indicado pelo com entário na linha 15). A gora suponha que o sistem a suspenda T, e com ece a executar T 2 O segundo thread vê que threadNumber é igual a 1 e perm anece ‘travado’ no laço while (linha 31). Isso garante a exclusão mútua, porque T 2não pode entrar em sua seção crítica até que Tj saia da sua e coloque threadNumber em 2 (linha 17). Eventualm ente T, term ina a execução em sua seção crítica (lem bre-se de que estam os supondo que as seções críticas não contenham laços infinitos e que os threads não m orram nem fiquem bloqueados dentro das seções críticas). Nesse ponto T, coloca threadNumber em 2 (linha 17) e passa para suas instruções ‘não críticas’. A gora T 2está livre para entrar em sua seção crítica. Em bora essa im plem entação garanta exclusão mútua, a solução tem desvantagens significativas. N a primitiva enter­ MutualExdusionO, o thread usa o processador para realizar trabalho não essencial (o thread testa repetidam ente o valor de threadNumber). D iz-se que tal thread está em espera ociosa. A espera ociosa pode ser um a técnica ineficaz para im plem entar exclusão m útua em sistemas uniprocessadores. Lem bre-se de que a m eta da m ultiprogram ação é aum entar a utilização do processador. Se nossa prim itiva de exclusão m útua usar ciclos de processador para realizar trabalho não essencial ao thread, o tem po do processador será desperdiçado. Essa sobrecarga, todavia, é lim itada a curtos períodos de tem po (quando há disputa entre os threads para entrar em suas seções críticas). A desvantagem m ais prejudicial dessa im plem entação é que ela viola um a das principais restrições que identificamos na Seção 5.3, “Im plem entação de primitivas de exclusão m útua” , ou seja, um thread que não está em sua seção crítica não m S U tW iA S O jM T ílc io tU lti 1 S iste m a : 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int threadNumber = 1; startThreadsf); // inicialize e lance ambos os threads T h re a d 7,; void m ain() { w h ile U d o n e ) { while ( threadNumber == 2 ); // enterMutualExclusion // código da seção crítica threadNumber = 2; // exitMutualExclusion // código fora da seção crítica 20 21 } // termine o while mais externo 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 } // termine Thread T 1 T h re a d T2: void m a in f) { while (Id o n e ) { while ( threadNumber == 1 ); // enterMutualExclusion // código da seção crítica threadNumber = 1; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } // termine Thread T2 FujttrO/ S. € IntjUeMteHt&çÃo ejcclouíLc mútvuv — vers&o 1. deve afetar um thread que deseja entrar em sua própria seção crítica. Por exemplo, T , deve entrar na seção crítica primeiro, porque o sistem a inicialm ente coloca threadNum ber em 1. Se T 2 tentar entrar prim eiro, ele inicia a execução e tenta, sem sucesso, entrar em sua seção crítica. Eventualm ente T , executa, entrando em sua seção crítica e colocando threadNumber em 2. Por isso, T 2 pode ser atrasado consideravelm ente antes de poder entrar em sua seção crítica. N a verdade os threads devem entrar e sair de suas seções críticas com alternância restrita. Se um thread precisar entrar em sua seção crítica mais frequentem ente do que outro, o thread m ais veloz será obrigado a funcionar na velocidade do m ais lento, o que é deno­ minado problem a de sincronização de intertravamento.* A im plem entação de exclusão m útua seguinte elim ina esse problem a, mas introduz outro. É claro que o problema da Seção 5.2.1 requeria sincronização de intertravamento, porque o buffer era de tamanho unitário. Entre­ tanto, quase todos os buffers contêm diversas entradas, o que significa que a sincronização de intertravamento causa comportamento ineficiente se o produtor e o consumidor funcionarem em velocidades diferentes. üipítulo 5 Execução assUicrona, concorrente, J25 Segunda, versão (trioloção da, exclusão mutua,) A Figura 5.7 contém um a solução que tenta elim inar a sincronização de intertravamento da im plem entação anterior. N a prim eira solução, o sistem a m antinha som ente um a única variável global — o que forçava a sincronização de intertra­ vamento. A versão 2 m antém duas variáveis — t l Inside que é verdadeira se T , estiver dentro de sua seção crítica, e t2lnside que é verdadeira se T 2 estiver dentro de sua seção crítica. U sando duas variáveis para governar o acesso às seções críticas (uma para cada thread), podem os elim inar a sincro­ nização de intertravamento em nossa segunda im plem entação de exclusão mútua. Tj poderá entrar continuam ente em sua seção crítica tantas vezes quanto necessário enquanto t2lnside for falso. E mais, se T , entrar na seção crítica e colocar t l Inside 1 S iste m a : 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 boolean t1 Inside = false; boolean t2lnside = false; startThreadsO; // inicialize e lance ambos os threads T h re a d T v o id m a in (){ w h ile (ld o n e ) { while ( t2lnside ); // enterMutualExclusion t1 Inside = true; // enterMutualExclusion // código da seção crítica t1 Inside = false; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } // termine Thread T1 Thread T 2: void m ain() { while (Id o n e ) { while ( t1 Inside ); // enterMutualExclusion t2lnside = true; // enterMutualExclusion // código da seção crítica t2lnside = false; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } // termine Thread T2 'ouro, 5.7 | Implesumbação d& exclusão mútua, — versão 2. 126 Sistemas operasiôKAÍs em verdadeiro, T2 estará em espera ociosa. Eventualm ente T, concluirá sua seção crítica e executará seu código de saída da exclusão m útua colocando tl Inside em falso. Em bora essa solução elim ine a questão da sincronização de intertravamento, infelizm ente não garante a exclusão m ú­ tua. Considere a seguinte situação. As variáveis t l Inside e t2lnside são am bas falsas e am bos os threads tentam entrar em suas seções críticas ao mesmo tempo. Tj testa o valor de t2lnside (linha 14), determ ina que o valor é falso e passa para o próxim o com ando. Suponha que o sistem a faça a preem pção de Tj antes que ele possa executar a linha 16 (o que ele precisa fazer para m anter T 2 fora da sua própria seção crítica). A gora T 2executa, determ ina que t l Inside é falso e assim T 2entra em sua seção crítica. Enquanto T 2está em sua seção crítica, ele sofre preem pção, e Tj retom a a execução na linha 16 colocando t l Inside em verdadeiro e entrando em sua seção crítica. A m bos os threads estão executando concorrentem ente suas seções críticas violando a exclusão múltipla. Terceira/ versão (introdução do deadlock,) A Versão 2 falhou porque entre o instante em que um thread determ ina em seu teste while que pode seguir em frente (linhas 14 e 43) e o m om ento em que sinaliza, por m eio de um flag, para dizer que está em sua seção crítica (linhas 16 e 36), existe a possibilidade de um outro thread obter o controle, passar no seu teste while e entrar em sua seção crítica. Para corrigir esse problem a, assim que um thread tentar o teste w hile, deve ter certeza de que o outro processo não pode passar no seu próprio teste while. A versão 3 (Figura 5.8) tenta resolver esse problem a fazendo cada thread sinalizar seu próprio flag antes de entrar no laço while. Desse modo, T, indica seu desejo de entrar na seção crítica colocando tlWantsToEnter em verdadeiro. Se t2Want$ToEnter for falso, T, entrará em sua seção crítica e im pedirá que T 2 entre em sua própria seção crítica. Assim, a exclusão m útua será garantida e parece-nos a solução correta. G arantirem os que, no m om ento em que um thread sinalizar sua intenção de entrar na seção crítica, um outro thread não poderá entrar na seção crítica. Um problem a foi resolvido, mas um outro foi introduzido. Se cada thread sinalizar seu flag antes de executar o teste while, cada um deles encontrará o flag de um outro thread sinalizado e ficará executando o laço para sem pre em while. Esse é um exemplo de deadlock (im passe) entre dois processos, discutido no Capítulo 7, “D eadlock e adiam ento indefinido” . 1 S iste m a : 2 3 4 5 6 7 8 9 10 void m ain() 11 { 12 13 14 15 16 17 18 19 20 boolean tlW antsToEnter = false; boolean t2WantsToEnter = false; startThreadsf); // inicializa e lança ambos os threads T h re a d 7,: while ( Idone ) { tlW antsToEnter = true; // enterMutualExclusion while ( t2W antsToEnter); // enterMutualExclusion // código da seção crítica t1 WantsToEnter = false; // exitMutualExclusion 21 22 23 24 25 26 27 28 29 // código fora da seção crítica } // termine o while mais externo } // termine Thread T 1 T h re a d T ^ Implementação de, exclusão mútua, — versão 3 (parte 1 de, 2). Capitulo S 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 Execução aesíncrona, concorrente, JQ J void mainO { w h ile (!d o n e ) { t2WantsTo Enter = true; // enterMutualExclusion while ( t1 W antsToEnter); // enterMutualExclusion // código da seção crítica t2WantsToEnter = false; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } // termine Thread T2 ÜjUrO/ S.S | Implementação de, exelusão mútua, — versão 3 (parte,2 de,2). Quarta/ versão (introdução do adiamento indefinido) Para criar um a im plem entação de exclusão m útua efetiva, precisam os de um m odo de ‘escapar’ dos laços infinitos que encontram os na versão anterior. A versão 4 (Figura. 5.9) consegue fazer isso forçando cada thread em laço a colocar seu flag em falso durante curtos períodos, o que perm ite que outro thread prossiga com seu laço while com seu próprio flag colocado em verdadeiro. A quarta versão garante exclusão m útua e im pede deadlock, mas perm ite que se desenvolva um outro problem a poten­ cialm ente devastador, o a d ia m e n to indefinido. Com o não podem os prever as velocidades relativas de threads assíncronos concorrentes, devemos considerar todas as possíveis seqüências de execução. Os threads poderíam, por exemplo, prosseguir em cascata (um atrás do outro). Cada thread pode colocar seu flag em verdadeiro (linha 14), em seguida fazer o teste while (linha 16), depois entrar no corpo do laço while, colocar seu flag em falso (linha 18), esperar durante um período de tempo aleatório (linha 20), colocar seu flag em verdadeiro (linha 22), e repetir a seqüência com eçando no teste while. À medida que os threads fazem isso, as condições testadas (linhas 18 e 45) perm anecerão verdadeiras. É claro que a probabilidade de ocorrência de tal seqüência de execução seria baixa — mas podería ocorrer. Se um sistem a usando esse tipo de exclusão m útua estivesse controlando um voo espacial, um m arcapasso ou um sistem a de controle de tráfego aéreo, a possibilidade de adiamento indefinido, e subseqüente falha de sistema, podería colocar vidas humanas em risco. Portanto, a versão quatro tam bém é um a solução inaceitável para o problem a da exclusão mútua.1234567890 1 S is te m a : 2 3 4 5 6 7 8 9 10 11 12 13 14 15 boolean t1 WantsToEnter = false; boolean t2WantsToEnter = false; startThreadsf); // inicializa e lança ambos os threads T hread T j void mainO { while (Id o n e ) { t1 WantsToEnter = true; // enterMutualExclusion urO/5.9 Implementação de,exclusão mútua,— versão 4 (parte, 1de,2). m 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 SUtWiAS OpeTílciotUlti while ( t2W antsToEnter) // enterMutualExclusion { t1 WantsToEnter = false; // enterMutualExclusion // espere por um período de tem po curto, aleatório t1 WantsToEnter = true; } / / termine while // código da seção crítica t1 WantsToEnter = false; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } //te rm in e Thread T1 Th re a d T2: void m ain() { while (Id o n e ) { t2WantsToEnter = true; // enterMutualExclusion while ( t1 W antsToEnter) // enterMutualExclusion { t2WantsToEnter = false; // enterMutualExclusion // espere por um período de tempo curto, aleatório t2WantsToEnter = true; } / / termine while // código da seção crítica t2WantsToEnter = false; // exitMutualExclusion // código fora da seção crítica } // termine o while mais externo } // termine Thread T2 Figura, 5.9 liMplemerúição de, ex.clutcLo mútuo, — t/ers&o 4 (porte, 2 de,2). Algoritm o de, Vekker (um a,solução adeguada,) A figura 5.10 ilustra o A lg o ritm o de D ek k e r — um a solução correta da exclusão m útua de dois threads implem entada exclusivam ente em software sem nenhum a instrução de hardw are de uso especial. O algoritm o de Dekker ainda usa um flag de sinalização (flag) para indicar o desejo de um thread de entrar na sua seção crítica, mas tam bém incorpora o conceito de ‘thread favorecido’ (favored thread), que entrará na seção crítica no caso de ocorrer um a disputa (isto é, quando cada thread desejar entrar sim ultaneam ente em sua seção crítica). Vamos exam inar com o o A lgoritm o de Dekker elim ina a possibilidade de adiam ento indefinido ocorrida na versão 4. Prim eiram ente observe que, nesse algoritmo, a primitiva enterMutualExclusion é im plem entada pelas linhas 15-26 e 45-56; a prim itiva exitMutualExclusion é im plem entada pelas linhas 30-31, 60-61. T, indica seu desejo de entrar em sua seção crítica Capítulo 5 1 Sistema: 2 3 4 5 6 7 8 9 10 int favoredThread = 1; boolean tIW antsToEnter = false; boolean t2WantsToEnter = false; 11 void m ain() { while ( !d o n e ) { tIW antsToEnter = true; 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 startThreads(); // inicializa e lança ambos os threads T h re a d T f; while ( t2W antsToEnter) { if ( favoredThread == 2 ) { tIW antsToEnter = false; while ( favoredThread == 2 ); // espera ociosa tIW antsToEnter = verdadeiro; } // termine if } / / termine while // código da seção crítica favoredThread = 2; tIW antsToEnter = falso; // código fora da seção crítica } // termine o while mais externo } / / termine Thread T1 Th re a d void m ain() { while ( Id o n e ) { t2WantsTo Enter = true; while ( tIW antsT oE nter) { if ( favoredThread == 1 ) { t2WantsToEnter = false; while ( favoredThread == 1 ); // espera ociosa t2WantsToEnter = true; } // termine if } / / termine while 10 Algoritmo de, Vekker pura, exclusão uuótua, (parte 1 de Z). Execução aosíncrona, concorrente. 129 130 SUtwuis operaciotuiU 57 58 59 60 61 62 63 64 65 // código da seção crítica favoredThread = 1; t2WantsTo Enter = false; // código fora da seção crítica } // termine o while mais externo 66 67 } // termine Thread T2 Figura, S. 10 Algoritmo de, Vekkerpara, excLuã/> mútua, (parte, 2 de,2). sinalizando seu flag em true (linha 15). O thread então prossegue até o teste while (linha 17) e determ ina se T2 tam bém quer entrar em sua seção crítica. Se o flag de T 2 estiver sinalizado em false, não haverá disputa entre threads que estão tentando entrar em suas seções críticas, portanto T, pulará o corpo do laço while e entrará em sua seção crítica (linha 28). Suponha porém que, quando T, executar o teste while (linha 17), descubra que o flag de T 2 está sinalizado em true. Nesse caso haverá disputa entre threads que estão tentando entrar em suas respectivas seções críticas. O Thread T, entra no corpo do seu laço while no qual exam ina o valor da variável favoredThread que é usada para resolver esses conflitos (linha 19). Se o thread T, for o thread favorecido, ele pulará o corpo do if e executará repetidam ente o teste while esperando que T 2 coloque t2WantsToEnter em false, o que, com o verem os, ele eventualm ente deverá fazer. Se T, determ inar que T 2 é o thread favorecido (linha 19), T, será forçado a entrar no corpo do com ando if, onde colocará tlWantsToEnter em false (linha 21), e executará o laço dentro do while seguinte enquanto T2 continuar com o thread favorecido (linha 22). Colocando tlWantsToEnter em false, T, perm ite que T 2 entre em sua própria seção crítica. Eventualm ente T2 sai de sua seção crítica e executa seu código de saída da exclusão m útua (linhas 60-61). Esses co­ m andos colocam favoredThread de volta em T, e colocam í2WantsToEnter em false. A gora T, pode passar o teste while interno (linha 22) e colocar tlWantsToEnter em true (linha 23). Então T, executa o teste while m ais externo (linha 17). Se t2WantsToEnter (que foi recentem ente colocado em false) ainda estiver false, T, entrará na sua seção crítica (linha 28) e seu acesso exclusivo ficará garantido. Entretanto, se T 2 tiver tentado rapidam ente entrar m ais um a vez na sua própria seção crítica, t2WantsToEnter será colocado em true e T, m ais um a vez será forçado novam ente para o interior do corpo do while m ais externo (linha 19). Porém, dessa vez, T , é o thread favorecido. Portanto, T , pula o corpo do if e executa repetidam ente o teste while mais externo (linha 17) até que T 2 coloque t2WantsToEnter em false, perm itindo que T , entre em sua seção crítica. O A lgoritm o de Dekker garante exclusão m útua im pedindo, ao m esm o tempo, deadlock e adiam ento indefinido. C on­ tudo, a prova dessa declaração não é im ediatam ente evidente devido à natureza com plexa da exclusão mútua. Por exemplo, considere a seguinte possibilidade interessante. Q uando T, sai do laço interno da espera ociosa (linha 22), o sistem a pode tom ar T, preem ptivo (retirando a CPU de T, e designando-a para outro thread) antes de colocar tlWantsToEnter em true, o que perm itiría que T 2ficasse executando o laço na tentativa de entrar novamente em sua própria seção crítica. Então T2colocaria t2WantsToEnter em true e entraria novam ente em sua seção crítica. Quando T, eventualm ente retom ar a execução, colocará tlWantsToEnter em true. Com o a vez é de T, (e porque tlWantsToEnter agora está colocado em true), se T2 tentar entrar novamente (linha 47), deverá colocar t2WantsToEnter em false e entrar em sua espera ociosa interna (linha 52). A gora T, poderá entrar em sua seção crítica. Essa circunstância, que a princípio podería parecer com plicada, não resulta em adiam ento indefinido. Uma prova rigorosa de que o algoritm o nunca resulta em adiam ento indefinido é um a tarefa m ais com plicada (veja no site deste livro: “Curiosidades, Por que você deveria acreditar que seu software está funcionando corretam ente?”), que o leitor pode consultar na literatura disponível.16 R evuã o ' 1. Identifique o problem a fundam ental em cada um a das quatro tentativas de im plem entar exclusão mútua. 2. (V/F) Se o algoritm o apresentado na Figura 5.9 fosse modificado de m odo que os threads esperassem por períodos de tempos diferentes (por exem plo, T, espera de 0 a 0,2 segundo, enquanto T 2 espera de 0,5 a 0,7 segundo), esse algoritm o não sofreria adiam ento indefinido. R e ip o itã i: i ) Versão 1: requeria que T, entrasse prim eiro e dem andava alternância rígida. Versão 2: violava a exclusão mútua; am bos os threads podiam entrar em suas seções críticas ao mesmo tempo. Versão 3: habilitava os dois threads a Capítulo 5 Execução MsUicroHji concorrente, J£ J entrar em deadlock para que nenhum deles jam ais entrasse em sua seção crítica. Versão 4: perm itia a possibilidade (se bem que remota) de dois threads adiarem indefinidam ente um ao outro (se funcionassem em cascata). 2) Falso. O fato é que não se pode fazer nenhum a suposição quanto às velocidades relativas de threads assíncronos concorrentes. M esm o que os intervalos de tem po aleatórios pudessem ser diferentes, não poderiam os prever quão rapidam ente o restante do algoritm o executaria. 5.4.2 Algoritmo Peterson, O desenvolvim ento do Algoritm o de Dekker na seção anterior introduz alguns problem as delicados que surgem da sim ultaneidade e do assincronism o em sistem as de m ultiprogram ação. Durante m uitos anos esse algoritm o representou o que de m elhor havia em soluções de espera ociosa para im por exclusão mútua. Em 1981, G.L. Peterson publicou um algoritm o m ais simples para im por exclusão m útua de dois processos com espera ociosa (Figura 5 .1 1).17 Para ilustrarm os a correção do A lgoritm o de Peterson, vamos exam iná-lo no caso em que é executado pelo thread T r Antes de entrar em sua seção crítica, T I indica que quer fazer isso colocando HWantsToEnter em true (linha 15). Para evitar 1 S iste m a : 2 3 4 5 int favoredThread = 1; boolean t1 WantsToEnter = false; boolean t2WantsToEnter = false; 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 startThreadsO;// inicializa e lança ambos os threads T h re a d T j void m ain() { w h ile (ld o n e ) { t1 WantsToEnter = true; favoredThread = 2; while ( t2WantsToEnter && favoredThread == 2 ); // código da seção crítica 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 t1 WantsToEnter = false; // código fora da seção crítica } / / termine while } // termine Thread T1 T h re a d T ^ void m ain() { while (Id o n e ) { t2WantsTo Enter = true; favoredThread = 1; while ( t1 WantsToEnter && favoredThread == 1 ); 'ura, 5.11 Algoritmo de, Peterson,poro, exclusão mútuo, (porte, 1 de,2). 132 40 41 42 43 44 45 46 47 48 49 Sistemas operacionais // código da seção crítica t2WantsTo Enter = false; // código fora da seção crítica } / / termine while } // termine Thread T2 Figura, 5.11 Algoritmo d e Peterson,para, exclusão mútua, (parte, 2 de, 2). adiam ento indefinido, T I coloca favoredTliread em 2 (linha 1 6 ) , perm itindo que T 2 entre em sua seção crítica. Então fica em espera ociosa enquanto t2WantsToEnter for true e favoredíhread for 2. Se qualquer dessas condições tom ar-se falsa, T j poderá entrar em sua seção crítica com segurança (linha 2 0 ) . Após executar as instruções em sua seção crítica, T I coloca tlW antsíoEnter em false (linha 2 2 ) , indicando que concluiu sua seção crítica. A gora vam os considerar com o a preem pção afeta o com portam ento do thread T r Se não houver nenhum a disputa pela seção crítica quando o thread T, executar seu código de entrada de exclusão mútua, t2WantsToEnter será false quando o thread T, executar a linha 18; thread T, entra em sua seção crítica (linha 20). Considere o caso em que o thread T, sofre preem pção im ediatam ente após entrar em sua seção crítica. Com o o thread T 2 deve colocar favoredíhread em 1 (linha 3 7 ) , o teste que T2 executa na linha 3 9 fará que T 2entre em espera ociosa até que o thread T, tenha saído de sua seção crítica e colocado tlWantsToEnter em false. Contudo, se t2WantsToEnter for true quando o thread T, tentar entrar em sua seção crítica (linha 1 8 ) , então T 2 deve ter sofrido preem pção enquanto tentava entrar em sua seção crítica. Uma possibilidade é que T 2 tenha sofrido preem pção enquanto executava o código em sua seção crítica, o que significa favoredThread = 2 e t2W antsíoEnter = true. N esse caso, T, deve sim plesm ente espera ociosam ente na linha 1 8 até que T 2 conclua sua seção crítica e coloque t2WantsToEnter em false, causando assim a falha da condição em while na linha 1 8 e perm itindo que T, prossiga. Se o thread descobrir que t2WantsToEnter é true e favoredíhread é 2 na linha 1 8 , Tj esperará ociosam ente no seu laço while (linha 1 8 ) , porque tinha colocado favoredíhread em 2 im ediatam ente antes de executar a linha 1 8 . O thread T, esperará até que T 2obtenha novam ente o processador e coloque favoredíhread em 1 (linha 3 7 ) . Nesse ponto T2deve esperar ociosam ente porque tlW antsíoEnter é true e favoredíhread é 1. Quando thread retom ar o controle de um processador, executará o teste em seu laço while e entrará em sua seção crítica (linha 20). Se o thread T, descobrir que t2W antsíoEnter é true e favoredíhread é 1 na linha 1 8, poderá entrar com segurança em sua seção crítica, porque tlW antsíoEnter é true e favoredíhread é 1; o thread T 2deve esperar ociosam ente até que Tj conclua a execução de sua seção crítica e coloque tlW antsíoEnter em false. A gora darem os um a prova formal de que o Algoritm o de Peterson garante exclusão mútua. Faremos isso provando que T 2não pode executar enquanto T l esteja dentro de sua seção crítica. N ote que o algoritm o não muda se cada instância dos caracteres 1 e 2 forem alternadas. Conseqüentem ente, se provarmos que T2 não pode executar enquanto T, estiver dentro de sua seção crítica, tam bém terem os provado que T, não pode executar enquanto T 2 estiver dentro de sua seção crítica. Para iniciar a prova, observam os que o valor de favoredíhread é estabelecido im ediatem ente antes de um thread executar seu laço while. A lém do mais, cada thread coloca o valor em favoredíhread, para que o outro thread seja favorecido se am bos os threads quiserem entrar em suas seções críticas. E tam bém tlW antsíoEnter é controlado exclusivam ente pelo thread T,; sim ilarm ente, t2WantsíoEnter é modificado exclusivam ente pelo thread T2. A gora suponha que T l seja o único thread que está executando dentro de sua seção crítica — isso im plica que tlW antsíoEnter = true e que favoredíhread = 1 ou t2W antsíoEnter = false. Para T 2 entrar em sua seção crítica (linha 39), • tlW antsíoEnter deve ser false, o u • favoredíhread deve ser 2, o u • a m b o s , tlW antsíoEnter é false e favoredíhread é 2. Essa prova assum irá que T 2 entrou com sucesso em sua seção crítica enquanto T, executa dentro de sua seção crítica e m ostra que o Algoritm o de Peterson garante exclusão mútua, porque isso não pode ocorrer (ou seja, prova por contradição). No prim eiro caso (tlW antsíoE nter é false), T 2 entrou em sua seção crítica, porque tlW antsíoEnter é false e favoredíhread é 1 ou 2. Todavia, com o descrito anteriorm ente nesta seção, tlW antsíoEnter deve ser true se thread T, tam bém estiver executando dentro üipítulo 5 Execução MSÍKcrôHji concorrente J23 de sua seção crítica — a única vez que t l WantsToEnter é false é após T, ter saído de sua seção crítica (linha 22) e antes de tentar entrar nela novam ente (linha 1 5 ) . Assim , o thread T 2não podería ter entrado em sua seção crítica porque t l WantsToEnter era false. Isso im plica tam bém que o thread 2 não podería ter entrado em sua seção crítica dada a terceira condição ( t l WantsToEnter é false e favoredThread é 2). A gora precisam os m ostrar por contradição que T 2 não pode entrar em sua seção crítica porque favoredTTiread não pode ser colocado em 2 enquanto T, executa dentro de sua seção crítica. Para entrar em sua seção crítica, T 2 deve ter colocado t2WantsToEnter em true (linha 36), e favoredThread em 1 (linha 37) antes de sair do laço while na linha 39. Portanto, se o thread T2 executar em sua seção crítica enquanto o thread Tj executa em sua seção crítica, o valor de favoredThread deve ter mudado depois de T 2 ter executado a linha 37. N ote que a única vez em que favoredThread é colocado em 2 é quando T, executa a linha 16 do seu código de entrada em exclusão m útua, requerendo que T, saia de sua seção crítica. Note que o thread T 2já colocou t2WantsToEnter em true na linha 36. Conseqüentem ente, quando o thread Tj tentar entrar em sua seção crítica na linha 18, ficará em espera ociosa, porque t2WantsToEnter é true e favoredThread é 2. Em bora T2 possa entrar em sua seção crítica, agora Tj deve esperar até que T 2 saia de sua seção crítica. Isso contradiz a declaração de que am bos, T2 e T ,, estão executando dentro de suas seções críticas. Com o dem onstram os, por contradição, que Tj e T 2 não podem executar concorrentem ente dentro de suas seções críticas, provamos que o A lgoritm o de Peterson garante exclusão mútua. D eadlock e adiam ento indefinido são impossíveis no A lgoritm o de Peterson contanto que nenhum thread term ine ines­ peradamente. [Nota: Com o sempre, querem os dizer que deadlock e adiam ento indefinido não poderíam ser causados pelo código de entrada e saída de exclusão mútua. Não obstante, poderíam ocorrer, se os threads se com portassem mal em suas seções críticas]. Para ocorrer deadlock, T, e T 2 devem estar concorrentem ente em espera ociosa em seus laços while. Isso não ocorrerá, porque favoredThread está ou em 1 ou em 2 e não é modificado durante o laço while, o que significa que o teste while sem pre falhará para um dos threads, perm itindo que ele entre em sua seção crítica. Para ocorrer adiamento indefinido, um thread teria de poder concluir e entrar mais uma vez continuam ente em sua seção crítica enquanto o outro thread estivesse em espera ociosa. Com o cada thread coloca o valor de favoredThread no número correspondente ao outro thread antes de entrar no laço while, o Algoritmo de Peterson garante que os dois threads irão se alternar na execução de suas seções críticas, o que significa que não poderá ocorrer adiamento indefinido. RevUãty 1. Qual a m aior sem elhança existente entre o Algoritm o de D ekker e o A lgoritm o de Peterson? 2. Qual variável é necessária para evitar adiam ento indefinido? R eipoitài: i ) A m bos têm as m esm as três variáveis globais. 2 ) Rem over a variável favoredThread perm itiría a possibili­ dade de adiam ento indefinido. 5 .4 3 Exclusão PHÁtua/dbH/threaM: o algoritmo da,padaria, de, Lam port Dijkstra foi o prim eiro a apresentar um a im plem entação de primitivas de exclusão m útua para n threads (n-thread exclusion).ls¥Lnuth respondeu com um a solução que elim inava a possibilidade de adiam ento indefinido no algoritm o de Dijkstra, mas ainda perm itia que um processo sofresse (potencialm ente) um longo atraso.19Isso gerou um a série de esforços para descobrir algoritm os com atrasos mais curtos. Eisenberg e M cGuire apresentaram um a solução que garantia que um processo podería entrar em sua seção crítica em n- 1 tentativas.20 Lam port desenvolveu um a solução aplicável particular­ m ente a redes de com putadores (veja no site deste livro: “Biografia, Leslie Lam port”).210 algoritm o, que discutirem os detalhadam ente nesta seção, usa um sistem a do tipo ‘pegue um a ficha’, com o os utilizados em padarias muito m ovim en­ tadas; ele foi apelidado de Algoritmo da Padaria de Lamport. Bum s et al. oferecem um a solução para a exclusão m útua de n threads que usa um a única variável com partilhada.22 Carvalho e Roucairol discutem a im posição de exclusão m útua em redes de com putadores.23 Lamport foi o primeiro a apresentar um algoritmo que permite que os threads entrem rapidamente em suas seções críticas quando o acesso à seção crítica não for contestado (o que normalmente é o caso).24 Esses algoritmos de exclusão mútua rá­ pida tendem a sofrer de ineficiência quando a seção crítica é, de fato, um ponto de contenção. Anderson e Kim apresentam um algoritmo que permite entrada rápida em uma seção crítica na ausência de disputa, e um bom desempenho sob disputa.25 M uitas das prim eiras soluções para o problem a da exclusão m útua de n threads são difíceis de entender, porque reque­ rem um grande núm ero de variáveis com partilhadas e laços com plicados que determ inam se um thread pode entrar em sua seção crítica. O algoritm o de Lam port dá um a solução mais sim ples que tom a com o modelo um cenário do m undo real — esperar para ser atendido em um a padaria. Além do mais, o algoritm o de Lam port não requer que qualquer operação aconteça atomicamente. O algoritm o de Lam port é m odelado segundo uma padaria na qual um funcionário atende aos pedidos dos clientes no balcão; esse funcionário pode atender exatam ente um cliente por vez. Se houver apenas um cliente presente, a transação 134 S U tw u is o p e ra cio n a is será simples: o cliente faz o seu pedido, o funcionário pega as mercadorias, o cliente paga pelo que com prou e sai da pa­ daria. Entretanto, quando há m uitos clientes solicitando atendim ento concorrentem ente, o funcionário precisa determ inar em que ordem vai atendê-los. M uitas padarias atendem seus clientes na ordem ‘prim eiro a chegar, prim eiro a ser atendido’, solicitando que peguem um a ficha num erada em um distribuidor de fichas à entrada da padaria. As fichas são distribuídas em ordem ascendente (se a ficha corrente contiver um valor n y a próxim a terá um valor n+ 1). A pós cada transação o fun­ cionário atende o cliente cuja ficha tem o m enor valor numérico, o que garante que os clientes sejam atendidos na ordem ‘prim eiro a chegar, prim eiro a ser atendido’. A Figura 5.12 apresenta uma im plem entação do algoritm o de Lam port para n threads. No algoritm o de Lam port cada thread representa um cliente que deve ‘pegar um a ficha’ para determ inar quando o thread pode entrar em sua seção crítica; quando um thread tem um a ficha com o m enor valor num érico, ele pode entrar em sua seção crítica. A exclusão m útua é im posta reajustando-se o valor da ficha do thread quando ele sai da sua seção crítica. D iferentem ente de um distribuidor de fichas do mundo real, o algoritm o de Lam port perm ite que vários threads obtenham o m esm o núm ero de ficha. Como veremos, o algoritm o de Lam port inclui um m ecanism o de resolução de im passe que garante que som ente um thread por vez possa executar em sua seção crítica. As linhas 3-7 declaram dois vetores com partilhados entre todos os n threads que participam da exclusão mútua. O tam anho do vetor booleano choosing (linha 4 ) é n \ se o thread estiver no m om ento selecionando um valor de ficha, choosing[x] será true. Caso contrário, choosing[x] será false. O vetor de inteiros ticket (linha 7) contém valores correspondentes a cada ficha de thread. Sim ilar ao choosing, o valor da ficha do thread T x é contido em tic k e tfx ]. Nesse exemplo o valor inicial de cada ficha do thread é zero. 1 S iste m a : 2 3 4 5 6 7 8 9 10 11 // vetor que registra quais threads estão pegando uma ficha boolean choosingln]; // valor da ficha para cada thread inicializado em 0 int ticketln]; startThreads(); // inicialize e lance todos os threads. T h re a d Tx: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 void m ain() { x = threadN um berf); // armazene o número corrente do thread w h ile (ld o n e ) { / / pegue uma ficha choosinglx] = true; // inicie processo de seleção de ficha ticketlx] = maxValuef tic k e t) + 1; choosinglx] = false; // encerre processo de seleção de ficha // espere o número ser chamado comparando o corrente // valor da ficha com o valor da ficha de outro thread for ( int i = 0; i < n; i++) { if ( i == x ) { continue; // não é preciso verificar a própria ficha } / / term ine if // espere ociosamente enquanto threadli] está escolhendo while ( choosingli]!= false ); Figura, 5.12 Algoritmo dapodarias des Lamport (partes 1 des2). Capítulo S 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 Execução acsíncrona, concorrente, 135 // espere ociosamente até que o valor corrente da ficha seja o mais baixo while ( ticketli] != 0 && ticket[i] < tic k e t[x ]); // código de resolução de impasse favorece ficha de menor número if ( ticketli] == ticket[x] & & i < x ) // execute laço até threadli] sair de sua seção crítica while ( ticketli] ! = 0 ); // espere ociosamente } // termine for // código da seção crítica ticketlx] = 0; // exitMutualExclusion // código fora da seção crítica } / / termine while } // termine Thread TX Figurou 5.12 Algoritmo da,padaria, de, Lamport (parte, 2 de, 2). As linhas 13-54 representam o código executado pelo thread T x, um dos n threads que tentam executar suas seções críticas. Cada thread que participa do algoritm o da padaria executa as mesmas construções enterMutualExdusion (linhas 19-44) e exitMutualExclusion (linha 48). Q uando um thread é iniciado, ele executa a linha 15 que arm azena um valor inteiro na variá­ vel x para identificar exclusivam ente o thread. O thread usa esse valor para determ inar suas entradas correspondentes nos vetores choosing e ticket. Cada thread ‘pega um a ficha’ executando o código nas linhas 19-22. A linha 20 indica que o thread corrente está tentando pegar um a ficha, colocando choosingtx] em true. Com o logo verem os, essa etapa é necessária para garantir que a exclusão m útua seja im posta se vários threads determ inarem concorrentem ente os valores de suas fichas. O thread cham a o método maxValue (linha 21), que retom a o m aior valor do vetor de inteiros ticket. Então o thread som a um ao valor e o guarda com o seu valor de ficha, ticket[x] (linha 21). N ote que, se houver num erosos threads no sistema, o m étodo maxValue poderá dem orar um tempo substancial para executar, aum entando a probabilidade de o thread que cham ar maxValue sofrer preem pção antes que o método conclua. Depois que o thread designou seu valor de ficha em ticket[x] (linha 21), coloca choosingtx] em false (linha 22), indicando que não está m ais selecionando um valor de ficha. N ote que, quando um thread sai de sua seção crítica (linha 48), o valor da ficha é colocado em zero, o que significa que o valor da ficha de um thread é diferente de zero som ente se ele quiser entrar em sua seção crítica. D iferentem ente de um a padaria do m undo real, na qual o funcionário cham a o núm ero de cada cliente por vez para atendê-lo, o algoritm o da padaria requer que cada thread determ ine quando ele pode entrar na sua seção crítica (linhas 24-44). Antes de entrar em sua seção crítica, o thread precisa executar o laço for (linhas 2 6 -4 4 ) que determ ina o estado de todos os threads do sistema. Se o thread T , que é o thread a ser examinado, e o thread Tx, que é o thread que está execu­ tando o com ando, forem idênticos (linha 28), T r executará o com ando continue (linha 30), que pula os com andos restantes no corpo do laço for e passa diretam ente para increm entar i na linha 26. Caso contrário, T x determ ina se T. está escolhendo um valor de ficha (linha 34). Se T r não esperar até que T. tenha escolhido sua ficha antes de entrar em sua seção crítica, a exclusão m útua poderá ser violada. Para entender o porquê, vamos exam inar as outras duas condições testadas em cada iteração do laço for. A linha 37 testa se o thread corrente possui um valor de ficha m enor ou igual ao valor de ficha do thread que ele está exam inando. Essa condição é análoga à de um a padaria do m undo real — cada thread deve esperar até possuir o menor valor de ficha diferente de zero. Contudo, diferentem ente de um a padaria real, dois ou m ais threads do sistem a podem obter um a ficha com o mesmo valor. Por exemplo, considere um thread T a que sofreu preem pção depois de o m étodo maxValue retom ar e antes que o thread designe um novo valor para ticket[a] na linha 21. Se o próxim o thread que executar cham ar maxValue, o método retom ará o m esm o valor com o fez para Tq. Consequentem ente, qualquer um dos threads poderá obter o m esm o valor de ficha. N o caso de um empate, a linha 40 indica que o thread com o m enor identificador exclusivo prossiga antes. Voltemos à linha 34 para exam inar com o a exclusão m útua é violada se o thread T x não esperar caso T. esteja escolhendo um valor de ficha. Por exemplo, considere o que acontece se o thread T a sofrer preem pção após voltar do método maxValue, 136 S titw u u operncíôKAà mas antes de adicionar um ao valor da ficha (linha 21). Suponha, para esse exemplo, que maxValue retom e o valor 215. Após Ta sofrer preem pção, diversos outros threads executam seu código de entrada de exclusão mútua. Considere dois threads, T h e T , que executam após Ta sofrer preem pção e concluem o código de seleção de ficha (linhas 19-22), deixando o thread T h com a ficha de valor 216 (note que o valor da ficha de T a é correntem ente 0) e T . com a ficha de valor 217. É possível que conclua seu código de entrada de exclusão m útua (linhas 19-44), execute sua seção crítica (linha 46) e saia de sua seção crítica (linha 48) antes de Ta retom ar o controle de um processador. Também é igualm ente possível que T entre em sua seção crítica antes de T a recuperar o controle de um processador. Se T sofrer preem pção enquanto estiver executando código em sua seção crítica e T a retom ar o controle de um proces­ sador, T uconcluirá a instrução da linha 21 colocando o valor de sua ficha em 226, que é m ais baixo do que o valor de T c. Assim, T a podería executar seu código de entrada de exclusão m útua e entrar em sua seção crítica antes de Tr sair da sua seção crítica, violando a exclusão mútua. Por essa razão, T t deve esperar até que T. tenha concluído sua seleção de ficha (linha 34) antes de com parar os valores das fichas (linhas 36-43). Q uando T x tiver aplicado todos os seus testes para cada thread (linhas 28-43), será garantido o acesso exclusivo de à sua seção crítica. Q uando sair da seção, T ç colocará seu valor de ficha em 0 (linha 48) para indicar que não está mais executando em sua seção crítica nem tentando entrar nela. Além de ser um dos m ais sim ples algoritm os de exclusão m útua de n threads, o algoritm o da padaria de Lam port exibe diversas propriedades interessantes. Por exemplo, não requer que suas instruções sejam executadas atomicamente. Lem bre-se da Seção 5.3, “Im plem entação de primitivas de exclusão m útua”, que precisávam os que as instruções execu­ tassem atom icam ente, o que era necessário porque am bos os algoritm os, de D ekker e de Peterson, requerem m últiplos threads para modificar um a variável com partilhada para controlar o acesso às suas seções críticas. Se cada thread puder ler e m odificar essa variável sim ultaneam ente em diferentes processadores, os threads poderão ler valores inconsistentes de suas variáveis com partilhadas. Isso podería perm itir que os threads entrassem em suas seções críticas sim ultaneam ente, violando a exclusão mútua. Em bora muitas arquiteturas forneçam um pequeno conjunto de instruções atôm icas (veja a Seção 5.5, “Soluções de hardw are para o problem a da exclusão m útua”), é raro encontrar um sistema m ultiprocessador que ofereça hardw are para evitar que os threads leiam e escrevam dados sim ultaneam ente. O algoritmo da padaria de Lam port oferece uma solução elegante para a exclusão mútua em sistemas multiprocessadores, porque a cada thread é designado seu próprio conjunto de variáveis que controlam o acesso à sua seção crítica. Em bora todos os threads do sistem a com partilhem os conjuntos choosing[x] e ticket [ x ] , o thread é o único que pode modificar os valores de choosing[x] e tic k e t[x ]. Isso evita que os threads leiam dados inconsistentes, porque as variáveis que um thread exam ina enquanto está executando seu código de entrada de exclusão m útua não podem ser modificadas sim ultaneam ente por um outro thread. U m a outra propriedade interessante do algoritm o da padaria é que threads que estão à espera para entrar em suas seções críticas são adm itidos na ordem ‘prim eiro a chegar, prim eiro a ser atendido’ (First-Come-First-Served — FCFS) a menos que m últiplos threads tenham o mesmo valor de ficha. Por fim, o algoritm o de Lam port pode continuar a im por exclusão m útua mesmo que um ou m ais threads falhem, contanto que o sistem a coloque o valor de cada thread que falhou no vetor choosing em false e o valor de cada thread no vetor ticket em 0. D ada essa provisão final, o algoritm o da padaria de Lam port não pode sofrer deadlock nem adiam ento indefinido, um a propriedade particularm ente im portante em sistemas m ultiprocessadores e distribuídos, nos quais a falha de um dispositivo de hardware, com o um processador, não resulta necessariam ente em falha do sistema. R e tfiã o ' 1. D escreva por que a exclusão m útua de n threads pode ser difícil em um sistem a distribuído ou de rede. 2. O que aconteceria se o sistem a não executasse tarefas de lim peza com o colocar os valores da ficha em zero e valores choosing em false para threads term inados? 3. Suponha que m últiplos threads obtenham o mesmo valor de ficha. N a am ostra de código fornecida, o thread com o identificador exclusivo m ais baixo entraria em sua seção crítica prim eiro. A ordem em que esses threads entram em suas seções críticas é importante? R e ip a ifa i: i ) H á um a latência entre o envio de um a m ensagem por um com putador e o recebim ento dessa m ensagem pelo com putador receptor, o que significa que algoritm os de exclusão m útua devem considerar atrasos entre o m omento em que um thread modifica um a variável com partilhada e um outro thread tenta entrar em sua seção crítica. 2) Todo o sistem a podería sofrer adiam ento indefinido. Suponha que um thread term inasse enquanto estivesse escolhendo um número de ficha e, portanto, choosing para aquele thread ficaria colocado em true etem am ente. Outros threads que quisessem entrar na exclusão m útua ficariam esperando etem am ente que o thread term inado colocasse a entrada do vetor choosing em false. 3) A menos que o program ador queira designar prioridades para threads que tenham o mesmo valor de ficha, a ordem em que os threads com valores de ficha idênticos entram em sua seção crítica não importa. A s linhas 34 e 37 da Figura 5.12 Capítulo 5 Execução assUtcronO/ concorrente/ 127 asseguram que nenhum thread com um valor de ficha mais alto ou m ais baixo possa entrar em sua seção crítica antes dos threads de valores idênticos. O sistem a precisa som ente assegurar que cada thread com o mesmo valor de ficha eventual­ m ente entre em sua seção crítica. 5.5 Soluções hardware/para/ oproblema/ de/ exclusão m útuu Nos exemplos anteriores, as soluções de software para o problem a da exclusão m útua fizeram poucas conjecturas sobre o conjunto de instruções do sistem a e as capacidades do hardware. Com o discutim os no Capítulo 2, “Conceitos de hardware e software” , projetistas de hardw are tendem a im plem entar m ecanism os anteriorm ente manipulados por software para m elhorar o desem penho e reduzir o tempo de desenvolvim ento. Esta seção apresenta diversos m ecanism os oferecidos em hardw are que ajudam a resolver o problem a da exclusão mútua. S.S.1 VesabUÜMuio interrupções A razão pela qual primitivas de exclusão m útua são necessárias em um sistem a uniprocessador é, em grande parte, que a preem pção perm ite que m últiplos threads acessem dados com partilhados assincronam ente, o que pode resultar em erros de program ação. Threads em geral sofrem preem pção por interrupções por m eio de um relógio de interrupção (para sinalizar a expiração do quantum). Portanto, um m odo simples de im por exclusão m útua é desabilitar (ou m ascarar) interrupções. Infelizm ente, a desabilitação de interrupções im põe lim ites ao que o software pode fazer dentro de um a seção crítica. Por exem plo, um thread que entrar em um laço infinito em sua seção crítica, após desabilitar interrupções, nunca mais devolverá seu processador. Se o sistem a for uniprocessador, o sistem a operacional não poderá mais usar tem porizadores de interrupção para obter o controle do processador, significando que o sistem a ficará suspenso. Em sistem as de tempo real, com o o de controle de tráfego aéreo, esse resultado poderá pôr vidas hum anas em risco. D esabilitar interrupções não é um a solução viável para a exclusão m útua em um sistem a multiprocessador. Afinal, seu propósito é garantir que não ocorrerão preempções.Todavia, em um sistem a multiprocessador, dois threads podem executar ao mesmo tem po, cada um em um processador diferente. Se esses threads não forem sincronizados, a desabilitação de interrupções por si só não evitará que eles executem sim ultaneam ente dentro de suas seções críticas. Desse modo, apenas desabilitar interrupções em qualquer processador (ou em am bos) é insuficiente para im por exclusão mútua. Em geral, pro­ jetistas de sistemas operacionais evitam desabilitação de interrupções para fornecer exclusão mútua. Contudo, existe um conjunto lim itado de soluções no qual é ótim o para o núcleo desabilitar interrupções para código confiável cuja execução exija um curto período de tempo. (Consulte os estudos de caso Linux e W indows XP nos capítulos 20 e 21, respectivamente, para exemplos de com o sistem as operacionais atuais im põem exclusão m útua desabilitando interrupções.) Rertião' 1. (V/F) Se um thread entrar em laço infinito após desabilitar interrupções em um sistem a multiprocessador, o sistem a operacional não pode m ais executar. 2. Por que um thread deveria evitar requisitar bloqueio de E/S em uma seção crítica de um sistem a uniprocessador enquanto as interrupções estivessem desabilitadas? R d p o ílã i * 1) Falso. O sistema operacional pode executar em qualquer processador no qual as interrupções não estejam desabilitadas. O thread que entrou em laço infinito pode ser abortado ou reiniciado, mas quaisquer dados que ele com par­ tilhe com outros threads podem ficar em estado inconsistente, causando erros de programa. 2) Q uando um thread requisita bloqueio de E/S, o sistem a operacional coloca aquele thread no estado bloqueado até receber um evento de conclusão de E/S. U m a vez que esses eventos são gerados por interrupções de hardware, o sistema operacional nunca recebería esse sinal enquanto as interrupções perm anecessem desabilitadas. Conseqüentem ente o thread ficará esperando no estado bloqueado por um evento que jam ais receberá. Esse é um exemplo de deadlock que discutirem os no Capítulo 7. S.S.2 Instrução test-cuuíset Desabilitar instruções raram ente é um a solução prática para o problem a da sincronização, portanto, há outras técnicas, entre as quais a utilização de instruções especiais de hardware. Lem bre-se de nossos exemplos anteriores em que dados com partilhados ficam corrom pidos porque o sistem a pode causar a preem pção de um thread depois de ele ter lido o valor em um a localização de memória, mas antes que possa escrever um novo valor na localização. A instrução test-and-set (teste e atualize) habilita um thread a realizar essa operação atomicamente (indivisivelm ente).26,27 Tais operações tam bém são descritas com o operações de memória leia-modifique-escreva (read-modify-write — RMW) porque o processador lê um valor da m emória, modifica seu valor em seus registradores e escreve o valor modificado na m em ória sem interrupção.28 Os exem plos anteriores de software de exclusão m útua requeriam que um thread lesse um a variável para determ inar que nenhum outro thread estivesse executando um a seção crítica e, então, atualizasse um a variável conhecida com o variá- 138 S U tw u is o p e ra c io n a is vel de im p ed im en to para indicar que o thread estivesse executando um a seção crítica. A dificuldade de garantir acesso m utuam ente exclusivo a seções críticas em software era que o thread podia sofrer preem pção entre testar a disponibilidade de um a seção crítica e estabelecer um im pedim ento para evitar que outros threads entrassem em suas seções críticas. A instrução testAndSet elim ina a possibilidade de ocorrer preem pção durante esse intervalo. A instrução testAndSet! a, b ) funciona da seguinte maneira. Prim eiro ela l ê o valor de b , que pode ser true ou false. Depois, o valor é copiado para a e a instrução coloca o valor de b em true. A Figura 5 .1 3 m ostra com o um thread pode em pregar testAndSet para im por exclusão mútua. A variável booleana global occupied é true se qualquer dos threads estiver em sua seção crítica. Thread T, decide entrar em sua seção crítica baseandose em sua variável booleana local, plM ustW ait. Se plM ustW ait for true, T, terá de esperar, caso contrário o thread poderá entrar em sua seção crítica. O thread inicialm ente põe a variável plM ustW ait em true. Então cham a repetidam ente testAndSet em plM ustW ait e a variável booleana global occupied. Se T 2 não estiver em sua seção crítica, o valor de occupied será false. Nesse caso, testAndSet designa false para a variável plM ustW ait e põe occupied em true. O while falha nesse ponto e entra em sua seção crítica. Com o a instrução indivisível de hardw are colocou occupied em tru e, T 2não conseguirá entrar em sua seção crítica até que tj tenha recolocado occupied em false. A gora suponha que T 2 j á esteja em sua seção crítica quando T , quiser entrar. Nesse caso, occupied continua true durante repetidos testes while. Portanto, T ] continua esperando ociosam ente até que, eventualm ente, T 2 deixe sua seção crítica e 1 S iste m a : 2 3 4 5 boolean occupied = false; startThreads!); // inicialize e lance ambos os threads 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 T h re a d 7t; void m ain() { boolean p1 M ustW ait = true; while ( I d o n e ) { while ( p1 M u stW a it) { testAndSet( p1 MustWait, occupied ); } // código da seção crítica p1 MustW ait = true; occupied = false; // código fora da seção crítica }//te m in e while } // termine Thread T1 T h re a d T ^ ura, 5.13 Instrução testAndSet para, exclusão mútua, (porte, 1 de,2). Capítulo S 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 Execução assíncrona, concorrente, 139 void m ain() { boolean p2M ustW ait = true; while ( I d o n e ) { while ( p 2 M u stW a it) { testAndSet( p2MustWait, occupied ); } // código da seção crítica p2MustW ait = true; occupied = false; // código fora da seção crítica } / / termine while } // termine Thread T2 iauray 5 .1 3 Instrução testAndSet pura, exclusão nuctua, (parte 2 de 2). ponha occupied em false. Nesse ponto, testAndSet designa o valor de occupied em plM ustW ait, perm itindo assim que T j entre em sua seção crítica. Em bora testAndSet, do modo com o usada aqui, garanta exclusão mútua, a solução pode sofrer adiam ento infinito. E possível que um thread saia da sua seção crítica e execute um laço para cham ar testAndSet antes de o thread com petidor ter um a chance de executar novamente. Revilão' 1. O algoritm o da Figura 5.13 evita adiam ento indefinido? 2. ( V / F ) A instrução testAndSet im põe exclusão mútua. R eipoitãi: 1 ) Não, o algoritm o da Figura 5 .1 3 requer um a variável favoredProcess com o discutido na Seção 5 . 4 . 1 , “A lgo­ ritm o de Dekker” , para evitar adiam ento indefinido. 2) Falso. A instrução testAndSet é um a ferram enta que program adores usam para simplificar soluções de software para exclusão mútua, mas a instrução em si não im põe exclusão mútua. 5.53 Instrução Swap' Para simplificar o código de sincronização e m elhorar a eficiência do programa, a m aioria das arquiteturas fornece di­ versas instruções atômicas. Entretanto, cada arquitetura suporta um conjunto diferente dessas operações, significando que a instrução testAndSet pode não estar disponível para a aplicação ou para o program ador do sistema. N esta seção dem onstramos com o um a outra instrução que realiza um a operação de m em ória leia-modifique-escreva pode fornecer funcionalidade idêntica à instrução testAndSet. É com um que program as troquem , ou perm utem (sw ap), valores arm azenados em duas variáveis diferentes (consi­ dere, por exem plo, o algoritm o Quicksort). Em bora o conceito seja sim ples, na m aioria das linguagens de program ação de alto nível um a troca bem -sucedida de valores entre duas variáveis requer três instruções e a criação de um a variável tem porária: tem p = a; a = b; b = temp; Com o essas operações de perm uta (swapping) são realizadas regularmente, muitas arquiteturas suportam um a instrução sw ap que habilite um thread a trocar os valores de duas variáveis atomicamente. 140 SUtwuis operaciotuiti A instrução sw ap ( a, b ) ocorre da seguinte maneira: prim eiro a instrução carrega o valor de b, que pode ser ou true ou false, em um registrador temporário; depois o valor de a é copiado para b, e o valor do registro tem porário é copiado para a. A Figura 5.14 m ostra com o um thread pode em pregar a instrução swap para im por exclusão mútua. Semelhante à Figura 5.13, a variável booleana global occupied é true se qualquer dos threads estiver em sua seção crítica. O thread T, decide entrar em sua seção crítica baseando-se em sua variável booleana local, plM ustW ait. Similarmente, o thread T 2 decide entrar em sua seção crítica com base na sua variável p2MustWait. Note que a instrução swap pode ser usada intercam biavelm ente com a instrução testAndSet nesse algoritmo. A única diferença entre a Figura 5.13 e a 5.14 é que criam os um a ‘via rápida’ para a seção crítica na qual o controle da seção pode ser obtido pela execução de um a instrução a menos (ou seja, testando a condição de laço após a instrução swap). 1 S iste m a : 2 3 4 5 booleana occupied = false; startThreads(); // inicialize e lance ambos os threads 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 T h re a d 7t; void m ain() { boolean p1 M ustW ait = true; while ( I d o n e ) { do { swap( p1 MustWait, occupied ); } while ( p1 M u s tW a it); // código da seção crítica 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 p1 MustW ait = true; occupied = false; // código fora da seção crítica } / / termine while } // termine Thread T 1 T h re a d T f void m ain() { boolean p2M ustW ait = true; while ( I d o n e ) { do { urO/ 5.14 Instrução swap para, excUucio nuÁtu/o (parte’ 1 d e 2). Capitulo 5 41 42 43 44 45 46 47 48 49 50 51 52 53 Execução assíncrona, concorrente, 141 swap( p2MustWait, occupied); } while ( p2M ustW a it); // código da seção crítica p2M ustW ait = true; occupied = false; // código fora da seção crítica } / / termine while } / / termine Thread T2 Fujurcc S. 14 Instrução swap para, exclusão mútua, (parte, 2 de,2). R e rtiã o ' 1. Por que podería ser mais provável um a instrução swap estar em um sistem a do que um a instrução testAndSet? R e ip a itã i: i ) M uitos algoritm os requerem algum tipo de perm uta (swapping), portanto uma instrução de hardware swap é muito útil para algoritm os além das que só fazem exclusão mútua. 5.6 Semáforos Outro m ecanism o que um sistem a pode fornecer para im plem entar exclusão m útua é o semáforo, com o descrito por Dijkstra em seu profundo trabalho sobre processos seqüenciais cooperativos (veja no site deste livro: “Biografia, Edsger W. D ijkstra”)-29 U m sem áforo contém um a variável protegida cujo valor (um núm ero inteiro), um a vez inicializado, pode ser acessado e alterado por apenas um a de duas operações, P e V. [Nota: P e V são abreviaturas das palavras holandesas proberen, que significa ‘testar’, e verhogen, que significa ‘increm entar’]. Um thread cham a a operação P (também deno­ m inada operação esperar [wait]) quando quiser entrar em sua seção crítica, e cham a a operação V (tam bém denom inada operação sinalizar [sign]) quando quiser sair de sua seção crítica. Antes de um sem áforo poder ser usado para sincroni­ zação, ele deve ser inicializado. A inicialização configura o valor da variável protegida para indicar que nenhum thread está executando em sua seção crítica e tam bém cria um a fila que arm azena referências a threads, que estão esperando para entrar em suas seções críticas protegidas por aquele semáforo. N ote que P e V são apenas abstrações que encapsulam e ocultam detalhes de im plem entações de exclusão mútua. Essas operações podem ser aplicadas a um sistem a com qualquer núm ero de threads cooperativos. 5.6.1 Exclusão mútuso com semáforos A Figura 5.15 dem onstra com o a exclusão m útua é im posta usando um semáforo. O sistem a inicializa o semáforo occupied em l ; esses sem áforos são denom inados semáforos binários. A quele valor indica que um a seção crítica está disponível. O program a da Figura 5.15 usa as operações P e V com o as primitivas enterMutualExdusionO e ex9M ufualExdusion() da Seção 5.2.3, “Primitivas de exclusão m útua”. Q uando um thread quiser entrar em um a seção crítica protegida por um semáforo S, ele cham ará P(S), que operará da seguinte maneira: Se S > 0 S = S - 1 Senão 0 thread que está chamando é colocado na fila de threads à espera no semáforo Com o a Figura 5.15 inicializa o valor do sem áforo em 1, som ente um thread receberá perm issão para entrar na seção por vez. Quando esse thread cham ar P , o valor do sem áforo será reduzido para 0. Quando um outro thread cham ar P, aquele thread será bloqueado. Após um thread term inar de executar sua seção crítica, ele cham a V(S). Essa operação ocorre da seguinte maneira: 142 S istem as o ^e ro c io n o is 1 S iste m a : 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // crie semáforo e inicialize valor em 1 Semaphore occupied = new SemaphoreO); startThreadsf); // inicialize e lance ambos os threads T h re a d Tx: voidm ainO { w h ile (ld o n e ) { P( occupied ); // espere // código da seção crítica V( occupied ); // sinalize // código fora da seção crítica } //te rm in e while } // Thread TX Figurcu 5. 15 Exjdusáo mútuo, com, semáforos. S e h o u v e r th r e a d s e s p e r a n d o e m S R e t o m e o ' p r ó x i m o ' t h r e a d à e s p e r a n a fila d o s e m á f o r o S en ão S = S + 1 Assim, se houver threads à espera no sem áforo, o ‘próxim o’ thread, que depende da im plem entação do semáforo, executará. Senão, o valor de S será increm entado, perm itindo que m ais um thread entre em sua seção crítica. U m a im plem entação adequada de sem áforo requer que P e V sejam operações indivisíveis. E tam bém , se vários sem á­ foros tentarem um a PfSjsim ultaneam ente, a im plem entação deverá garantir que som ente um thread tenha perm issão para prosseguir. Os outros threads ficarão esperando, mas a im plem entação de P e V pode garantir que não sofrerão adiam ento indefinido. Por exemplo, quando um thread fica bloqueado em um semáforo, o sistem a pode pôr aquele thread em uma fila associada com o semáforo. Q uando um outro thread cham ar P , o sistem a poderá selecionar um dos threads da fila para ser liberado. Adm itirem os um a disciplina de enfileiram ento do tipo ‘prim eiro a entrar, prim eiro a sair’ para threads bloqueados em um sem áforo (para evitar adiam ento indefinido). R e rfiã o ' 1. O que podería potencialm ente acontecer se um thread cham asse a operação V sem ter cham ado a P ? 2. O que podería potencialm ente acontecer se threads bloqueados em um sem áforo não saíssem da fila na ordem ‘prim eiro a entrar, prim eiro a sair’? ReifJOitài: 1) Uma das possibilidades é o sem áforo estar inicialm ente em 1 e não haver nenhum thread à espera. A operação V increm enta o valor do sem áforo para 2. Agora, dois threads usando P poderíam entrar em suas seções críticas. 2) Um thread podería sofrer adiam ento indefinido. 5.6.2 SuvcroKÍzAçã/> (LetkreeuU com semáforos N a seção anterior vim os com o um program a pode usar um sem áforo para proteger o acesso a um a seção crítica. Sem á­ foros tam bém podem ser usados para sincronizar dois ou mais threads concorrentes. Por exemplo, suponha que um thread T, queira ser notificado da ocorrência de um evento particular. Suponha que algum outro thread, T 2, seja capaz de detectar que esse evento ocorreu. Para sincronizar esses dois threads, T, executa algum as instruções prelim inares e, então, cham a Capítulo 5 Execução assUteroKeeconcorrente' J43 P em um sem áforo que foi inicializado em 0, fazendo T, ficar bloqueado. Eventualm ente T 2 executa V para sinalizar que o evento ocorreu, o que perm ite que T, prossiga (com o sem áforo ainda em zero). Esse m ecanism o acontece m esm o que T2 detecte o evento e o sinalize com V antes de T, esperar pelo evento cham ando P. O sem áforo terá sido increm entado de 0 para 1, portanto, quando T, cham ar P, a operação sim plesm ente decrem entará o sem áforo de 1 para 0, e prosseguirá sem esperar pelo evento. Um exemplo de sincronização de threads é o relacionam ento produtor/consum idor apresentado na Seção 5.2.1, “Estudo de caso de Java multithread, Parte II” . A Figura 5.16 mostra com o im plem entar esse relacionam ento com semáforos. Ambos os threads com partilham um a variável denom inada sharedValue. O produtor gera valores e os designa a essa variável, e o consum idor recupera e processa os valores que o produtor coloca nessa variável. Cada thread pode ter de esperar que um evento ocorra antes de poder cum prir sua tarefa. O consum idor pode ter de esperar que um valor seja produzido (indicado pelo produtor que sinaliza o sem áforo valueProduced); o produtor deve esperar que um valor produzido anteriorm ente seja consum ido (indicado pelo consum idor que sinaliza o sem áforo valueConsumed). A im plem entação de cada thread é direta. O produtor gera um novo valor (linha 1 7 ) e espera no sem áforo valueConsumed (linha 1 8 ). O valor do sem áforo inicialm ente é 1 (linha 4 ) , portanto o produtor designa o valor recém -criado nextValueProduced à variável com partilhada sharedValue (linha 1 9 ). Então o produtor sinaliza o sem áforo valueProduced (linha 2 0 ) . O consum idor espera nesse sem áforo (linha 3 4 ) e, quando o produtor sinalizar valueProduced (linha 2 0 ) , o consum idor designa a variável com partilhada sharedValue a uma variável local nextValueConsumed (linha 3 5 ) . O consum idor então sinaliza o sem áforo valueCon­ sumed (linha 3 6 ) , que perm ite que o produtor crie um valor e assim por diante. Os semáforos asseguram acesso m utuam ente exclusivo à variável com partilhada sharedValue e garantem que os threads se alternem para que o consum idor sempre leia o valor que o produtor acabou de criar. 1 2 3 4 5 S iste m a : // semáforos que sincronizam acesso a sharedValue Semaphore valueProduced = new Semaphore(O); Semaphore valueConsumed = new SemaphoreO); int sharedValue; // variável compartilhada por produtor e consumidor 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 startThreadsf); // inicialize e lance ambos os threads T h re a d P ro d u to r: void m ain() { int nextValueProduced; // variável para armazenar o valor produzido w h ile (ld o n e ) { nextValueProduced = generateTheValuef); // produza valor P( valueConsumed ); // espere até o valor ser consumido sharedValue = nextValueProduced; // seção crítica V( valueProduced ); // sinalize que o valor foi produzido 21 22 23 24 25 26 27 28 29 30 31 32 33 } / / termine while } // temine thread produtor T h re a d C o n s u m id o r: void m ain() { int nextValue; // variável para armazenar o valor consumido while (Id o n e ) { urO/ 5.16 Relacionamento produtor/consumidor implementado couv semáforos (porte' 1 de, 2). 144 34 35 36 37 38 39 40 41 S is te m a s o p e ra c io tu u s P( valueProduced ); // espere até o valor ser produzido nextValueConsumed = sharedValue; // seção crítica V( valueConsumed ); // sinalize que o valor foi consumido processTheValuef nextValueConsumed ); // processe o valor } / / termine while } // termine thread consumidor Figura, 5. 16 | RjdacioKAMieKto produtor/consumiAor implementado com, semáforos (porte, 2 de, 2). RevU cur 1. (V/F) Um thread pode estar em apenas um a fila de espera de um sem áforo por vez. 2. O que acontece se o sem áforo valueProduced for inicializado em um valor 1 em vez de um valor 0 ? R e ip o ifa i: i ) Verdadeiro. Um thread é bloqueado quando colocado na fila de threads à espera em um semáforo, o que significa que ele não pode executar código que estiver esperando em qualquer outro semáforo. 2) O consum idor poderia potencialm ente consum ir um valor antes que o produtor o produzisse. 5.6.3 Semáforos contadores Um se m á fo ro c o n ta d o r (tam bém denom inado se m á fo ro g e ra l) é aquele que é inicializado em um valor inteiro m aior do que zero e com um ente m aior do que um . Um sem áforo contador é particularm ente útil quando o recurso a ser alocado pertence a um conjunto de recursos idênticos. O sem áforo é inicializado para o núm ero de recursos existente no conjunto. C ada o peração P decrem enta o sem áforo de 1, indicando que um outro recurso foi rem ovido do conjunto e está em uso por um thread. C ada operação V increm enta o sem áforo de 1, indicando que um thread devolveu um recurso ao conjunto e que este recurso pode ser realocado a outro thread. Se um thread tentar um a operação P quan­ do o sem áforo fo r decrem entado para zero, ele deverá esperar até que o recurso seja devolvido ao conjunto por um a operação V. RevUcur 1. Descreva com o im plem entar um sem áforo binário com um sem áforo contador. 2. (V/F) A operação V de um sem áforo contador sem pre adiciona 1 à contagem. R eipo& tãí: i ) É só inicializar o sem áforo contador para um valor de um. 2) Falso. Se um ou m ais threads estiverem esperando, V deixa um dos threads prosseguir e não increm enta a contagem. 5.6.4 Implementação de,semáforos Sem áforos podem ser im plem entados em aplicações de usuário e no núcleo. Dado o algoritm o de Dekker ou a dispo­ nibilidade da instrução de m áquina testAndSet ou swap, im plem entar P e V com espera ociosa é um a operação direta. Porém, espera ociosa desperdiça ciclos de processador que poderíam ser m ais bem usados em um sistem a de m ultiprogramação. No Capítulo 3, “Conceito de processos”, estudam os o m ecanism o de alternância de estado de thread im plem entado no núcleo. N otam os que um thread que requisitar um a operação E/S bloqueia-se voluntariam ente e tom a-se dependente da conclusão de E/S. O thread bloqueado não espera ociosam ente — fica adorm ecido até que o sistem a o acorde e o transfira para a lista de prontos. Para evitar espera ociosa, podem -se im plem entar operações de sem áforo no núcleo por meio de bloqueio de threads à espera.30 Um sem áforo é im plem entado com o um a variável protegida e um a fila na qual threads podem esperar por ope­ rações V. Quando um thread tenta um a operação P em um sem áforo cujo valor é zero, o thread entrega o processador e bloqueia-se para esperar um a operação V no semáforo. O sistem a coloca o thread na fila de threads que esperam naquele semáforo. (Supom os um a disciplina de enfileiram ento ‘prim eiro a entrar, prim eiro a sair’. Outras disciplinas têm sido investigadas.)31 Então o sistem a designa novam ente o processador ao próxim o thread pronto. O thread que está à espera na fila do sem áforo eventualm ente passa para o início da fila. U m a operação V subseqüente remove o thread da fila do sem áforo e o coloca na lista de prontos.32 Capítulos Execução MSÍKcrona, concorrente, J45 É claro que threads que tentam operações P e V sim ultâneas em um sem áforo precisam ter acesso exclusivo ao semáforo garantido pelo núcleo. No caso de sistem as uniprocessadores, pelo fato de P e V serem tão curtos, sua indivisibilidade pode ser assegurada sim plesm ente desabilitando interrupções enquanto as operações P e V estiverem em execução. Isso impede que o processador seja usurpado até a operação ser concluída (ponto em que as interrupções são novam ente ha­ bilitadas), mas deve ser feito com cuidado, ou pode levar a mau desem penho ou até a deadlock (veja no site deste livro: “Curiosidades, Requisitos am bíguos”). No núcleo de um sistem a m ultiprocessador, um dos processadores pode receber a incum bência de controlar a lista de prontos e determ inar quais processadores executam quais threads.33 U m a outra abordagem da im plem entação de um núcleo para um sistem a m ultiprocessador é controlar o acesso (via espera ociosa) a um a lista com partilhada de prontos.34 Um núcleo de sistem a operacional distribuído pode designar um processador para controlar a lista de prontos, mas, em geral, cada processador gerencia sua própria lista de prontos e, essencialm ente, tem seu próprio núcleo.35,36,37,38 Quando um thread m igra entre vários processadores de um sistem a dis­ tribuído, o controle daquele thread é passado de um núcleo para outro. R evu ã o ' 1. Cite um grande benefício da im plem entação de sem áforos no núcleo. 2. Imagine que um sem áforo perm ita que o thread de prioridade m ais alta prossiga quando V for chamada. Qual o problem a potencial que isso pode causar? R u p o à fa i: i ) Sem áforos podem evitar espera ociosa. O núcleo pode suspender um thread que tentar um a operação P quando o valor corrente do sem áforo for 0 e levá-lo de volta à fila de prontos quando um a operação V for cham ada, o que pode m elhorar o desem penho. 2) Threads em um a fila de espera de sem áforo podem ser indefinidam ente adiados por threads de prioridade m ais alta. Kestmto Q uando existir m ais de um thread em um sistem a ao m esm o tempo, diz-se que os threads são concorrentes. Dois threads concorrentes podem executar independentem ente um do outro ou podem executar cooperativamente. Diz-se que processos que operam independentem ente um do outro, contudo, de quando em quando, devem se com unicar e se sincronizar para executar tarefas cooperativas executam assincronam ente. Q uando um thread lê dados que um outro thread está escrevendo ou quando um thread escreve dados que um outro thread tam bém está escrevendo, podem ocorrer resultados indeterminados. Podemos resolver esse problem a conceden­ do a cada thread acesso exclusivo à variável com partilhada. Enquanto um thread increm enta a variável com partilhada, todos os outros threads que desejam fazer o m esm o terão de esperar. Essa operação é denom inada exclusão mútua. Quando o thread que está em execução term inar de acessar a variável com partilhada, o sistem a perm itirá que um dos processos à espera prossiga. Essa operação é denom inada serialização do acesso à variável com partilhada. D essa m a­ neira, threads não poderão acessar dados com partilhados sim ultaneam ente. Em um relacionam ento produtor/consum idor, o thread produtor gera dados e os arm azena em um objeto com ­ partilhado, e o thread consum idor lê dados de um objeto com partilhado. D em onstram os neste capítulo com o podem surgir erros de lógica com acesso não sincronizado de m últiplos threads a dados com partilhados — dados podem ser perdidos se o produtor colocar novos dados no buffer com partilhado antes que o consum idor consum a os dados anteriores; e dados podem ser incorretam ente duplicados se o consum idor consum ir dados novam ente antes que o produtor produza o próxim o valor. Se essa lógica fizesse parte de um a aplicação de controle de tráfego aéreo, vidas hum anas poderíam estar em risco. E xclusão m útua precisa ser im posta som ente qu an ­ do threads acessam dados m odificáveis com partilhados — quando estão executando operações que não conflitam um as com as outras (lendo dados), o sistem a deve perm itir que os threads executem concorrentem ente. Q uando um thread acessa dados m odificáveis com partilhados, diz-se que está em um a seção crítica (ou região crítica). Para evitar os tipos de erros que encontram os anteriorm ente, o sistem a deve garantir que som ente um thread por vez pos­ sa executar instruções na sua seção crítica. Se um thread qualquer tentar entrar em sua seção crítica enquanto outro estiver executando sua própria seção crítica, o prim eiro deverá esperar até que o thread que está em execução saia de sua seção crítica. A ssim que um thread sair da sua seção crítica, o thread que esteja esperando (ou um dos threads à espera, se houver vários) poderá entrar e executar sua seção crítica. Se um thread que estiver dentro de um a seção crítica terminar, voluntária ou involuntariam ente, o sistem a operacional, ao realizar sua lim peza final, deverá liberar a 146 S titw u u operncíôKAà exclusão m útua para que outros threads possam entrar em suas seções críticas. D iscutim os as primitivas enterMutualExclusionf) e exitM utualExdusionO que invocam as operações m ais fundam entais inerentes à exclusão m útua. Essas prim itivas exibem as seguintes propriedades: cada instrução em linguagem de m áquina é executada indivisivelmente; não se faz nenhum a suposição sobre as velocidades relativas de threads assíncronos concorrentes; um thread que estiver executando instruções fora da sua seção crítica não poderá evitar que quaisquer outros threads entrem em suas seções críticas; e um thread não deve ser im pedido indefinidam ente de entrar em sua seção crítica. U m a elegante im plem entação de software de exclusão m útua foi apresentada pela prim eira vez por Dekker. A com ­ panhamos o desenvolvim ento de Dijkstra para o Algoritmo de Dekker que fornece exclusão m útua para dois threads e, ao m esm o tem po, aborda os problem as da espera ociosa, sincronização intertravada; deadlock e adiam ento indefini­ do. Em seguida, discutim os algoritm os mais sim ples e mais eficientes desenvolvidos por G. L. Peterson e L. Lamport. O A lgoritm o da Padaria de Lamport, projetado para siste­ mas distribuídos, dem onstra um algoritm o de softw are de exclusão m útua para n threads, que é válido para sistemas m ultiprocessadores e não requer que sua operação seja rea­ lizada atomicamente. Vários m ecanism os de hardw are foram desenvolvidos para ajudar a exclusão mútua. Um modo simples de impor exclusão mútua usando hardware é desabilitar (ou mascarar) interrupções. Essa solução é benéfica por sua simplicidade; contudo, desabilitar interrupções pode ser desastroso se um thread se com portar mal em um a seção crítica. Além dis­ so, desabilitar interrupções não é um a solução viável para exclusão m útua em um sistem a multiprocessador. Foram desenvolvidas outras técnicas de hardware, entre elas a uti­ lização de instruções especiais de hardware. As instruções test-and-set e swap habilitam um thread a executar opera­ ções atôm icas de m em ória do tipo ler-modificar-escrever (Reaã-M odify-W rite - RM W ). Essas instruções elim inam a possibilidade de preem pção entre a instrução que determ ina se um thread pode entrar em sua seção crítica e a instrução que configura um a variável para indicar que nenhum thread pode entrar na seção crítica. Um outro m ecanism o de exclusão m útua são os sem áfo­ ros, com o descrito por Dijkstra. Um sem áforo contém uma variável protegida cujo valor (um núm ero inteiro), um a vez inicializado, pode ser acessado e alterado somente chamando um a de duas operações, P e V. Um thread cham a a operação P (também denominada operação esperar [wait]) quando qui­ ser entrar em sua seção crítica; um thread cham a a operação V (também denom inada operação sinalizar [sign]) quando quiser sair de sua seção crítica. Antes de um sem áforo poder ser usado para sincronização, ele deve ser inicializado. A inicialização configura o valor da variável protegida para indicar que nenhum thread está executando em sua seção crí­ tica. Um semáforo contador (também denom inado semáforo geral) pode ser inicializado em um valor inteiro maior do que um. Semáforos contadores são particularm ente úteis quando os recursos devem ser alocados por m eio de um conjunto de recursos idênticos. Semáforos podem ser implementados em aplicações de usuário e no núcleo. Dado o Algoritm o de D ekker ou a disponibilidade de uma instrução de m áquina testÀndSet ou swap, implementar P e V com espera ociosa é uma operação direta. Contudo, espera ociosa desperdiça ciclos de processador que poderíam ser mais bem usados em um sistema de m ultiprogram ação. Operações de sem áforo tam ­ bém podem ser im plem entadas no núcleo para evitar espera ociosa bloqueando threads em espera. Exercícios 5.1 Cite diversas razões por que o estudo da concorrência é apro­ priado e importante para estudantes de sistemas operacionais. 5.2 Explique por que a seguinte afirmativa é falsa: quando di­ versos threads acessam informações compartilhadas na memória principal, a exclusão mútua deve ser imposta para evitar a produção de resultados indeterminados. 5.3 O algoritmo de Dekker, as instruções testÀndSet e swap e as operações de semáforo P e V podem ser usados para impor exclu­ são mútua. Quais as diferenças e semelhanças entre esses diversos esquemas? Considere suas respectivas vantagens e desvantagens. 5.4 Quando dois threads tentam simultaneamente implementar enterMutualExdusion (), admitimos que o ‘vencedor’ é selecionado alea­ toriamente. Discuta as ramificações dessa premissa. Apresente um método melhor. Discuta como tal método podería ser implementado em um sistema multiprocessador no qual diversos threads pudessem de fato tentar enterMutualExclusionf) exatamente no mesmo instante. 5.5 Comente a utilização de primitivas de exclusão mútua na Figura 5.17. 5.6 Qual o real significado do Algoritmo de Dekker? 5.7 No Algoritmo de Dekker (Figura 5.10) é possível que T2saia de sua seção crítica, execute seu código de saída de exclusão mútua, execute seu código de entrada de exclusão mútua e entre novamente em sua seção crítica antes de T, ter a chance que está esperando para entrar em sua própria seção crítica. T2podería reentrar em sua própria seção crítica muitas vezes antes de T, ter uma chance? Se puder, explique exatamente como isso podería acontecer e indique se essa situação é um exemplo de adiamento indefinido. Se não puder acontecer, explique exatamente como deve ser evitado. 5.8 Explique como o exemplo de programa concorrente que impõe exclusão mútua com testÀndSet (Figura 5.13) podería levar a adiamento indefinido. Indique por que, ainda assim, essa pos­ sibilidade seria muito improvável. Sob quais circunstâncias seria aceitável usar a técnica de exclusão mútua? Sob quais circunstân­ cias seria totalmente inaceitável? 5.9 Faça uma análise exaustiva do Algoritmo de Dekker. Ele tem alguma fraqueza? Se não tiver, explique por quê. 5.10 A solução para a exclusão mútua de n threads apresentada por Eisenberg e McGuire39 garante que qualquer projeto isolado Capítulos 1 Execução axsUicrôHji concorrente, J47 // execute instruções fora de uma seção crítica 2 3 4 5 enterMutualExclusionf); // execute instruções dentro de uma seção crítica 6 7 8 9 10 11 12 13 14 15 16 17 enterMutualExclusionf); // execute instruções dentro de uma seção crítica aninhada exitMutualExclusionf); // execute instruções dentro de uma seção crítica exitMutualExclusionf); // execute instruções fora de uma seção crítica F igura/ 5 .1 7 Código para/ o Exercício S.S. entrará em sua seção em n- 1 tentativas no pior caso. Poderiamos esperar um desempenho melhor com n processos? 5.11 Primitivas de exclusão mútua podem ser implementadas com espera ociosa ou com bloqueio. Discuta a aplicabilidade e os méritos relativos de cada abordagem. 5.12 Explique detalhadamente como semáforos binários e ope­ rações de semáforo binário podem ser implementados no núcleo de um sistema operacional. 5.13 Explique como a habilitação e a desabilitação de interrupções são úteis na implementação de primitivas de exclusão mútua em sistemas uniprocessadores. 5.14 Mostre como implementar operações de semáforo com testAndSet. 5.15 Alguns computadores têm uma instrução swap que, como a testAndSet, simplifica a implementação de primitivas de exclusão mútua. A instrução swap apenas troca os valores de duas booleanas 1 e, por isso, requer uma área de retenção temporária; a instrução swap é executada indivisivelmente. a. Expresse swap como um cabeçalho de procedimento em uma linguagem de alto nível. b. Mostre como o seu procedimento swap (assumindo que seja executado indivisivelmente) pode ser usado para implementar as primitivas enterMutualExclusionf) e exitMutualExdusionf). 5.16 Como mencionado no capítulo, seções críticas que se referem a conjuntos de variáveis compartilhadas que não se interceptam, na verdade, podem ser executadas simultaneamente. Suponha que as primitivas de exclusão mútua sejam modificadas para incluir uma lista de parâmetros das variáveis compartihadas particulares que serão referidas na seção crítica. a. Comente a utilização dessas novas primitivas de exclusão mútua da Figura 5.18. // execute instruções fora de uma seção crítica 2 3 4 5 enterMutualExclusionfa); // execute instruções em uma seção crítica 6 7 enterMutualExclusionfb); 8 9 10 11 12 13 14 15 16 17 // execute instruções em uma seção crítica aninhada exitMutualExclusionfb); // execute instruções em uma seção crítica exitMutualExclusionfa); // execute instruções fora de uma seção crítica1 8 18 Noims p rim itü n is de, exclusão m útua,para, o Exercício S. 1€(d). 148 S U tw u is o jte ra c io fu iti b. Suponha que os dois threads da Figura 5.19 operem concorrentemente. Quais os possíveis resultados? 5.17 No Algoritmo de Dekker, o que aconteceria (se é que algo aconteceria) se as duas instruções de atribuição do código de saída da exclusão mútua fossem invertidas? 5.18 Mostre que o Algoritmo de Peterson (Figura 5.11) é jus­ tamente limitado (boutided fa iP 0), ou seja, um thread não pode ser atrasado indefinidamente em qualquer condição de atraso que ocorra com repetição indefinida. Em particular, mostre que qualquer thread que esteja à espera para entrar em sua seção crítica será atrasado por não mais do que o tempo que o outro thread demora para entrar e sair de sua própria seção crítica uma vez. 5.19 Apresente uma análise detalhada do Algoritmo de Peterson para demonstrar que funciona adequadamente. Em particular, mos­ tre que não pode ocorrer deadlock, que não pode ocorrer adiamento indefinido, e que a exclusão mútua é imposta com sucesso. 5.20 Mostre que, se um sistema que implemente o Algoritmo da padaria de Lamport não fizer a limpeza final, poderá sofrer adiamento indefinido. 5.21 Tendo como base o que você sabe sobre núcleo e tratamento de interrupções, descreva como operações de semáforo podem ser implementadas em um sistema uniprocessador. 5.22 No capítulo demos a entender que a espera ociosa pode ser desperdiçadora. Ela é sempre assim? Quais as alternativas exis­ tentes? Discuta os prós e os contras da espera ociosa. 5.23 Se muitos threads tentarem uma operação P> qual deles deve obter permissão para prosseguir? Quais as principais questões nesse caso? Quais critérios você podería utilizar para decidir qual thread deve prosseguir em um sistema uniprocessador? Quais critérios você podería utilizar em um sistema multiprocessador? 5.24 Um sistema suporta apenas semáforos binários. Mostre que semáforos contadores podem ser simulados nesse sistema usando semáforos binários. 5.25 Um requisito da implementação de uma P e V é que cada uma dessas operações deve ser executada indivisivelmente; ou seja, uma vez iniciada, cada operação executa até a conclusão, sem interrupção. Dê um exemplo de uma situação simples em que, se essas operações não fossem executadas indivisivelmente, a exclusão mútua podería não ser imposta adequadamente. 5.26 Suponha que a única primitiva de exclusão mútua fornecida por threads de usuário seja um comando que desabilite interrupções para as próximas 32 instruções e reabilite interrupções. Explique os benefícios e desvantagens dessa abordagem. 5.27 Como threads cooperativos implementam primitivas de exclusão mútua no sistema mencionado no exercício anterior? 5.28 O código da Figura 5.20 fornece exclusão mútua? Do con­ trário, mostre uma intercalação na qual a exclusão mútua não é preservada. 5.29 Cite uma outra restrição da exclusão mútua violada pelo algoritmo descrito na Figura 5.20. Projetos sugeridos 5.30 Elabore um trabalho de pesquisa sobre o algoritmo de ‘exclu­ são mútua rápida’ de Lamport. Como funciona? Onde é usado? 5.31 Pesquise exclusão mútua em sistemas distribuídos. Que pesquisas estão em curso nesse campo? 5.32 Pesquise exclusão mútua em sistemas multiprocessadores. Por que podería ser mais fácil do que a exclusão mútua em sistemas distribuídos? 5.33 Muitos algoritmos de exclusão mútua são verificados utilizando-se programas de computador. Pesquise como esses programas conseguem verificar se um determinado algoritmo está correto. 5.34 Dijkstra provavelmente é mais famoso pelo seu algoritmo do caminho mais curto. Contudo, ele também contribuiu muito em outros campos da ciência da computação. Por exemplo, fica­ mos sabemos no capítulo que ele inventou os semáforos. Prepare uma biografia de E. W. Dijkstra e suas importantes contribuições ao campo da ciência da computação. Consulte por exemplo, www.cs.utexas.edu/users/EWD. 5.35 Pesquise as primitivas de concorrência Ada. Como a exclusão mútua é garantida nesta linguagem? Simulações sugeridas 5.36 Implemente semáforos em Java. Depois use-os para forne­ cer sincronização entre dois threads em um programa produtor/ consumidor. TkreaÁ T 1 1 o Z enterMutualExclusion(a); 3 4 5 enterMutualExclusion(b); 1 enterMutualExclusion(b); 9 Z exitMutualExclusion(b); 6 7 TkreaÁ T2 3 4 5 enterMutualExclusion(a); exitMutualExclusion(a); 6 exitMutualExclusion(a); Figura/ 5. 19 Código pürso o Exercício 5.1G(b). 7 exitMutualExclusion(b); Copítuio 5 1 S is te m a : 2 3 4 5 int turn = 1; boolean t1 WantsToEnter = false; boolean t2WantsToEnter = false; 6 7 8 9 10 11 12 13 14 15 16 17 18 19 startThreadsl); // inicialize e lance ambos os threads T h re a d Ty; void m ain() { w h ile (ld o n e ) { t1 WantsToEnter = true; while ( turn != 1 ) { while ( t2W antsToEnter); 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 turn = 1; } / / termine while // código da seção crítica t1 WantsToEnter = false; // código fora da seção crítica } // termine o while mais externo } // termine Thread T 1 Th re a d void m ain() { while ( Idone ) { t2WantsToEnter = true; while ( turn ! = 2 ) { while ( t1 W antsToEnter); turn = 2; } / / termine while // código da seção crítica t2WantsToEnter = false; // código fora da seção crítica } // termine o while mais externo } // termine Thread T2 Figuro, 5.20 Algoritmo poro, o Exercício 5.28. Execução acsíncrona, concorrente, 150 S U tw u is o jte ra c io fu iti Notas 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. J. W. Atwood, “Concurrency in operating systems”, Com­ puter, v. 9, n° 10, out. 1976, p. 18-26. R. H. Thomas, “A majority consensus approach to concur­ rency control”, ACM Transactions on Database Systems, v. 4, 1979, p. 180-209. R Wegner e S. A. Smolka, “Processes, tasks and monitors: a comparative study of concurrent programming primitives”, IEEE Transactions on Software Engineering, v. SE-9, nfl 4, 1983, p. 446-462. K. M. Chandy e J. Misra, “Asynchronous distributed simulation via a sequence of parallel computations”, Communications o f the ACM, v. 24, nfl 4, abr. 1981. R. D. Schlichting e F. B. Schneider, “Understanding and using asynchronous message passing primitives”, Proceedings o f the Symposium on Principies o f Distributed Computing, 18-20 ago. 1982, Ottawa, Canadá, ACM, Nova York, p. 141-147. A. J. Bemstein, “Program analysis for parallel processing”, IEEE Transactions on Computers, v. 15, nfl 5, out. 1966, p. 757-762. P. J. Courtois, F. Heymans e D. L. Pamas, “Concurrent control with readers and writers”, Communications o f the ACM, v. 14, na 10, out. 1971, p. 667-668. L. Lamport, “Concurrent reading and writing”, Communi­ cations o f the ACM, v. 20, na 11, nov. 1977, p. 806-811. G. Ricart e A. K. Agrawala, “An optimal algorithm for mutual exclusion in Computer networks”, Communications o f the ACM, v. 24, na 1, jan. 1981, p. 9-17. D. W. Jones, “An empirical comparison of priority queue and event set implementations”, Communications o f the ACM, v. 29, nQ4, abr. 1986, p. 300-311. M. Raynal, Algorithms fo r mutual exclusion. Cambridge, MA: MIT Press, 1986. E. W. Dijkstra, “Cooperating sequential processes”, Technological University, Eindhoven, Holanda, 1965. Reprodu­ zido em F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968, p. 43-112. E. W. Dijkstra, “Cooperating sequential processes”, Technological University, Eindhoven, Holanda, 1965. Reprodu­ zido em F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968, p. 43-112. G. L. Peterson, “Myths about the mutual exclusion problem”, Information Processing Letters, v. 12, na 3, jun. 1981, p . 115-116. L. Lamport, “A new solution of Dijkstra’s concurrent pro­ gramming problem”, Communications o f the ACM, v. 17, na 8, ago. 1974, p. 453-455. E. W. Dijkstra, “Cooperating sequential processes”, Technological University, Eindhoven, Holanda, 1965. Reprodu­ zido em F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968, p. 43-112. G. L. Peterson, “Myths about the mutual exclusion pro­ blem”, Information Processing Letters, v. 12, na 3, jun. 1981, p. 115-116. E. W. Dijkstra, “Solution of a problem in concurrent pro­ gramming control”, Communications o f the ACM, v. 8, na 5, set. 1965, p. 569. D. Knuth, “Additional comments on a problem in concur­ rent programming control”, Communications o f the ACM, v. 9, na 5, maio 1966, p. 321-322. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. M. A. Eisenberg e M. R. McGuire, “Further comments on Dijkstra’s concurrent programming control problem”, Communications o f the ACM, v. 15, nQ 11, nov. 1972, p. 999. L. Lamport, “A new solution to Dijkstra’s concurrent pro­ gramming problem”, Communications o f the ACM, v. 17, na 8, ago. 1974, p. 453-455. J. E. Bums, P. Jackson, N. A. Lynch, M. J. Fischer e G. L. Peterson, “Data requirements for implementation of n-process mutual exclusion using a single shared variable”, Journal o f the ACM, vol. 29, na 1, jan. 1982, p. 183-205. O. S. F. Carvalho e G. Roucairol, “On mutual exclusion in Computer networks”, Communications o f the ACM, v. 26, na 2, fev. 1983, p. 146-147. Leslie Lamport, “A fast mutual exclusion algorithm”, ACM Transactions on Computer Systems (TOCS), v. 5, na 1, fev. 1987, p.1-11. James H. Anderson e Yong-Jik Kim, “An improved lower bound for the time complexity of mutual exclusion”, Proceedings o f the Twentieth Annual ACM Symposium on Principies o f Distributed Computing, ago. 2001, Newport, p. 90-99. Philip Gilbert e W. J. Chandler, “Interference between communicating parallel processes”, Communications o f the ACM, v. 15, na 6, jun. 1972, p. 436. Leon Presser, “Multiprogramming coordination”, ACM Computing Surveys (CSUR), v. 7, na 1, jan. 1975, p. 38. Clyde P. Kruskal, Larry Rudolph e Marc Snir, “Efficient synchronization of multiprocessors with shared memory”, ACM Transactions on Programming Ixinguages and Sys­ tems (TOPLAS), out. 1988, p. 580. E. W. Dijkstra, “Cooperating sequential processes”, Technological University, Eindhoven, Holanda, 1965. Reprodu­ zido em F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968, p. 43-112. P. Brinch Hansen, “The nucleus of a multiprogramming System”, Communications o f the ACM, v. 13, na 4, abr. 1970, p. 238-241,250. Eugene Stark, “Semaphore primitives and starvation-free mutual exclusion”, Journal ofthe Association fo r Compu­ ting Machinery, v. 29, na4, out. 1982, p. 1049-1072. P. J. Denning, T. D. Dennis e J. A. Brumfield, “Low contention semaphores and ready lists”, Communications o f the ACM, v. 24, na 10, out. 1981, p. 687-699. P. B rinch H ansen, “Edison: a m ultiprocessor language” , Softw are P ractice and E xperience, v. 11, nQ4, abr. 1981, p. 325-361. Linux kem el source code, version 2.5.75, miller.cs.wm.edu/ lxr3.linux/http/source/ipc/sem .c?v=2.5.75. 35. 36. 37. P. Brinch H ansen, “ D istributed processes — a con­ current program m ing concept” , C om m unications o f the AC M , v. 21, na 11, nov. 1978, p. 934-941. L. L am port, “T im e, clo ck s, and th e o rd erin g o f events in a distributed system ” , Com m unications o f the AC M , v. 21, n2 7, ju l. 1978, p. 558-565. L. Lam port, “T he im plem entation o f reliable distri­ buted m ultiprocess system s”, C om puter N etw orks, v. 2, nQ2, abr. 1978, p. 95-114. üipítulo S 38. 39. G. R icart e A. K. A graw ala, “A n optim al algorithm for m utual exclusion in Computer netw orks” , Com ­ m unications o f the A C M , v. 24, n2 1, jan . 1981, p. 9-17. M. A. Eisenberg e M. R. M cG uire, “ Further com ments on D ijkstra’s concurrent program m ing control 40. Execução mUtcrona, concorrente, fó j problem ” , Com m unications o f the AC M , v. 15, nc 11, nov. 1972, p. 999. G. R. Andrews e F. B. Schneider, “Concepts and notations for concurrent program m ing”, ACM Computing Surveys, v. 15, n* 1, mar. 1983, p. 3-44. C u m u lo 6 ^ r o jr m w jtç íio c o n c o r r e n te Pensamentos elevados devem ter linguagem de>alto nível. Aristófanes Enguanto os escritores tornam-se, mais numerosos é,natural que, os leitoretfiquem mais indolentes. Oliver Goldsm ith Quando o último leitor não mais ler. Oliver Wendell H olmes 0 primeiro preceitofo i nunca,aceitar uma coisa como verdadeira até, que, eu,soubesse que,fosse, verdadeira sem qualquer dúvida. René Descartes Isso mostra quão maisfá cil é,ser crítico do que, estar correto. Benjam in Disraeli Este capítulo apresenta: • Como monitores sincronizam o acesso a dados. • Como variáveis condicionais são usadas com monitores. • Soluções para problemas clássicos da programação concorrente, tais como leitores e escritores, e bujfer circular. • Monitores Java. • Chamada remota de procedimento. Capítulo 6 Programação concorrente, J fâ 6.1 Introdução N o últim o capítulo apresentam os o Algoritm o de Dekker e o Algoritm o de Peterson para a im plem entação de pri­ mitivas de exclusão m útua, e estudam os os semáforos de Dijkstra. Esses m ecanism os têm diversas fragilidades. São tão primitivos, que é difícil usá-los para expressar soluções para questões de concorrência m ais com plexas, e sua presença em program as concorrentes aum enta o já difícil problem a de provar a correção do program a. A m á utilização acidental ou m al-intencionada desses algoritm os poderia resultar em erros im perceptíveis que poderíam corrom per a operação de um sistem a concorrente. A abordagem do semáforo, em particular, tem m uitas falhas.1 Se um a operação P for omitida, a exclusão m útua não será garantida. Se uma operação V for omitida, os threads que estão à espera por causa das operações P poderão sofrer deadlock. U m a vez iniciada a operação P, o thread não pode desistir e adotar um curso alternativo de ação enquanto o sem áforo perm anecer em uso. Um thread só pode esperar em um sem áforo por vez, o que pode resultar em deadlock em situações dc alocação de recursos. Por exemplo, cada um de dois threads pode reter um recurso pelo qual o outro thread está esperando. Esse é o caso clássico de deadlock de dois threads que discutirem os no Capítulo 7, “Deadlock e adiam ento indefinido” . Para com bater esse problem a, pesquisadores desenvolveram construções de exclusão m útua de nível m ais alto que simplificam a resolução de questões com plexas de concorrência, facilitam a prova da correção do programa, e dificultam a m á utilização ou adulteração por um programador. Program ação concorrente é m uito m ais difícil do que program ação seqüencial. Program as concorrentes são m ais com plicados de escrever, depurar, m odificar e de provar que estão corretos (veja no site deste livro: “C uriosidades, É im possível testar exaustivam ente”). E ntão por que a com unidade de program adores insiste tanto na program ação concorrente? A onda de interesse em linguagens de program ação concorrente deve-se ao fato de nos habilitarem a expressar soluções mais naturais para problem as inerentem ente paralelos. A lém disso, o verdadeiro paralelism o de hardw are possível com m ultiprocessadores (veja o Capítulo 15, “Gerenciam ento de m ultiprocessador”) e sistemas distribuídos (veja o Capítulo 17, “Introdução a sistemas distribuídos”) som ente pode ser dom inado por meio da program ação concorrente. As aplicações potenciais da program ação concorrente são numerosas. Tem havido m uita discussão sobre concorrência em redes de com ­ putadores,2 sistem as distribuídos3,4,5,6,7e sistem as de tem po real.8,9,10 Os próprios sistemas operacionais certam ente são, por si sós, exemplos im portantes de sistem as concorrentes, assim com o sistem as de controle de tráfego aéreo, sistem as de m issão crítica e sistemas de controle de processo de tempo real (como os que controlam refinarias de petróleo, unidades de fabricação de produtos quím icos e instalações de processam ento de alimentos). E bem sabido que a visão hum ana é um a tarefa inerentem ente paralela. É quase certo que a previsão do tem po fará grandes progressos quando o paralelism o m aciço alcançar a escala de bilhões e até trilhões de processadores concorrentes. Neste capítulo abordarem os construções e linguagens de program ação concorrente de alto nível. Em particular exam i­ narem os m onitores, variáveis condicionais, com unicação interprocessos usando cham adas rem otas de procedim ento e os recursos de program ação concorrente oferecidos pela linguagem de program ação Java. Os exemplos de pseudocódigo da Seção 6.2, “M onitores” , usam um a sintaxe baseada na linguagem C; o restante do capítulo utiliza program as com pletos em Java. O capítulo term ina com uma longa seção sobre literatura que salienta a riqueza da program ação concorrente com o área de pesquisa. Q ue abordagem os im plem entadores deveríam adotar ao construir sistem as concorrentes hoje? A ntes da década de 90 havia, entre outras, as seguintes linguagens de program ação concorrente: A d a," Pascal C oncorrente,12,13 P roces­ sos D istribuídos,14 C C oncorrente,15 Processos Seqüenciais C om unicantes,16,17 M odula-2,18,19,20VAL21 e *M OD (para program ação distribuída).22 Com exceção da A da, essas linguagens de program ação geralm ente foram desenvolvidas por acadêm icos para finalidades de pesquisa e com um ente lhes faltavam m uitas das características necessárias para im plem entar sistem as reais. A tualm ente, m uitas linguagens de program ação populares suportam concorrência, entre elas Java, C#, Visual C++ .NET, Visual B asic.N ET e Python. A program ação concorrente proporciona oportunidades para estudantes de ciência da com putação que pretendam seguir carreira neste setor; há poucas pessoas com experiência em um assunto tão com plicado. Ret/Uão' 1. Por que os pesquisadores buscaram construções de exclusão m útua de nível m ais alto? 2. Qual a notável linguagem de program ação concorrente de alto nível desenvolvida antes da década de 90 que tinha, de fato, as características necessárias para im plem entar sistem as reais? R e ip o ifa i: i ) Essas construções facilitam a prova da correção do program a e dificultam a m á utilização ou o corrompimento. 2) Ada. 154 S U tw u is o jte ra c io fu u s 6.2 Monitores Monitor é um objeto que contém dados e procedim entos necessários para realizar a alocação de determ inado recurso com partilhado reutilizável serialmente ou grupo de recursos com partilhados reutilizáveis serialmente. A idéia de um m onitor foi sugerida por D ijkstra,23 seguido por Brinch Hansen,24*2^ , então, refinada por Hoare.26 H á muita discussão sobre esse tópico im portante na literatara.27,28,29,30,31,32,33,34,35 M onitores tom aram -se um a im portante construção de software — a linguagem de program ação Java faz uso extensivo de m onitores para im plem entar exclusão mútua. Para realizar alocação de recursos por m eio de m onitores, um thread deve cham ar um a rotina de entrada de monitor. M uitos threads podem querer entrar no m onitor ao m esm o tempo, mas a exclusão m útua é rigidam ente im posta na fronteira do m onitor — apenas é perm itida a entrada de um thread por vez. Com o o m onitor garante exclusão mútua, são evitados problem as de concorrência (como resultados indeterminados). Os dados internos de um m onitor podem ser globais para todas as rotinas internas do m onitor ou locais para um a roti­ na específica. Os dados do m onitor estão acessíveis som ente dentro do monitor; os threads fora do m onitor não dispõem de nenhum modo para acessar os dados do monitor. Essa é um a form a de ocultação de informações — um a técnica de arquitetura de software que m elhora a m odularidade e facilita o desenvolvim ento de sistem as de softw are m ais confiáveis (veja o quadro “Reflexões sobre Sistemas Operacionais, O cultação de inform ações”). Se um thread cham ar um a rotina de entrada no m onitor quando não houver nenhum outro thread executando dentro do monitor, ele obterá uma trava no m onitor e entrará nele. Enquanto o thread estiver dentro do monitor, nenhum outro thread poderá entrar para obter o recurso. Se um thread cham ar uma rotina de entrada no m onitor enquanto o m onitor estiver travado, esse obriga o thread cham ador a esperar fora do m onitor até que a trava seja liberada (ou seja, quando um thread não estiver m ais executando dentro do monitor). No entanto, a garantia de exclusão m útua oferecida pelos m onitores não é suficiente para bloquear um thread, dentro do monitor, em situações nas quais não possa continuar, por exemplo, quando o produtor encontra o buffer cheio, ou o consumidor encontra o buffer vazio. Nesses casos, variáveis condicionais são utilizadas, assim com o operações sobre essas variáveis, com o signal e waií, que serão explicadas na Seção 6.2.1. Para evitar adiamento indefinido, o m onitor dá prioridade m ais alta a threads que estão esperando do que aos que acabaram de chegar. R eviicuy 1. Por que um thread deve esperar por um recurso fora do monitor? 2. Com o um m onitor im pede que m últiplos threads executem concorrentem ente dentro dele? R e ip a itã i: i ) Se o thread tivesse de esperar por um recurso dentro de um monitor, nenhum outro podería entrar no m onitor para devolver o recurso. Com o veremos no Capítulo 7, “D eadlock e adiamento indefinido”, isso podería fazer que todos os threads que estivessem esperando pelo recurso sofressem deadlock. 2) O m onitor im põe exclusão m útua em sua fronteira usando os tipos de técnicas discutidos no Capítulo 5, “Execução assíncrona concorrente”. Rej-lexõeç çoWc o<o&c<xc\owâ\6 OcM Átaçãx) c lb U tfe rttu iç ô e t Ocultação de inform ações é uma das técnicas mais fundamen­ tais da engenharia de software. É implementada de muitas maneiras em sistemas operacionais. Quando um método ou função chama outro, ou outra, o que chama não precisa conhecer os detalhes de im ple­ mentação daquele que é chamado; basta conhecer a interface — quais argumentos devem ser passados e em que ordem, e quais valores de retorno esperados. A ocultação de inform ações tem muitas van­ tagens. Facilita o serviço daquele que cham a, o qual não precisa estar familiarizado com a comple­ xidade (possivelmente enorme) do modo de implementação daquele que é chamado. Também facilita a modificação de sistemas — uma função chamada geralmente pode ser substituída com facilidade sem e xigir m udanças na função que chama, contanto que a interface com a fu n ç ã o que é cham ada permaneça a mesma. Os sistemas operacionais de hoje têm dezenas de milhares de componentes (ou mais) que estão constantem ente em evolução para se adaptarem às novas tendências de hardware e software e sendo aperfeiçoados para funcionar melhor. A ocultação de informações desempenha um papel crucial na inteligibilidade e capacidade de manutenção desses sistemas enormes e de alto grau de modularidade. Capítulo 6 Programação concorrente, 6.2.1 VariÁJueis condicionais M onitores im plem entam exclusão m útua e sincronização entre threads de execução. Um thread que esteja corrente­ m ente dentro de um m onitor poderá ter de esperar fora dele até que um outro thread execute um a ação no monitor. Por exemplo, no relacionam ento produtor/consum idor, o produtor, ao verificar que o consum idor ainda não leu o valor de um buffer único com partilhado, deve esperar fora do m onitor que governa o buffer para que o consum idor possa consum ir o conteúdo do buffer. Sim ilarm ente, um consumidor, ao verificar que um buffer com partilhado está vazio, deve esperar fora do m onitor até que o produtor preencha o buffer. O thread que está dentro do m onitor utiliza a variável condicional para esperar por um a condição fora do monitor. O m onitor associa a variável condicional a cada situação distinta que poderá obrigar o thread a esperar. Definimos as operações wait e signal como: w ait (conditionVariablé) signal (conditionVariablé) Variáveis condicionais são diferentes de ‘variáveis convencionais’. Cada variável condicional tem uma fila associada. Um thread que cham ar wait em uma variável condicional particular será colocado na fila associada com aquela variável condicional (enquanto estiver naquela fila, o thread estará fora do monitor, de m odo que um outro thread poderá eventual­ m ente entrar no m onitor e cham ar signal). Um thread que cham e signal em um a variável condicional particular fará que um thread que esteja esperando naquela variável condicional seja retirado da fila associada àquela variável e entre novamente no monitor. Podem os pressupor um a disciplina de fila do tipo ‘primeiro a entrar, prim eiro a sair’ (First-In-First-O ut— FIFO), em bora esquem as de prioridade possam ser úteis em certas situações.36-37 A ntes de aquele thread entrar novam ente no m onitor, o thread que cham ar signal deverá prim eiram ente sair do m o­ nitor. B rinch H ansen (veja no site deste livro: “Biografia, Per B rinch H ansen” ), ao notar que m uitas instruções signal precediam im ediatam ente um a instrução return (ou seja, o thread sai do m onitor), propôs um m onitor sinalize-e-saia (signal-and-exit) no qual um thread sai im ediatam ente do m onitor ao sinalizar.38 O s m onitores dos próxim os exem plos são do tipo sinalize-e-saia. A ltem ativam ente, um m onitor sinalize-e-continue perm ite que um thread que esteja dentro do m onitor sinalize que esse logo estará disponível, mas ainda continuará travado até que o thread saia dele. Um thread pode sair do m onitor esperando em um a variável condicional ou concluindo a execução do código protegido pelo m oni­ tor. O thread liberado por um m onitor sinalize-e-continue deve aguardar até que o thread que sinalizou saia do monitor. C om o discutirem os na Seção 6.3, “M onitores Java” , a linguagem de program ação Java im plem enta m onitores do tipo sinalize-e-continue. RevU cuy 1. Qual problem a podería ocorrer se uma variável condicional usasse um a fila por prioridade (em vez de um a fila FIFO)? 2. (V/F) Cada m onitor contém exatam ente uma variável condicional. RçjJpoÚ M l 1) U m thread de prioridade mais baixa podería ser adiado indefinidamente por um fluxo de threads cha­ m ando a instrução wait ao entrar na fila de prioridades. 2) Falso. U m m onitor contém um a variável condicional separada para cada situação distinta que possa fazer um thread cham ar wait no monitor. 6.2.2 Alocação simples recursos conc monitores Suponha que diversos threads estejam disputando um recurso que requer acesso exclusivo. A Figura 6.1 m ostra um m onitor simples para m anipular a alocação e desalocação desse recurso. A linha 4 declara a variável de estado inUse que m onitora se um recurso está ou não em uso. A linha 5 declara uma variável condicional na qual espera um thread que encontrou o recurso não disponível e é sinalizada por um thread que está devolvendo o recurso (tornando-o, portanto, disponível). As linhas 7-17 e 19-25 declaram duas rotinas de entrada no monitor. Para indicar que essas rotinas são de entrada no m onitor (e não rotinas privadas do m onitor), cada um a recebe um prefixo com a palavra-chave em pseudocódigo monitorEntry. A linha 8 inicia o método getResource que um thread cham a para requisitar o recurso associado à variável condicional available. A linha 10 testa o estado da variável inUse para verificar se o recurso está em uso. Se esse valor for tru e, significando que o recurso foi alocado a um outro thread, o thread que está cham ando deverá esperar na variável condicional available (linha 12). Após cham ar w ait, o thread sai do m onitor e é colocado na fila associada à variável condicional available. Como veremos, isso perm ite que o thread que está usando o recurso entre no m onitor e libere o recurso sinalizando a variável condicional available. Q uando o recurso não estiver em uso, o thread que o requisitar executará a linha 1 5 que coloca inUse em true, concedendo ao thread acesso exclusivo ao recurso. 156 Stitw uu operacionais A linha 2 0 inicia o método returnResource que um thread cham a para liberar o recurso. A linha 2 2 põe o valor de inUse em false indicando que o recurso não está m ais em uso e pode ser alocado a um outro thread. A linha 2 3 cham a signal na variável condicional available para alertar quaisquer threads que estejam à espera que o recurso agora está livre. Se houver threads à espera na fila associada à available (como resultado da execução da linha 1 2 ) , o próxim o thread que estiver esperando entrará novamente no m onitor e excutará a linha 15 obtendo acesso exclusivo ao recurso. Se não houver threads esperando em available, signal não terá nenhum efeito. A beleza do m onitor da Figura 6.1 é que ele funciona exatam ente com o um sem áforo binário: o método getResource age com o a operação P; o método returnResource age com o a operação V. Com o o m onitor simples de um só recurso pode ser usado para im plem entar semáforos, m onitores são, no mínim o, tão poderosos quanto semáforos. N ote que a inicialização do m onitor (linhas 3-5) é executada antes que o thread com ece a usar o m onitor; nesse caso inUse é colocada em false indi­ cando que o recurso está inicialm ente disponível. Rei/Uãc 1. O que aconteceria se returnResourceO não sinalizasse (sig nal) a variável condicional available? 2. Para que serve a palavra-chave monitorEntry? R e íp o itõ i: 1) Todos os threads que estão à espera na variável condicional available sofreriam deadlock — esperariam para sempre. 2) A palavra-chave monitorEntry distingue entre rotinas de entrada no monitor, que podem ser acessadas por todos os threads e executadas por apenas um thread por vez, e m étodos privados do m onitor que som ente podem ser aces­ sados dentro do monitor. 6.2.3 Exemplo Monitor: buffer circular N esta seção discutirem os o b u ffe r c irc u la r (às vezes denom inado b u ffe r lim itado) e quanto ele é útil em situações nas quais um thread produtor passa dados a um thread consumidor. Com o o produtor e o consum idor acessam os mesmos dados e podem funcionar em velocidades diferentes, a sincronização entre os dois threads é essencial. Podem os usar um arranjo para im plem entar o buffer circular. N a im plem entação da solução do problem a produtor/ consum idor em buffer circular o produtor deposita dados nos elem entos sucessivos do arranjo. O consum idor os retira na 1 // Fig. 6.1: Monitor de alocação de recursos 2 3 4 5 // inicialização do monitor (executada somente uma vez) boolean inUse = false; // variável de estado simples Condition available; // variável condicional 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // requisite recurso monitorEntry void getR esourcef) { if ( inUse ) // recurso em uso? { wait( available ); // espere até que available seja sinalizada } / / termine if inUse = true; // indique que recurso agora está em uso } // termine getResource // devolva o recurso monitorEntry void returnResource() { inUse = false; // indique que recurso não está em uso signaK available ); // sinalize a um thread à espera para continuar } // termine returnResource urcb G. 1 Alocação sim ples d e recurso com, um , m onitor em,pseudocódigo. Ca^vtvdo 6 ProyrauuiçÂo concorrente J57 ordem em que foram depositados (FIFO). O produtor pode estar vários itens à frente do consum idor e eventualmente preen­ cher o último elem ento do arranjo. Q uando produzir m ais dados, precisará ‘fazer a volta’ e recom eçar a depositar dados no prim eiro elem ento do arranjo (supondo, é claro, que o consum idor tenha retirado os dados ali depositados previam ente pelo produtor). O arranjo efetivam ente se fecha em um círculo, daí o term o buffer circular. Devido ao tamanho fixo do buffer circular, o produtor ocasionalmente encontrará todos os elementos do arranjo preenchi­ dos; nesse caso deve esperar até que o consum idor esvazie um elem ento do conjunto. Similarmente, às vezes o consum idor quer consumir, mas o arranjo estará vazio; nesse caso, o consum idor deve esperar até que o produtor deposite dados em um elem ento do arranjo. O m onitor da Figura 6.2 (baseado no exem plo apresentado por H oare)39 im plem enta um buffer circular e os m ecanism os de sincronização apropriados para m anipular o relacionam ento produtor/consumidor. Suporem os que o arranjo drcularBuffer contenha entradas BUFFER_SIZE consistindo em um caractere (linha 3). As variáveis writerPosition e readerPosition (linhas 4-5) indicam em qual entrada do buffer circular o próxim o item deve ser colocado por um produtor e de qual entrada do buffer circular o próxim o item deve ser retirado por um consum idor, respectivamente. 1 // Fig. 6.2: Monitor de buffer circular 2 3 4 5 6 7 8 9 10 11 // entrada no monitor chamada pelo produtor para escrever dados monitorEntry void putCharf char slotData ) 12 { 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 char drcularBuffer! ] = new char[ BUFFER_SIZE ]; // buffer int writerPosition = 0; // próxima entrada para onde escrever int readerPosition = 0; // próxima entrada de onde ler int occupiedSlots = 0; // número de entradas com dados Condition hasData; // variável condicional Condition hasSpace; // variável condicional // espere na variável condicional hasSpace se o buffer estiver cheio if ( occupiedSlots == BUFFER_SIZE ) { wait( hasSpace ); // espere até hasSpace estar sinalizada } / / termine if // escreva caractere no buffer drcularBuffer! writerPosition ] =slotData; ++occupiedSlots; // mais uma entrada tem dados writerPosition = (writerPosition + 1) % BUFFER_SIZE; signal( hasData ); // sinalize que os dados estão disponíveis } // termine putChar // entrada no monitor chamada pelo consumidor para ler dados monitorEntry void getCharf outputParameter slotData ) { // espere na variável condicional hasData se o buffer estiver vazio if ( occupiedSlots == 0 ) { wait( hasData ); // espere até hasData estar sinalizada } / / termine if // leia caractere do buffer para o parâmetro de saída slotData slotData = drcularBuffer! readPosition 1; occupiedSlots— ; // uma entrada a menos tem dados readerPosition = (readerPosition + 1)% BUFFER_SIZE; signaK hasSpace ); // sinalize que o caractere foi lido } // termine getChar UTOyG.2 IuipíementeiçÂo d&pteudocódigo d&monitorpara, cmc buffer circuUr. 158 S U tw u is o jte ra à o tu u s Um produtor adiciona dados ao buffer cham ando o m étodo putChar (linhas 1 0 - 2 4 ) . A linha 1 4 testa se o buffer está cheio. Se estiver, o produtor espera na variável condicional hasSpace (linha 16). Ao fazer isso, o produtor sai do m onitor e espera na fila associada à variável condicional hasSpace. Com o logo veremos, isso perm ite que um consum idor entre no monitor, consum a dados do buffer circular e sinalize a variável condicional hasSpace (linha 2 0 ) , o que, por sua vez, perm ite que o produtor continue. Então ele escreve os dados no buffer (linha 2 0 ) , increm enta o núm ero de entradas ocupadas (linha 2 1 ) e atualiza a variável writerPosition (linha 2 2 ) . Por fim, a linha 2 3 sinaliza a variável condicional hasData para perm itir que um consum idor à espera, se houver, prossiga. Um consum idor lê dados do buffer circular cham ando o método getChar (linhas 2 6 - 4 0 ) . Note a utilização do parâm etro de saída slotData no pseudocódigo (indicado pela palavra-chave outputParameter na linha 2 7 ) . M uitas linguagens suportam tal capacidade. Dados escritos no parâm etro de saída estão im ediatam ente disponíveis no argum ento do chamador. A linha 3 0 testa se o buffer está vazio. Se estiver, o consum idor espera na variável condicional hasData (linha 3 2 ) . Q uando o consu­ m idor puder continuar, ele lerá os dados do buffer diretam ente no parâm etro de saída slotData (linha 3 6 ) , disponibilizando im ediatam ente os dados no argum ento do chamador. Então o consum idor decrem enta o núm ero de entradas ocupadas (linha 3 7 ) e atualiza readerPosition (linha 3 8 ) . A linha 3 9 sinaliza a variável condicional hasSpace para perm itir que um produtor à espera, se houver, prossiga. A beleza do buffer circular é que ele perm ite que o produtor ‘passe à frente’ do consumidor. O produtor pode criar um valor sem esperar que o consum idor leia o valor anterior (como é necessário no relacionam ento produtor/consum idor com buffer único). Esses valores extras são colocados nas entradas vazias do buffer circular. M esm o assim o consum idor lerá os valores na ordem correta. O buffer circular reduz a quantidade de tem po que o produtor deve esperar antes de produzir outro valor, m elhorando assim o desem penho do sistema. Q uanto m aior o buffer circular, m ais valores o produtor pode produzir antes de ter de esperar que o consum idor esvazie o buffer. Se o produtor e o consum idor trabalharem aproxi­ m adam ente na m esm a velocidade, a utilização do buffer circular poderá aum entar a velocidade m édia da aplicação. Se houver um a diferença entre as velocidades m édias dos threads, essa vantagem será anulada. Por exem plo, se o produtor trabalhar consistentem ente m ais velozm ente do que o consum idor, o buffer circular rapidam ente ficará cheio e continua­ rá cheio, forçando o produtor a esperar toda vez que o consum idor liberar espaço. Do m esm o modo, se o consum idor trabalhar consistentem ente com m aior velocidade do que o produtor, ele encontrará o buffer vazio e quase sem pre terá de esperar que o produtor crie um valor. N esses dois últim os casos, usar o buffer circular desperdiçará m em ória em vez de aum entar a velocidade da aplicação. Sistem as operacionais podem utilizar um buffer circular para im plem entar controle de spooling. Um exemplo com um ocorre quando um thread gera linhas que deverão ser im pressas por um dispositivo de saída relativam ente lento com o um a im pressora. Pelo fato de o thread produzir as linhas m uito m ais rapidam ente do que a im pressora pode imprim ilas, e porque gostaríam os que o thread pudesse concluir sua execução o m ais rapidam ente possível, as linhas de saída do thread podem ser dirigidas para um buffer circular. O buffer circular pode estar em um a unidade de arm azenam ento prim ário, ou m ais provavelm ente em um disco. O thread que cria as linhas que deverão ser im pressas é denom inado spooler. Um outro thread lê as linhas de circularB uffer e as passa para a im pressora. M as esse segundo thread, denom inado d esp o o ler, funciona na m enor velocidade da im pressora. O buffer circularB uffer tem espaço de arm azenam ento suficiente para ‘tirar o atraso’ resultante da incom patibilidade entre as velocidades dos threads do spooler e do despooler. É ób­ vio que partim os da prem issa que o sistem a não gera, indefinidam ente, linhas de im pressão mais rapidam ente do que a im pressora pode im prim i-las; se fizesse isso, o buffer estaria sem pre cheio e seria de pouca valia para harm onizar’ a operação de im pressão. Revuão' 1. Cite as duas situações em que um buffer circular é menos eficiente do que um buffer de valor único na relação produtor/consumidor. 2. Esse m onitor suportaria um produtor e dois consum idores de modo que cada elem ento produzido pelo produtor fosse consum ido por exatam ente um consum idor? Por que sim ou por que não? R e ip o ità i: 1) Se a diferença entre as velocidades médias do produtor e do consum idor for significativa, a vantagem do buffer circular é anulada. Se o produtor funcionar consistentem ente com m aior velocidade do que o consum idor, quase sempre encontrará o buffer cheio e toda vez terá de esperar que um consum idor consuma. Se o consum idor funcionar consistentem ente com m aior velocidade do que o produtor, quase sem pre encontrará o buffer vazio e terá de esperar toda vez que um produtor produza. N esses casos, um buffer de valor único pode ser usado sem perder desem penho. 2) Sim. A exclusão m útua ainda seria im posta pelo monitor. O produtor ainda produziría valores normalm ente. Apenas um consu­ m idor leria cada dado de um produtor. Capítulo 6 Programação concorrente, J£Q 6.2 A Exemplo d&monitor: Leitores &escritores Em sistemas de com putador é comum ter alguns threads consumidores (denominados leitores) que lêem dados, e threads produtores (denom inados escritores) que os escrevem. Por exemplo, no sistem a de reservas de um a em presa aérea pode haver m uito m ais leitores do que escritores — serão feitas muitas consultas ao banco de dados de inform ações de voos disponíveis antes de o cliente selecionar e se decidir por determ inada poltrona em determ inado voo. Com o os leitores não m udam o conteúdo de um banco de dados, m uitos deles podem ter acesso ao banco de dados ao m esm o tempo. M as um escritor pode modificar os dados, portanto, deve ter acesso exclusivo. Quando um escritor está ativo, nenhum outro leitor ou escritor pode estar ativo. Essa exclusão precisa ser im posta som ente no nível do registro. Não é necessário conceder a um escritor acesso exclusivo ao banco de dados inteiro — fazer isso podería prejudicar dras­ ticam ente o desem penho. O problem a de elaborar o projeto de um program a concorrente para controlar o acesso de leitores e escritores a um banco de dados foi proposto e resolvido pela prim eira vez por Courtois, Heym ans e Pam as.40 A solução da Figura 6.3 é baseada na desenvolvida por Hoare.41 O m onitor da Figura 6.3 pode ser usado para controlar o acesso a um banco de dados inteiro, a um subconjunto do banco de dados consistindo em m uitos ou poucos registradores ou até a um único registro. Em qualquer um desses casos pode ser aplicada a discussão a seguir. Som ente um escritor pode estar ativo por vez; quando um escritor está ativo, a variável booleana writeLock (linha 4) é íru e. N enhum leitor pode estar ativo se um escritor estiver ativo. A variável inteira readers (linha 3) indica o núm ero de leitores ativos. Q uando o núm ero de leitores for reduzido a zero (linha 29), um escritor à espera (se houver) se tom ará ativo (linha 31). Se um novo leitor não puder prosseguir (linha 13), esperará na variável condicional canRead (linha 15). Se um novo escritor não puder prosseguir (linha 40), esperará na variável condicional canWriíe (linha 42). Q uando um leitor desejar ler, cham a a entrada de m onitor beginRead (linhas 8-21); um leitor que tiver term inado cham a endRead (linhas 23-24). Em beginRead um novo leitor pode prosseguir contanto que nenhum thread esteja esperando para escrever (linha 13). A últim a condição é im portante para evitar adiam ento indefinido de escritores à espera; ela é testada usando-se a função booleana queue, que determ ina se há ou não threads esperando na variável condicional especificada em seu argumento. N ote que o procedim ento beginRead term ina sinalizando canRead (linha 20) para perm itir que um outro leitor à espera com ece a ler, o que obriga o próxim o leitor da fila de leitores à espera a tom ar-se ativo e, por sua vez, sinalizar ao próxim o leitor à espera que pode prosseguir. Essa ‘reação em cadeia’, tam bém denom inada efeito em cascata, continuará até que todos os leitores à espera tenham se tornado ativos. Enquanto a cadeia estiver avançando, todos os threads que chegarem serão forçados a esperar, porque o m onitor cum pre a regra de atender threads sinalizados antes dos que estão chegando. Se aos leitores que chegam fosse perm itido prosseguir, um fluxo contínuo de leitores que chegassem causaria adiam ento indefinido de escritores à espera. Com o os leitores não interferem uns nos outros e podem executar em paralelo em sistemas m ultiprocessadores, esse é um m odo eficiente de servir a esses threads. Q uando um thread acaba de ler, cham a a entrada de m onitor endRead (linhas 23-24) que decrem enta o núm ero de leitores de 1 (linha 26). Eventualm ente esse decrem ento faz o número de leitores passar para zero, quando então o thread sinaliza canWrite (linha 31) para perm itir que um escritor à espera, se houver, prossiga (evitando adiam ento indefinido de escritores à espera). Quando um thread deseja escrever, cham a a entrada de monitor beginWrite (linhas 3 6 - 4 6 ) . Como um escritor deve ter acesso exclusivo, se houver quaisquer leitores ativos ou se houver um escritor ativo (linha 4 0 ) , o novo escritor deverá esperar na variável condicional canWriíe (linha 4 2 ) . Q uando o escritor puder prosseguir (porque canWrite está sinalizado na linha 3 1 ou na linha 6 0 ) , writeLock é colocado em true (linha 4 5 ) , o que deixa de fora quaisquer outros escritores e leitores. Q uando um escritor term ina, cham a a entrada de m onitor endWrite (linhas 48-63). Esse procedim ento coloca writeLock em false (linha 51), para que ou leitores ou um outro escritor possa se tom ar ativo. Então o m onitor deve sinalizar a um 1 // Fig. 6.3: Problema dos leitores/escritores 2 3 4 5 6 7 8 9 int readers = 0; // número de leitores boolean writeLock = false; // true se um escritor estiver escrevendo Condition canWrite; // variável condicional Condition canRead; // variável condicional // entrada de monitor chamada antes de executar read monitorEntry void beginReadf) ura, G.3 Pseudocódigo de, monitor para, resolver oproblema, de, leitores e, escritores (parte, 1de,2). 160 10 11 12 13 14 15 16 17 18 19 20 21 Sistemas operacionais { // espere fora do monitor se escritor estiver correntemente escrevendo ou se // escritores estiverem correntemente esperando para escrever if ( writeLock || queuef canWrite )) { wait( canRead ); // espere até que leitura seja permitida } / / termine if ++readers; // há um outro leitor signaK canRead ); // permita que leitores à espera prossigam } // termine beginRead 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 // entrada de monitor chamada após leitura monitorEntry void endReadf) { - - readers; // há um leitor a menos // se não houver mais leitores lendo, permita que um escritor escreva if ( readers == 0 ) { signal ( canWrite ); // permita que um escritor prossiga } / / termine if } // termine endRead // entrada de monitor chamada antes de executar write monitorEntry void beginW ritef) { // espere se leitores estiverem lendo ou se um escritor estiver escrevendo if ( readers > 0 || writeLock ) { wait( canWrite ); // espere até que seja permitido escrever } / / termine if writeLock = true; // bloqueie todos leitores e escritores } // termine beginWrite // entrada de monitor chamada após executar w rite monitorEntry void endW rite() { writeLock = false; // libere o bloqueio // se um leitor estiver esperando para entrar, sinalize um leitor if ( queue( canRead )) { signaK canRead ); // efeito em cascata em leitores à espera } / / termine if else // sinalize um escritor se nâo houver leitores esperando { signaK canWrite ); // um escritor que está esperando pode prosseguir } / / termine else } // termine endWrite Fisjura, 6 3 Pseudocódigo de, monitorpara, resolver oproblema, de, leitores e, escritores (parte, 2 de, 2). Capítulo 6 Programação concorrente, JfaJ outro thread à espera para que esse prossiga (linhas 53-61). Ele deve dar preferência a um leitor à espera ou a um escritor à espera? Se der preferência a um escritor à espera, será possível que um fluxo constante de escritores que estão chegando cause o adiam ento indefinido dos leitores que estão à espera. Portanto, quando um escritor termina, prim eiram ente verifica se há algum leitor esperando (linha 54). Se houver, canRead é sinalizada (linha 56) e o leitor à espera pode prosseguir (o que, é claro, provoca um efeito em cascata de todos os leitores que estão à espera). Se não houver nenhum leitor esperando, canWrite é sinalizada (linha 60) e um escritor à espera obtém perm issão para prosseguir. R e rtiã o ' 1. A Figura 6.3 provoca efeito em cascata em leitores à espera, mas nunca em escritores à espera? Por quê? 2. Q ue salvaguarda existe contra um fluxo contínuo de leitores que adie indefinidam ente um escritor? Reípoitãi: i ) Leitores não interferem uns nos outros, portanto, m uitos leitores podem ler com segurança de um a vez só. 2 ) N a entrada de m onitor beginRead, se houver quaisquer escritores esperando para escrever (linha 1 3 ) , um thread que quiser ler deverá esperar na variável condicional canRead (linha 1 5 ) . 63 MonitoresJcunn, N as próxim as seções apresentam os soluções Java m ultithread com pletas, funcionais, para problem as com uns de program ação concorrente. M onitores são associados a cada objeto criado em Java e tam bém representam o m ecanism o primário para fornecer exclusão m útua e sincronização em aplicações Java multithread. A palavra-chave synchronized impõe exclusão m útua sobre um objeto em Java. N esta seção explicam os quais as diferenças entre m onitores Java e m onitores em pseudocódigo discutidos na seção anterior. Q uando um thread tenta executar um método protegido por um m onitor Java (ou seja, o m étodo é declarado synchronized), deve prim eiram ente entrar no conjunto de entrada daquele m onitor (com um ente denom inado fila de entrada), que é um a fila de threads que estão à espera para entrar no monitor. Se não houver nenhum a contenção para a entrada, um thread entrará im ediatam ente no monitor. Se já houver um thread dentro do monitor, os outros threads deverão perm anecer na entrada até o m onitor ficar disponível. M onitores Java são com umente denom inados monitores sinalize-e-continue.42 Lembre-se de que um m onitor sinalize-econtinue perm ite que um thread que esteja dentro do m onitor sinalize que aquele m onitor logo ficará disponível, mas ainda m antenha um bloqueio no m onitor até sair. Um thread pode sair de um m onitor esperando em uma variável condicional ou concluindo a execução do código protegido pelo monitor. Um thread que estiver executando em um m onitor e que deve esperar em uma variável condicional em itirá uma cham ada wait. O método wait força o thread a liberar o bloqueio do m onitor e esperar em um a variável condicional não denominada. A pós cham ar w ait, um thread é colocado no conjunto de espera (tam bém denom inado fila de espera), um a fila de threads que estão à espera para entrar novam ente no m onitor para acessar o objeto. Os threads perm anecem no conjunto de espera até que sejam sinalizados (notificados) por um outro thread. Com o a variável condicional é im plícita em Java, um thread pode ser sinalizado, entrar novamente no m onitor e constatar que a condição pela qual esperou não foi cumprida. Conseqüentem ente, um thread pode ser sinalizado diversas vezes antes que a condição pela qual esteja esperando seja cumprida. Threads em item sinais cham ando o m étodo notify ou notifyAll. O método notify acorda um único thread do conjunto de espera. O algoritm o que determ ina qual thread entrará no m onitor em seguida varia dependendo da im plem entação da m áquina virtual Java (JVM ). Conseqüentem ente, o program ador não pode confiar em uma disciplina de enfileiramento particular quando notify é chamado. U m a outra arm adilha do m étodo no tify é que a ordem em que algum as im plem entações da J V M retiram threads dos conjuntos de entrada e espera pode provocar longos atrasos no serviço para determ inados threads desses conjuntos — criando a possibilidade de adiam ento indefinido. D esse m odo, se m ais de dois threads acessarem um m onitor é m elhor usar o m étodo notifyAll que acorda todos os threads nos conjuntos de entrada e espera. Q uando todos os threads estive­ rem acordados, o escalonador de threads determ inará qual deles obtém o monitor. O escalonador de threads em prega um a disciplina de enfileiram ento que im pede adiam ento indefinido.43,44 Com o notifyA ll acorda todos os threads que estão à espera para entrar no m onitor (ao contrário de n o tify, que acorda um único thread), ele incorre em m ais sobrecarga do que no tify. No caso sim ples da sincronização de dois threads, n o tify rende um desem penho m ais alto do que notifyA ll sem sofrer adiam ento indefinido. Revuão1. Qual a diferença entre m onitores sinalize-e-continue e sinalize-e-saia? Qual deles é usado em Java? Retfoitã: i) Java usa m onitores sinalize-e-continue que perm item que um thread sinalize que estará deixando o m S is te m a s o p e ra c io n a is m onitor em breve, retendo ainda o controle do monitor. M onitores sinalize-e-saia requerem que um thread libere sua trava do m onitor im ediatam ente após a sinalização. 6.4 Estudo de ccuso deJava, nudtitkread, Parte ttl: relacionajuento produtor/consuuudor eneJoamv N esta seção apresentam os um a im plem entação em Java do relacionam ento produtor/consum idor exam inado na Seção 5 .2 .1 , “Estudo de caso de Java multithread, Parte II” . A aplicação nas figuras 6 . 4 e 6 .5 dem onstra um produtor e um consu­ m idor acessando um único buffer com partilhado com sincronização provida por um monitor. N esse caso o produtor produz um valor som ente quando o buffer estiver vazio, fazendo com que o buffer fique cheio; o consum idor consom e um valor apenas quando o buffer estiver cheio, fazendo com que o buffer fique vazio. Esse exemplo utiliza novamente a interface Buffer (Figura 5 . 1 ) e as classes Producer (Figura 5 . 2 ) e Consumer (Figura 5 . 3 ) do exemplo da Seção 5 .2 .1 . A reutilização dessas classes do exemplo, sem sincronização, habilita-nos a dem onstrar que threads que acessam um objeto com partilhado não ficam cientes de que estão em sincronia. O código que executa a sincronização é colocado nos m étodos set e get da classe SynchronizedBuffer (Figura 6 . 4 ) que im plem enta a interface Buffer (linha 4 ) . Assim , os m étodos run de Producer e Consumer sim ­ plesm ente cham am os m étodos set e get do objeto com partilhado com o no exemplo da Seção 5 .2 .1 . A classe SynchronizedBuffer (Figura 6 . 4 ) contém dois cam pos — buffer (linha 6 ) e occupiedBuffers (linha 7 ) ; set (linhas 9 ^ 4 -3 ) e get (linhas 4 5 - 7 9 ) agora são m étodos synchronized (linhas 1 0 e 4 6 ) ; assim, som ente um thread pode entrar em qualquer desses m étodos por vez para um objeto SynchronizedBuffer particular. Em bora occupiedBuffers (linha 7 ) seja logicam ente um a 1 2 3 4 // Fig. 6.4: SynchronizedBuffer.java // SynchronizedBuffer sincroniza acesso a um inteiro compartilhado. 5 { 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class SynchronizedBuffer implements Buffer private int buffer = -1; // compartilhado por produtor e consumidor private int occupiedBuffers = 0; // conta buffers ocupados // coloca valor no buffer public synchronized void set( int value ) { // para exibição, obtenha nome do thread que chamou este método String name = Thread.currentThreadf ).getN am e(); // enquanto não houverbuffers vazios, coloque thread no estado de espera while ( occupiedBuffers == 1 ) { // apresente informações de thread e buffer, então espere try 20 { 21 22 23 24 25 26 27 28 29 30 31 32 33 System.err.println( name + " tenta escrever." ); displayStatef "B uffer cheio. " + name + " espera." ); w a it(); // espere até o buffer estar vazio } // termine try // se thread à espera interrompeu, imprima cópia da pilha catch ( InterruptedException exception ) { exception.printStackTraceO; } // termine catch } // termine while fu ju rfc G.4 SynchronizedBuffer sincroniza, acesso a, uuv inteiro compartiUiado (parte/1de 3). Ca^vtvdo 6 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 Programação concorrente. buffer = value; // coloque novo valor em buffer // indique que produtor não pode armazenar um outro valor // até que consumidor recupere valor corrente do buffer ++occupiedBuffers; displayStatel name + " escreve " + b u ffe r); n o tify l); // mande o thread à espera entrar no estado pronto } // termine método set; libere trava de SynchronizedBuffer // retorne valor do buffer public synchronized int g e t() { // para exibição, obtenha nome do thread que chamou este método String name = Thread.currentThread( ).getN am e(); // enquanto não houver dados para ler, coloque thread no estado de espera while ( occupiedBuffers == 0 ) { // apresente informação de thread e buffer, então espere try { System.err.println( name + " tenta ler." ); displayState( "B uffer vazio. " + name + " espera." ); w a it();// espere até o buffer conter novos valores } / / termine try // se o thread à espera interrompeu, imprima cópia da pilha catch ( InterruptedException exception ) { exception.printStackTracel); } // termine catch } // termine while // indique que produtor pode armazenar um outro valor // porque consumidor acabou de recuperar valor do buffer --o c c u p ie d B u ffe rs ; displayStatel name + " lê " + b u ffe r); n o tify l); // diga ao thread à espera para ficar pronto return buffer; } // termine método get; libere a trava de SynchronizedBuffer // exiba operação corrente e estado do buffer public void displayStatel String operation ) { StringBuffer outputLine = new StringBufferl operação ); outputLine.setLengthl 40); outputLine.appendl buffer + "\t\t" + Contagem de Ocupados ); System.err.printlnl outp u tLine ); System.err.printlnl); } // termine método displayState ura, G.4 SynchronizedBuffer sincroniza,acesso a, um, inteiro compartilhado (parte, 2 de, 3). 163 164 90 91 f U ju r a , S is te m a s o p e ra c io n a is } // termine classe SynchronizedBuffer 6.4 SynchronizedBuffer sutcroniza, &cetso a, imc Utteiro unipartilhado (parte, 3 de, 3). variável condicional, ela é do tipo int; não há nenhum objeto ou tipo em Java que represente um a variável condicional. Os m étodos em SynchronizedBuffer usam occupiedBuffers em expressões condicionais (linhas 16 e 52) para determ inar se é a vez do produtor ou do consum idor executar um a tarefa. Se occupiedBuffers for zero, buffer está vazio, e o produtor poderá colocar um valor em buffer (linha 34). Essa condição (linha 52) tam bém significa que o consum idor deve esperar (linha 59) no método get para ler o valor de buffer (novamente, porque está vazio). Se occupiedBuffers for 1, o consum idor poderá ler o valor de buffer porque ele contém nova inform ação. Essa condição (linha 16) tam bém significa que o produtor deve esperar para colocar um valor em buffer porque esse está correntem ente cheio. Q uando o m étodo run de threadProducer invoca o m étodo set de synchronized (da linha 26 da Figura 5.2), o thread tenta obter um a trava do m onitor SynchronizedBuffer. [Nota: Q uando falam os em ‘obter um a trava’ em um m onitor Java, quere­ mos dizer ‘conseguir acesso m utuam ente exclusivo a um m onitor’, nas discussões genéricas sobre m onitores na Seção 6.2, “M onitores” .] Se a trava estiver disponível, o thread Producer irá obtê-la. Então o laço no m étodo set (linhas 16-32 da Figura 6.4) determ ina se occupiedBuffers é igual a 1. Se for, buffer estará cheio, portanto a linha 21 produz um a m ensagem indicando que o thread Producer está tentando escrever um valor, e a linha 22 invoca o m étodo displayState (linhas 81-89) para produzir um a outra m ensagem indicando que o buffer está cheio e que o thread Producer está no estado de espera. N ote que o m étodo displayState não é declarado Synchronized, porque é cham ado no método main (linha 18 da Figura 6.5) antes que os threads produtor e consum idor sejam criados e, daí em diante, som ente de dentro dos m étodos Synchronized get e set (linhas 10 e 46 da Figura 6.4). A penas um thread pode executar dentro do m onitor de SynchronizedBuffer por vez, e displayState é acessado som ente de dentro do monitor, portanto, o acesso m utuam ente exclusivo é im posto sem precisar declarar displayState Synchronized. A linha 23 invoca o método wait (herdado de Object por SynchronizedBuffer; todas as classes Java herdam de Object direta ou indiretam ente) para colocar o thread que cham ou o método set (ou seja, o thread Producer) no estado de espera para o objeto SynchronizedBuffer. C ham ar wait leva o thread cham ador a liberar a trava do objeto SynchronizedBuffer, o que é im portante, porque o thread não pode executar sua tarefa no m om ento — e reter a trava im pediría outros threads de acessar o objeto. Isso resultaria em deadlock, porque a variável condicional na qual o prim eiro thread estava à espera não m udaria nunca. Após o thread produtor cham ar wait na linha 23, um outro thread pode tentar obter a trava do objeto SynchronizedBuffer e invocar os m étodos set ou get do objeto — em particular, um thread consum idor agora pode esvaziar o buffer, permitindo eventualmente que o produtor que está à espera prossiga. O thread produtor perm anece no estado de espera até ser notificado por um outro thread de que pode prosseguir — pon­ to em que o thread produtor volta ao estado pronto e espera por um processador. Q uando volta ao estado em execução, o thread produtor im plicitam ente tenta obter de novo a trava do objeto SynchronizedBuffer. Se a trava estiver disponível, o produtor irá readquiri-la e o m étodo set continuará a executar com a instrução seguinte após wait. C om o wait é cham ado em um laço (linhas 15-32), a condição de continuação do laço é testada para determ inar se o thread pode continuar com sua execução. Se não puder, wait é invocado novam ente; caso contrário, o m étodo set continua com a instrução seguinte após o laço. A linha 34 do método set designa o argum ento value a buffer. A linha 38 increm enta occupiedBuffers para indicar que o buffer agora contém um valor (um consum idor pode ler o valor, mas um produtor ainda não pode colocar um outro valor ali). A linha 42 invoca o método notify (herdado de Object). Se o thread consum idor estiver à espera, ele entrará no estado pronto em que pode tentar realizar sua tarefa novam ente (tão logo o thread receba um processador designado). O método notify retom a im ediatam ente, e o método set retom a ao seu chamador. [Nota: Invocar o método notify funciona corretam ente nesse program a, porque apenas um thread cham a o m étodo get a qualquer instante (o thread consum idor). Program as em que há m últiplos threads esperando em um a condição devem invocar notifyAll para garantir que os m últiplos threads recebam notificações adequadamente.] Quando o método set retom a, im plicitam ente libera a trava do objeto SynchronizedBuffer. Os m étodos get e set são im plem entados de m aneira semelhante. Q uando o m étodo run do thread consum idor invoca o método get synchronized (da linha 28 da Figura 5.3), o thread tenta obter um a trava do objeto SynchronizedBuffer. Q uando adquire a trava, o laço while (linhas 5 1 -6 8 da Figura 6.4) determ ina se occupiedBuffers é igual a 0. Se for, o buffer estará vazio, portanto, a linha 57 produzirá um a m ensagem indicando que o thread consum idor está tentando ler um valor e a linha 58 invocará o método displayState para apresentar um a outra m ensagem indicando que o buffer está vazio e que o thread consum idor espera. A linha 59 invoca o método wait para colocar o thread consum idor que cham ou o método get no estado de espera Capítulo 6 Programação concorrente }()$ pelo objeto SynchronizedBuffer. Novamente, a cham ada a w ait obriga o thread cham ador a liberar a trava do objeto SynchronizedBuffer para que um outro thread possa tentar obter a trava e invocar o método sei ou gel do objeto. Se a trava do objeto SynchronizedBuffer não estiver disponível (se o ProducerThread ainda não tiver retom ado do método set), o thread consum idor ficará bloqueado até a trava tom ar-se disponível. O thread consum idor perm anece no estado de espera até ser notificado pelo thread produtor que pode prosseguir — ponto em que o thread consum idor retom a ao estado pronto e espera um processador. Quando volta ao estado em execução, o thread im plicitam ente tenta readquirir a trava do objeto SynchronizedBuffer. Se a trava estiver disponível, o thread consum idor a readquire e get continua executando com a próxim a instrução após w ait. Com o wait é cham ado em um laço (linhas 51-6 8 ), a condição de continuação do laço é testada para determ inar se o thread pode prosseguir. Se não puder, wait é invocado novamente; caso contrário o método get continua com a próxim a instrução após o laço. A linha 72 decrem enta occupiedBuffers para indicar que buffer agora está vazio, a linha 74 produz um a linha na janela do console indicando o valor que o consum idor acabou de ler, e a linha 76 invoca o método no tify. Se o thread produtor estiver esperando pela trava do objeto SynchronizedBuffer, ele entrará no estado pronto. Assim que lhe for designado um processador, o thread tentará readqui­ rir a trava e continuar realizando sua tarefa. O método no tify retom a im ediatam ente e o método get retom a o valor de buffer para seu cham ador (linha 78). [Nota: Novamente, invocar o método no tify funciona corretam ente nesse program a porque som ente um thread cham a o m étodo set em qualquer dado instante (o thread produtor)]. Q uando o método get retom a, a trava do objeto SynchronizedBuffer é liberada. A classe SharedBufferTest2 (Figura 6.5) é semelhante à classe SharedBufferTest (Figura 5.5). SharedBufferTest2 contém o método main (linhas 6-27), que lança a aplicação. A linha 9 instancia um SynchronizedBuffer com partilhado e designa sua referência à variável sharedLocation de SynchronizedBuffer. Usam os uma variável SynchronizedBuffer em vez de um a variável Buffer, para que main possa invocar o m étodo displayState de SynchronizedBuffer, não declarado na interface Buffer. O objeto SynchronizedBuffer arm azena os dados com partilhados entre os threads produtor e consumidor. As linhas 11-18 exibem os cabeçalhos das colunas para a saída de resultados. As linhas 2 1 -2 2 criam um objeto Producer e um objeto Consumer, respectivam ente, e passam sharedLocation para cada construtor, de modo que cada objeto seja inicializado com um a referência ao mesmo SynchronizedBuffer. Em seguida, as linhas 2 4 -2 5 invocam o método start nos threads producer e consumer para colocá-los no estado pronto, o que lança esses threads e estabelece a cham ada inicial ao método run de cada thread. Por fim, o método main term ina e o thread principal de execução morre. Estude as três am ostras de resultados da Figura 6.5. O bserve que cada inteiro produzido é consum ido exatam ente um a vez. A sincronização e a variável occupiedBuffers asseguram que o produtor e o consum idor som ente possam executar quando for a sua vez. O produtor deve ir prim eiro; o consum idor deve esperar caso o produtor ainda não tenha produzido desde a últim a vez que o consum idor consum iu; o produtor deve esperar caso o consum idor ainda não tenha consum ido o valor que o produtor produziu m ais recentem ente. N a prim eira e segunda am ostras de resultados, note os com entários que indicam quando produtor e consum idor devem esperar para realizar suas tarefas respectivas. N a terceira am ostra de resultados, observe que o produtor e o consum idor conseguiram , fortuitam ente, realizar suas tarefas sem esperar. R et/U ã# 1. Por que o método displayState não precisa ser declarado com o synchronized? (V/F) Se o método no tify nunca for cham ado no método get, o produtor nunca term inará de produzir, porque será adiado indefinidam ente na linha 23 da Figura 6.4. 2. R eipoitãi: 1 ) Em bora occupiedBuffers seja um recurso com partilhado, a única vez que displayState é cham ado é dentro de m étodos synchronized ou quando o program a contém som ente um thread. 2 ) Falso. É possível que o buffer nunca fique cheio, situação em que o produtor nunca executará a linha 23. Esse é o caso do terceiro resultado da Figura 6.5. 1 2 3 4 5 6 // Fig. 6.5: SharedBufferTest2.java // SharedBufferTest2 cria threads produtor e consumidor. public class SharedBufferTest2 { public static void main( String [ ] args ) uroy G.5 TkreaxU nwdLjtcarÁo une objeto compartilkaÁo cone sincronização (parte 1de 3). J66 S titw u u operncíôKAà 7 8 9 10 11 12 13 14 15 16 17 18 19 // cria objeto compartilhado usado por threads SynchronizedBuffer sharedLocation = new SynchronizedBuffer!); //A presenta cabeçalhos de colunas para saída de resultados StringBuffer columnHeads = new StringBuffer! "O p e ra çã o "); columnHeads.setLength! 4 0 ); columnHeads.append! "Buffer\t\tContagem de Ocupados" ); System.err.println! colum nHeads); System .err.println!); sharedLocation.displayState! "Estado Inicial" ); 20 // cria objetos produtor e consumidor Producer producer = new Producer! sharedLocation ); Consumer consumer = new Consumer! sharedLocation ); 21 22 23 24 25 26 27 28 29 producer.start!); // inicie thread produtor consum er.start!); // inicie thread consumidor } //te rm in e main } / / termine classe SharedBufferTest2 A u to s tr o s R & íu lta A ô 1: Operação Buffer C Estado Inicial -1 0 Buffer vazio. Consumidor espera. -1 0 Produtor escreve 1 1 1 Consumidor lê 1 1 0 Buffer vazio. Consumidor espera. 1 0 Produtor escreve 2 2 1 Consumidor lê 2 2 0 Produtor escreve 3 3 1 Consumidor lê 3 3 0 Buffer vazio. Consumidor espera. 3 0 Produtor escreve 4 4 1 Consumidor lê 4 4 0 Consumidor tenta ler. Consumidor tenta ler. Consumidor tenta ler. Produtor encerra produção. Terminando Produtor. Consumidor lê valores totalizando: 10. Terminando Consumidor. 'urcu 6.5 TkreaxU wácLifiauulo iam objeto MnipartUkaÁo com, sincronização (/tarte, 2 de, 3). Ca^vtvdo 6 Programação concorrente, tf) / Amostra^ de> R&sultaÁo 2: Operação Buffer Contagem de ocupados Estado Inicial -1 0 Buffer vazio. Consumidor espera. -1 0 Produtor escreve 1 1 1 Consumidor lê 1 1 0 Produtor escreve 2 2 1 Buffer cheio. Produtor espera. 2 1 Consumidor lê 2 2 0 Produtor escreve 3 3 1 Consumidor lê 3 3 0 Produtor escreve 4 4 1 4 0 Operação Buffer Contagem de ocupados Estado Inicial -1 0 Produtor escreve 1 1 1 Estado Inicial -1 0 Produtor escreve 1 1 1 Consumidor lê 1 1 0 Produtor escreve 2 2 1 Consumidor lê 2 2 0 Produtor escreve 3 3 1 Consumidor lê 3 3 0 Produtor escreve 4 4 1 4 0 Consumidor tenta ler. Produtor tenta escrever. Produtor encerra produção. Terminando Produtor. Consumidor lê 4 Consumidor lê valores totalizando: 10. Terminando Consumidor. Amostra, de, VxsuitaÁo 3: Produtor encerra produção. Terminando Produtor. Consumidor lê 4 Consumidor lê valores totalizando: 10. Terminando Consumidor. 'tera, 6.5 \ Tkreads modificando tem, objeto compartilhado com, sincronização (parte, 3 de, 3). 6.5 Estado de, ccuso de,Jaza, multvthvead Parte, tV : bufifiev circular em,Jaza > O program a da Seção 6.4 utiliza sincronização de threads para garantir que dois threads m anipulem dados corretam en­ te em um buffer com partilhado. Contudo, a aplicação pode não funcionar otim am ente. Se dois threads funcionarem em 168 Sistemas opernciôKAÍs velocidades diferentes, um deles gastará m ais tem po (ou quase todo seu tempo) esperando. Se o thread produtor produzir valores m ais rapidam ente do que o consum idor puder consum i-los, o produtor passará a m aior parte do seu tempo espe­ rando pelo consumidor. Similarmente, se o consum idor consum ir com mais rapidez do que o produtor puder produzi-los, o consum idor passará a m aior parte do seu tempo esperando pelo produtor. M esm o quando os threads funcionam nas mesmas velocidades relativas, ocasionalm ente podem ficar ‘fora de sincronia’ durante um certo período de tem po, o que obriga um deles a esperar pelo outro. N ão podem os e não devemos fazer conjecturas sobre as velocidades relativas de threads concorrentes assíncronos. Ocorrem muitas interações com o sistem a operacional, com a rede, com o usuário e com outros com ponentes do sistem a que podem fazer que os threads operem a velocidades diferentes e imprevisíveis. Q uando isso acontece no exem plo do produtor/consum idor, um thread deve esperar. Q uando threads passam um a parte significativa do seu tempo a esperar, program as podem ficar menos eficientes, o sistem a pode ficar menos responsivo a usuários interativos e aplicações podem sofrer longos atrasos, porque o processador não é usado com eficiência. Já vimos neste capítulo que, para m inim izar o tempo de espera para threads que com partilham recursos e funcionam com as mesmas velocidades m édias, podem os im plem entar um buffer circular que fornece entradas extras de buffer nas quais o produtor pode colocar valores quando estiver executando mais rapidam ente do que o consumidor, e das quais o consum idor pode recuperar esses valores quando estiver executando m ais rapidam ente do que o produtor. A chave da utilização de um buffer circular é lhe dar suficientes entradas de buffer para m anipular a produção ‘extra’ esperada. Se determ inarm os que durante um período de tempo o produtor freqüentem ente produz até três vezes mais valores do que o consum idor pode consumir, podem os equipar um buffer com três ou m ais entradas para dar vazão à produção extra. Se o núm ero de entradas do buffer for muito pequeno, os threads esperarão mais; se for m uito grande, desperdiçaria memória. O program a Java das figuras 6.6 e 6.7 dem onstra um produtor e um consum idor acessando um buffer circular (nesse caso, um arranjo com partilhado de três células) com sincronização. N essa versão do relacionam ento produtor/consum idor, o consum idor consom e um valor somente quando o arranjo não estiver vazio, e o produtor produz um valor som ente quando o arranjo não estiver cheio. A classe Producer foi ligeiram ente modificada em relação à versão apresentada na Figura 5.2; essa nova versão produz valores de 11 a 20 (em vez de 1 a 4). A classe Consumer sofreu um a ligeira modificação em relação à versão da Figura 5.3; essa nova versão consom e 10 valores (em vez de 4) do buffer circular. As m udanças significativas das figuras 6.4 e 6.5 ocorrem em CircularBuffer (Figura 6.6), que substitui SynchronizedBuffer (Figura 6.4). GrcularBuffer contém quatro campos. Arranjo buffers (linha 8) im plem enta o buffer circular com o um arranjo de inteiros de três elem entos. A variável occupiedBuffers (linha 11) é a variável condicional que pode ser usada para determ inar se um produtor pode escrever no buffer circular (ou seja, quando occupiedBuffers for m enor do que o núm ero de elem entos em buffers) e se um consum idor pode ler de um buffer circular (isto é, quando occupiedBuffers for m aior do que 0). A variável readLocation (linha 14) indica a posição em buffers da qual o valor seguinte pode ser lido por um consumidor. A variável writeLocation (linha 15) indica a localização seguinte em buffers na qual um produtor pode colocar um valor. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Fig. 6.6: CircularBuffer.java // CircularBuffer sincroniza acesso a um arranjo de // buffers compartilhados. public class CircularBuffer implements Buffer { // cada elemento do arranjo é um buffer private int buffers! ] = {-1, -1, -1 }; // occupiedBuffers mantém contagem de buffers ocupados private int occupiedBuffers = 0; // variáveis que mantêm localizações ler e escrever do buffer private int readLocation = 0; private int writeLocation = 0; // coloque valor dentro do buffer public synchronized void set( int value ) 'ura, G. G SynchronizedBuffer controla,acesso a, u n e arrastjo compartilhado de, inteiros (parte, 1 de, 4). Capítulo 6 Programação concorrente 19 20 21 // obtenha nome do thread que chamou este método String name = Thread.currentThread( ).getN am e(); 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 // enquanto o buffer estiver cheio, coloque o thread em estado de espera while ( occupiedBuffers == buffers.length ) { // apresente informação de thread e buffer, então espere try { System.err.printlnf "\nTodos os buffers cheios. " + name + " espera." ); waitO; // espere até espaço estar disponível } / / termine try //s e thread à espera interrompido, imprima cópia de pilha catch ( InterruptedException exception ) { exception.printStackTraceO; } // termine catch } // termine while // coloque valor em writeLocation de buffers buffers! writeLocation ] = value; // apresente valor produzido System.err.printlnf "\n " + name + " escreve " + buffers! writeLocation ] + " " ); // indique que um ou mais buffers estão ocupados ++occupiedBuffers; // atualize writeLocation para futura operação de escrita writeLocation = ( writeLocation + 1 ) % buffers.length; // apresente conteúdo de buffers compartilhados System.err.printlnf createStateO utputf)); n o tify f); // retorne um thread à espera para o estado pronto } // termine método set // retorne valor do buffer public synchronized int g e tf) { // obtenha nome do thread que chamou este método String name = Thread.currentThreadf J.getNamef); 66 67 68 69 70 71 72 73 74 // enquanto o buffer estiver vazio, coloque thread em estado de espera while ( occupiedBuffers == 0 ) { // apresente informação de thread e buffer, então espere try { System.err.printlnf "\nTodos os buffers vazios. " + name + " e s p e ra ."); ura, G. G SynchronizedBuffer controlcu acesso a, imc arranjo MMpartLlkaAo de, inteiros (parte, 2 de, 4). Jf)Ç 170 75 76 77 78 79 80 81 82 83 84 85 86 87 Sistemas o^eraxíonats w a it(); // espere até buffer conter novos dados } / / termine try // se thread à espera estiver interrompido, imprima cópia de pilha catch ( InterruptedException exception ) { exception.printStackTracel ); } / / termine catch } / / termine while // obtenha valor em readLocation corrente int readValue = buffersl readLocation ]; 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 // apresente valor consumido System.err.printlnl "\n " + name + " lê " + readValue + " " ); // decremente valor de buffers ocupados - - occupiedBuffers; // atualize readLocation para futura operação de leitura readLocation = ( readLocation + 1 ) % buffers.length; // apresente conteúdo de buffers compartilhados System.err.printlnf createStateO utputl)); n o tify f); // retorne um thread à espera para estado pronto return readValue; } // termine método get // crie saída de estado public String createStateOutputO { // primeira linha de informação de estado String output = "(buffers ocupados: " + occupiedBuffers + "Anbuffers: for ( int i = 0; i < buffers.length; + + i) { output += " " + buffersl i ] + " "; } / / termine for // segunda linha de informação de estado output += "\n "; for ( int i = 0; i < buffers.length; + + i ) { output += " -------"; } / / termine for // terceira linha de informação de estado output += "\n "; // anexe indicadores readLocation (R) e writeLocation (W) fu ju rtu G. G SynchronizedBuffer controla, acesso a um arranjo coui^artilkaÁo de, inteiros ('parte, 3 de, 4). Ca^vtvdo 6 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 Programação concorrente. 171 // abaixo das localizações apropriadas de buffer for ( int i = 0; i < buffers.length; + + i ) { if ( i == writeLocation && writeLocation == readLocation ) { output += " WR } // termine if else if ( i == writeLocation ) { output += " W } // termine if else if ( i == readLocation ) { output += " R } // termine if else { output += " } / / termine else } // termine for output += "\n "; retum output; } // termine método createStateOutput } / / termine classe CircularBuffer fig u ra , G.G SynchronizedBuffer controla, acesso a, um, arranjo compartilkaÁo de, inteiros (parte, 4 de, 4). O m étodo set de GrcularBuffer (linhas 17-59) realiza as m esm as tarefas que o SynchronizedBuffer da Figura 6.4, com algumas modificações. O laço while nas linhas 23^10 determ ina se o produtor deve esperar (ou seja, todos os buffers estão cheios). Se tiverem de esperar, as linhas 2 9 -3 0 m ostram que o produtor está à espera para realizar sua tarefa. Então a linha 31 invoca o método wait para colocar o thread produtor no estado de espera pelo objeto GrcularBuffer. Q uando a execução eventualmente continuar na linha 43 depois do laço while, o valor escrito pelo produtor será colocado no buffer circular na localização writeLocation. Em seguida as linhas 4 6 -4 7 em item o valor produzido. A linha 50 increm enta OccupiedBuffers — agora há no m ínim o um valor no buffer que o consum idor pode ler. Então, a linha 53 atualiza writeLocation para a próxim a cham ada ao método set de GrcularBuffer. A saída continua na linha 56 invocando o método createStateOutput (linhas 107-157) que apresenta o núm ero de buffers ocupados, o conteúdo dos buffers e writeLocation e readLocation correntes. Por fim, a linha 58 invoca o método notify para indicar que o thread consum idor que está à espera no objeto GrcularBuffer (se, de fato, o consum idor estiver esperando) deve prosseguir. O método get (linhas 61-105) da classe GrcularBuffer tam bém realiza as mesmas tarefas que realizava na Figura 6.4, com algum as poucas modificações. O laço while nas linhas 6 7 -8 4 determ ina se o consum idor deve esperar (ou seja, todas as entradas do buffer estão vazias). Se o thread consum idor tiver de esperar, as linhas 7 3 -7 4 indicarão que o consum idor está à espera para realizar sua tarefa. A linha 75 invoca o método wait para colocar o thread consum idor no estado de espera pelo objeto GrcularBuffer. Quando a execução eventualm ente continuar na linha 87 após o laço while, o valor de readValue será determ inado na localização readLocation do buffer circular. As linhas 90-91 em item o valor consumido. A linha 94 decrementa OccupiedBuffers — agora há no m ínim o um a posição aberta no buffer na qual o thread produtor pode colocar um valor. Então a linha 97 atualiza readLocation para a próxim a cham ada ao método get de GrcularBuffer. A linha 100 invoca o m étodo createSta­ teOutput para em itir o núm ero de buffers ocupados, o conteúdo dos buffers e writeLocation e readLocation correntes. Finalm ente a linha 102 invoca o método notify para indicar que o thread produtor que está esperando pelo objeto GrcularBuffer (se, de fato, houver um produtor esperando) deve prosseguir, e a linha 104 retom a o valor consum ido ao m étodo chamador. N ote que, com o Java im plem enta m onitores do tipo sinalize-e-continue, esse program a não requer o parâm etro de saída discutido na Seção 6.2.3, “Exem plo de monitor: buffer circular” . m Sistemas operacionais A classe GrcularBufferTest (Figura 6.7) contém o método main (linhas 8 -2 4 ) que lança a aplicação. A linha 13 cria o ob­ jeto sharedLocation de CircularBuffer. As linhas 19-20 criam os threads producer e consumer, e as linhas 22-23 os iniciam. Entre as am ostras de saídas estão occupiedBuffers correntes, o conteúdo dos buffers e writeLocation e readLocation correntes. As letras W e R na saída representam writeLocation e readLocation correntes, respectivamente. Note que, depois de o terceiro valor ser colocado no terceiro elem ento do buffer, o quarto valor é reinserido no início do arranjo — esse é o efeito do buffer circular. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // Fig. 6.7: CircularBufferTest.java // CircularBufferTest mostra dois threads manipulando um // buffer circular. // estabeleça os threads producer e consumer e os inicie public class CircularBufferTest { public static void main ( String args[ ]) { // crie objeto compartilhado para threads; use uma referência // a um CircularBuffer e não uma referência a Buffer // para invocar método createStateOutput do CircularBuffer CircularBuffer sharedLocation = new C ircularBuffer!); // apresente o estado inicial dos buffers em CircularBuffer System.err.printlnf sharedLocation.createStateOutputl)); // estabeleça threads Producer producer = new Producer) sharedLocation ); Consumer consumer = new Consumer! sharedLocation ); producer.startO; // inicie thread producer consumer.startO; // inicie thread consumer } / / termine main } // termine classe CircularBufferTest Autostra, de, Saída,: (buffers ocupados: 0) buffers: -1 -1 -1 WR Todos os buffers vazios. Consumidor espera. Produtor escreve 11 (buffers ocupados: d buffers: 11 -1 R W Consumidor lê 11 (buffers ocupados: 0) -1 buffers: 11 WR fu ju r a , G. 7 CircularBufferTest instancia, threads produtor e, consumidor (parte, 1 d& 4). Capítulo 6 Amostras cU saída, (Cont.): Produtor escreve 12 (buffers ocupados: 1) buffers: 11 12 R Produtor escreve 13 (buffers ocupados: 2) buffers: 11 12 W -1 W 13 R Consumidor lê 12 (buffers ocupados: 1) buffers: 11 12 W 13 R Produtor escreve 14 (buffers ocupados: 2) buffers: 14 12 W Produtor escreve 15 (buffers ocupados: 3) buffers: 14 15 13 R 13 WR Todos os buffers cheios. Produtor espera. Consumidor lê 13 (buffers ocupados: 2) buffers: 14 15 R 13 W Produtor escreve 16 (buffers ocupados: 3) buffers: 14 15 16 WR Todos os buffers cheios. Produtor espera. Consumidor lê 14 (buffers ocupados: 2) buffers: 14 15 W 16 R Produtor escreve 17 (buffers ocupados: 3) buffers: 17 15 16 WR Pigurcb G.7 CircularBufferTest instancia, tkreaoU produtor e, cotuumidor (parte 2 d& 4). Programação concorrente ffg 174 S is te m a s o p e ra c io n a is Amostra, de, Saída, (Cokí.): Consumidor lê 15 (buffers ocupados: 2) buffers: 17 15 16 W R Consumidor lê 16 (buffers ocupados: d buffers: 17 15 R 16 W Consumidor lê 17 (buffers ocupados: 0) buffers: 17 15 16 WR Produtor escreve 18 (buffers ocupados: 1) buffers: 17 18 R Consumidor lê 18 (buffers ocupados: 0) buffers: 17 18 16 W 16 WR Todos os buffers vazios. Consumidor espera. Produtor escreve 19 (buffers ocupados: 1) buffers: 17 18 W 19 R Consumidor lê 19 (buffers ocupados: 0) buffers: 17 18 19 WR Produtor escreve 20 (buffers ocupados: 1) buffers: 20 18 R 19 W Produtor encerra produção. Terminando Produtor. Pujura, 6.7 CircularBufferTest instasicia, tkreads produtor e,consumidor (parte, 3 de, 4). Ca^vtvdo 6 Programação concorrente, / / £ Antôstrcu de, Saída, (Cotit.): Consumidor lê 20 (buffers ocupados: 0) buffers: 20 18 19 WR Consumidor lê valores totalizando: 155. Terminando Consumidor. fig u ra , 6.7 CircularBufferTest instando, threads produtor e, consumidor (parte, 4 de, 4). R m ã» 1. Q uais os custos e benefícios potenciais de aum entar o tam anho de um buffer? 2. O que aconteceria se a linha 102 da Figura 6.6 fosse omitida? \pO itcii 1 1) O benefício potencial é que o produtor pode produzir mais e bloquear menos se o consum idor for tem po­ rariam ente m ais lento do que o produtor. Contudo, isso podería resultar em m em ória desperdiçada se am bos, consum idor e produtor, trabalhassem à m esma velocidade, se um deles trabalhasse muito mais rapidam ente do que o outro ou se o produtor raram ente se adiantasse tanto ao consum idor (se é que isso aconteça algum a vez) que pudesse tirar vantagem do espaço extra. 2) O thread consum idor concluiría sem em itir o notify. Se o produtor fortuitam ente nunca esperar pelo consum idor (o que é, na verdade, um a ocorrência rara) o sistem a funcionará corretam ente. O que m ais acontece, no entanto, é que se o produtor estiver à espera, ele nunca poderá prosseguir, isto é, o produtor poderá sofrer deadlock. Resumo Program as concorrentes são m ais difíceis de escrever, depurar, m odificar e de provar que estão corretos do que os não concorrentes. Não obstante, tem havido um a onda de interesse em linguagens de programação concorrente, porque nos habilitam a expressar mais naturalm ente soluções para problem as paralelos. A proliferação de sistem as m ultiprocessadores, sistemas distribuídos e arquiteturas maciçamente paralelas tam bém alim entaram essa onda. Um m onitor é um objeto que contém dados e procedi­ mentos necessários para realizar alocação de um ou mais recursos com partilhados reutilizáveis serialmente. Dados do monitor são acessíveis somente dentro do monitor; os threads que estão fora do m onitor não dispõem de nenhum modo para acessar os dados do m onitor diretam ente. Para reali­ zar um a função de alocação de recurso usando m onitores, um thread deve cham ar um a rotina de entrada no monitor. M uitos threads podem querer entrar no m onitor em vários m omentos, mas a exclusão m útua é rigidam ente im posta na fronteira do monitor. Um thread que tentar entrar no monitor quando esse estiver em uso será obrigado a esperar. Eventualm ente o thread que tem o recurso cham ará uma rotina de entrada no m onitor para devolver o recurso. Pode haver threads esperando pelo recurso, portanto a rotina de entrada no m onitor cham a signal para perm itir que um dos threads à espera obtenha o recurso e entre no monitor. Para evitar adiam ento indefinido, o m onitor dá prioridade mais alta a threads que estão esperando do que àqueles que aca­ baram de chegar. A ntes de um thread poder entrar novam ente no monitor, o thread que está cham ando signal deve prim eiram ente sau­ do monitor. Um m onitor do tipo sinalize-e-saia (signal-andexit) requer que um thread saia imediatamente do monitor ao sinalizar. Altem ativam ente, um m onitor sinalize-e-continue (signal-and-continue) permite que um thread que está dentro do m onitor sinalize que esse logo estará disponível, mas ainda m antenha um a trava no m onitor até que o thread saia dele. Um thread pode sair do m onitor esperando em uma variável condicional ou concluindo a execução do código protegido pelo monitor. Um thread que está correntem ente dentro de um m oni­ tor poderá ter de esperar fora dele até que um outro thread execute um a ação no monitor. U m m onitor associa um a variável condicional separada a cada situação distinta que podería forçar um thread a esperar. Toda variável condicional tem um a fila associada. Um thread que estiver cham ando wait em um a variável condicional particular será colocado na fila associada àquela variável condicional; um thread que estiver cham ando signal em um a variável condicional 176 S titw u u operncíôKAà particular fará que um thread que esteja à espera naquela variável condicional (se houver tal thread) seja retirado da fila associada àquela variável e entre no monitor. N a im plem entação da solução do problem a produtor/ consum idor com buffer circular, o produtor deposita dados nos elem entos sucessivos do arranjo com partilhado. O consum idor os retira na ordem em que foram depositados (FIFO ). O produtor pode estar vários itens à frente do consum idor e eventualm ente preencher o últim o elemento do arranjo. Q uando produzir m ais dados precisará ‘fazer a volta’ e recom eçar a depositar dados no prim eiro elemento do arranjo. Devido ao tamanho fixo do buffer circular, o produtor ocasional mente encontrará todos os elem entos do arranjo cheios; nesse caso deve esperar até que o consum idor es­ vazie um elem ento do arranjo. Sim ilarm ente, às vezes o consum idor desejará consumir, mas o arranjo estará vazio; nesse caso o consum idor deve esperar até que o produtor deposite dados em um elem ento do arranjo. Se dois threads funcionarem em velocidades diferentes, um deles gastará m ais tem po (ou até a m aior parte do seu tempo) a esperar. Se o thread produtor produzir valores mais rapidam ente do que o consum idor puder consum i-los, ele passará a m aior parte do seu tempo esperando que o consu­ m idor retire o próxim o valor do conjunto. Sim ilarm ente, se o thread consum idor consum ir valores mais rapidam ente do que o produtor puder produzi-los, ele passará a m aior parte do seu tempo esperando que o produtor coloque o próxim o valor no conjunto. Em sistemas de computador, é com um ter alguns threads que leem dados (denominados leitores) e outros que os es­ crevem (denominados escritores). Com o leitores não mudam o conteúdo de um banco de dados, m uitos deles podem ter acesso ao banco de dados ao mesmo tempo. M as um escritor pode modificar os dados, portanto, deve ter acesso exclusivo. Um novo leitor pode prosseguir contanto que nenhum thread esteja escrevendo e nenhum thread escritor esteja à espera para escrever. Cada novo leitor sinaliza ao próxim o leitor à espera para prosseguir, o que causa um a ‘reação em cadeia’ que continuará até que todos os leitores à espera tenham se tom ado ativos. Enquanto essa cadeia estiver avançando, todos os threads que chegam são forçados a esperar. Durante esse encadeam ento os leitores que chegarem não poderão entrar no monitor, porque esse cum pre a regra de atender a threads sinalizados antes de threads que estão chegando. Se fosse perm itido que os leitores que chegam prosseguissem , um fluxo contínuo de leitores causaria o adiamento indefini­ do dos escritores que estão à espera. Q uando o últim o leitor sai do monitor, o thread sinaliza a um escritor à espera para ele prosseguir. Quando um escritor termina, prim eiram ente verifica se há algum leitor esperando. Se houver, o leitor à espera prossegue (o que provoca novam ente um efeito cascata em todos os leitores que estão à espera). Se não houver nenhum leitor esperando, um escritor à espera obterá perm issão para prosseguir. M onitores é o m ecanism o primário para fornecer exclu­ são m útua e sincronização em aplicações Java multithread. A palavra-chave synchronized im põe exclusão m útua em um objeto em Java. M onitores Java são do tipo sinalize-e-continue, perm itindo que um thread sinalize que o m onitor logo ficará disponível, mas ainda mantenha uma trava no monitor até o thread sair dele. Em Java, o método wait obriga o thread chamador a liberar a trava do monitor e esperar em uma variável condicional não denom inada. Depois de cham ar wait, um thread é colocado no conjunto de espera onde perm anece até ser sinalizado por um outro thread. Com o a variável condicional é im plícita em Java, um thread pode ser sinalizado, entrar novamente no m onitor e constatar que a condição pela qual esperou não foi cumprida. Threads em item sinais cham ando o método no tify ou o m étodo notifyA ll. O método no tify acorda um único thread do conjunto de espera. Se mais de dois threads puderem acessar um monitor, será m elhor usar o método notifyAll que acorda todos os threads no conjunto de espera. Com o notifyAll acorda todos os threads que estão tentando entrar no m onitor (em vez de um único thread), no tify pode render um desem penho m ais alto em algum as aplicações. Exercícios 6.1 Quais as semelhanças e diferenças entre a utilização de monitores e de semáforos? 6.2 Quando um recurso é devolvido por um thread que está chamando um monitor, este dá prioridade a um thread à espera em detrimento de um novo thread que está requisitando. Por quê? 6.3 Quais as diferenças entre variáveis condicionais e variáveis convencionais? Faz sentido inicializar variáveis condicionais? 6.4 O texto afirmou repetidas vezes que não se deve fazer nenhuma conjectura sobre as velocidades relativas de threads concorrentes assíncronos. Por quê? 6.5 Quais fatores você acha que afetariam a escolha de um projetista quanto ao número de entradas que um buffer circular deveria ter? 6.6 Por que é consideravelmente mais difícil testar, depurar e pro­ var a correção de programas concorrentes do que seqüenciais? 6.7 O capítulo afirma que ocultação de informações é uma técni­ ca de estruturação de sistemas que contribui para o desenvolvimento de sistemas de software mais confiáveis. Na sua opinião, por que isso acontece? 6.8 Referindo-se ao monitor descrito na Figura 6.2, responda às seguintes perguntas: a. Qual procedimento coloca dados no buffer circular? b. Qual procedimento retira dados do buffer circular? c. Qual disciplina de enfileiramento descreve melhor a operação do buffer circular? d . Isto é verdade: writerPosition>=readerPosition? Ca^vtvdo 6 e. Quais instruções executam a inicialização do monitor? f. Qual instrução (ou instruções) pode ‘acordar’ um thread que está esperando em uma variável condicional? g. Qual instrução (ou instruções) pode pôr um thread ‘para dormir’? h. Qual instrução (ou instruções) garante que um buffer ‘faça a volta’? i. Qual instrução (ou instruções) modifica uma variável crítica compartilhada para indicar que uma outra entrada do buffer está disponível? 6.9 No monitor de leitores e escritores apresentado na Figura 6.3, por que faz sentido provocar efeito cascata em todos os leito­ res à espera? Isso podería causar adiamento indefinido aos leitores à espera? Sob quais circunstâncias você podería preferir limitar o número de leitores à espera que seriam inicializados quando a leitura fosse permitida? 6.10 (O Problema do Barbeiro Adormecido)45Uma barbearia tem um salão de corte com uma cadeira de barbeiro e uma sala de espera com n cadeiras. Os clientes entram na sala de espera um por vez se houver espaço disponível, senão vão a outra barbearia. Toda vez que o barbeiro termina o corte de um cabelo, o cliente sai e vai a outra loja, e um cliente que está esperando (se houver algum) entra no salão de corte e corta seu cabelo. Os clientes podem entrar na sala de espera um por vez, ou aqueles que estão esperando podem entrar no salão de corte (vazio) um por vez, mas esses eventos são mutuamente exclusivos. Se o barbeiro vir que a sala de espera está vazia, tira uma soneca ali mesmo. Quando um cliente chega e vê que o barbeiro está dormindo, ele o acorda e corta o cabelo, ou então espera. Use um monitor para coordenar a operação do Programação concorrente, ffj barbeiro e dos clientes. Se você conhecer Java, implemente seu monitor também em Java. 6.11 (O Problema dos Fumantesj46 [Nota: Um dos autores, HMD, trabalhou com S. Patil e Jack Dennis no Computation Structures Group do Projeto Mac do M.I.T.] Este problema tomou-se um clássico do controle da concorrência. Três fumantes são represen­ tados pelos threads S 1, S2 e S3. Três vendedores são representados pelos threads V I, V2, e V3. Para fumar, cada fumante precisa de tabaco, um envoltório para o tabaco e um fósforo; quando esses recursos estão disponíveis, o fumante fuma seu cigarro até o fim e fica livre para fumar novamente. SI tem tabaco, S2 tem envoltórios para tabaco, e S3 tem fósforos. VI fornece tabaco e envoltórios, V2 fornece envoltórios e fósforos, e V3 fornece fósforos e tabaco. V I, V2, e V3 trabalham em regime de exclusão mútua; somente um desses threads pode funcionar por vez, e o próximo vendedor não pode funcionar até que os recursos fornecidos pelo vendedor anterior tenham sido consumidos pelo fumante. Use um monitor para coordenar a operação dos threads fumante e vendedor. 6.12 Semáforos são no mínimo tão poderosos quanto monitores. Mostre como implementar um monitor usando semáforos. 6.13 Use semáforos para resolver o problema dos escritores e leitores. 6.14 Implemente o problema dos leitores e escritores. Modele sua solução segundo a solução de leitores e escritores da Figura 6.2 e a solução de buffer circular em Java das figuras 6.6 e 6.7. 6.15 Um thread que está à espera deve receber prioridade sobre um thread que está tentando entrar pela primeira vez em um monitor? Qual esquema de prioridade (se houver algum) deve ser imposto aos threads que estão esperando? Projeto sugerido 6.16 Elabore um estudo de pesquisa sobre programação concor­ rente em consoles de videogame. O hardware fornece primitivas de exclusão mútua ao programador da aplicação? Simulação sugerida/ 6.17 Estenda a solução produtor/consumidor sem um buffer circular, apresentada na Figura 6.1 para manipular múltiplos produtores. Notas 1. 2. 3. 4. “Rationale for the design of the Ada programming language”, ACM SIGPLAN Noticest v. 14, nQ6, jun. 1979, parte B. O. S. F. Carvalho e G. Roucairol, “On mutual exclusion in Computer networks”, Communications o f the ACM, v. 26, nfi 2, fev. 1983, p. 146-147. B. Liskov e R. Scheifler, “Guardians and actions: linguistic support for robust, distributed programs”, ACM Transactions on Programming Languages and Systems, v. 5, nQ3, 1983, p. 381-404. S. M. Shatz, “Communication mechanisms for programming distributed Systems”, Computer, v. 17, nc 6, jun. 1984, p. 21-28. 5. 6. 7. 8. D. A. Fisher e R. M. Weatherly, “Issues in the design of a distributed operating system for Ada”, Computer, v. 19, nQ 5, maio 1986, p. 38-47. B. H. Liskov, M. Herlihy e L. Gilbert, “Limitations of synchronous communication with static process structure in languages for distributed computing”, Proceedings o f the 13th ACM Symposium on Principies o f Programming Ixmguagesy St. Petersburg, FL, jan. 1986. S. M. Shatz e J. Wang, “Introduction to distributed-software engineering”, Computer, v. 20, na 10, out. 1987, p. 23-32. E. S. Roberts, A. Evans Jr., C. R. Morgan e E. M. Clarke, “Task management in Ada — a criticai evaluation for real- 178 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. S U tw u is o jte ra c io fu iti time multiprocessors”, Software: Practice and Experience, v. 11, nfl 10, out. 1981, p. 1019-1051. K. W. Nielsen e K. Shumate, “Designing large real-time Systems with Ada”, Communications ofthe ACM, v. 30, n2 8, ago. 1987, p. 695-715. R. Ford, “Concurrent algorithms for real-time memory management”, IEEE Software, v. 5, n2 5, set. 1988, p. 10-24. “Preliminary Ada Reference Manual”, ACM SIGPLAN Notices, v. 14, n2 6, jun. 1979, parte A. R Brinch Hansen, ‘The programming language concurrent Pascal”, IEEE Transactions on Software Engineering, v. SE-1, n2 2, jun. 1975, p. 199-207. D. Coleman, R. M. Gallimore, J. W. Hughes e M. S. Powell, “An assessment of concurrent Pascal”, Software: Practice and Experience, v. 9, 1979, p. 827-837. P. Brinch Hansen, “Distributed processes: a concurrent programming concept”, Communications o f the ACM, v. 21, n2 11, nov. 1978, p. 934-941. N. H. Gehani e W. D. Roome, “Concurrent C”, Software: Practice and Experience, v. 16, n2 9, 1986, p. 821-844. R. B. K ieburtz e A. S ilberschatz, “Com m ents on ‘communicating sequential processes’”, ACM Transactions on Programming Languages and Systems, v. 1, n2 2, 1979, p. 218-225. C. A. R. Hoare, Communicating sequential processes. Englewood Cliffs, NJ: Prentice Hall, 1985. J. Hoppe, “A simple nucleus written in modula-2: a case study”, Software: Practice and Experience, v. 10, n2 9, set. 1980, p. 697-706. N. Wirth, Programming in modula-2. Nova York: SpringerVerlag, 1982. J. W. L. Ogilvie, Modula-2 programming. Nova York: McGraw-Hill, 1985. J. R. McGraw, “The VAL language: description and analysis”, ACM Transactions on Programming Languages, v. 4, n2 1, jan. 1982, p. 44-82. R. P. Cook, “ *MOD — A language for distributed programming”, IEEE Transactions on Software Engineering, v.SE-6, n2 6, 1980, p. 563-571. E. W. Dijkstra, “Hierarchical ordering of sequential processes”, Acta Informática, v. 1, 1971, p. 115-138. P. Brinch Hansen, “Structured m ultiprogram m ing”, Communications o f the ACM, v. 15, n2 7, jul. 1972, p. 574578. P. Brinch Hansen, Operating system principies. Englewood Cliffs, NJ: Prentice Hall, 1973. C. A. R. Hoare, “Monitors: an operating system structuring concept”, Communications o f the ACM, v. 17, n2 10, out. 1974, p. 549-557. Veja também “Corrigendum”, Commu­ nications ofthe ACM, v. 18, n2 2, fev. 1975, p. 95. P. Brinch Hansen, ‘The solo operating system: processes, monitors, and classes”, Software: Practice and Experience, v. 6,1976, p. 165-200. J. H. Howard, “Proving monitors”, Communications ofthe ACM, v. 19, n2 5, maio 1976, p. 273-279. J. H. Howard, “Signaling in monitors”, Second International Conference on Software Engineering, São Francisco, CA, out. 1976, p. 47-52. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. A. M. Lister e K. J. Maynard, “An implementation of monitors”, Software: Practice and Experience, v. 6, n2 3, jul. 1976, p. 377-386. J. L. W. Kessels, “An altemative to event queues for synchronization in monitors”, Communications ofthe ACM, v. 20, n2 7, jul. 1977, p. 500-503. J. Keedy, “On structuring operating Systems with monitors”, Australian Computer Journal, v. 10, n2 1, fev. 1978, p. 23-27. Reimpresso em Operating Systems Review, v. 13, n2 1, jan. 1979, p. 5-9. B. W. Lampson e D. D. Redell, “Experience with processes and monitors in MESA”, Communications ofthe ACM, v. 23, n2 2, fev. 1980, p. 105-117. P. Wegner e S. A. Smolka, “Processes, tasks and monitors: a comparative study of concurrent programming primitives”, IEEE Transactions on Software Engineering, v. SE-9, n2 4, jul. 1983, p. 446-462. P. A. Buhr, M. Fortier e M. Coffin, “Monitor classifications”, ACM Computing Surveys, v. 27, n2 1, mar. 1995, p. 63107. C. A. R. Hoare, “Monitors: an operating system structuring concept”, Communications o fthe ACM, v. 17, n2 10, out. 1974, p. 549-557. P. A. Buhr, M. Fortier e Coffin, M., “Monitor classification”, ACM Computing Surveys, v. 27, n2 1, mar. 1995, p. 63107. P. Brinch Hansen, ‘The programming language concurrent Pascal”, IEEE Transactions on Software Engineering, n2 2, jun. 1975, p. 199-206. C. A. R. Hoare, “Monitors: an operating system structuring concept”, Communications o fthe ACM, v. 17, n2 10, out. 1974, p. 549-557. Veja também “Corrigendum”, Commu­ nications ofthe ACM, v. 18, n2 2, fev. 1975, p. 95. P. J. Courtois, F. Heymans e D. L. Pamas, “Concurrent control with readers and writers”, Communications ofthe ACM, v. 14, n2 10, out. 1971, p. 667-668. C. A. R. Hoare, “Monitors: an operating system structuring concept”, Communications o fthe ACM, v. 17, n2 10, out. 1974, p. 549-557. Veja também “Corrigendum”, Commu­ nications ofthe ACM, v. 18, n2 2, fev. 1975, p. 95. S. J. Hartley, “Concurrent programming using the Java language”, modificado em: 30 dez. 1997, www.mcs.drexel.edu/ -shartIey/ConcProgJava/monitors.htmI. 43. B. Venners, “Thread synchronization”, Inside the Java Virtual Machine, modificado em: 18 abr. 2003, www.artima.com/ insidejvm/ed2/thread$ynch.html. 44. 45. 46. T. W. Christopher e G. K. Thiruvathukal, High-performance Java platform computing, multithreaded and networked programming. Upper Saddle River, NJ: Prentice Hall, p. 89-93. E. W. Dijkstra, “Solution of a problem in concurrent programming control”, Communications o f the ACM, v. 8, n2 5, set. 1965, p. 569. S. S. Patil, “Limitations and capabilities of Dijkstra’s semaphore primitives for coordination among processes”, M.I.T. ProjectMAC ComputationalStructures Group Memo 57, fev. 1971. Cumulo f / D&u m olhar im o rta l. Robert Browning A detecção í> ou, deveria, ser, um a ciência, exata, e, deveria, ser tratada, comí, a, mesm a,frie-za e, ausência, de, emoção. Sir A rthur Conan Doyle Demoras term inam , m al. W illiam Shakespeare Este capítulo apresenta: • O problema do deadlock. • As quatro condições necessárias para existir deadlock. • O problema do adiamento indefinido. • Os conceitos de prevenção, evitação, detecção e recuperação de deadlock. • Algoritmos para evitação e detecção de deadlock. • Como os sistemas podem se recuperar de deadlocks. 180 SUtwuis operacionais 7.1 Introdução N os quatro capítulos anteriores discutim os processos assíncronos, processos concorrentes e threads. U m sistem a de m ultiprogram ação fornece muitos benefícios, mas, com o discutido no Capítulo 6, “Program ação concorrente” , a multiprogram ação tam bém introduz com plexidade adicional. Um problem a que surge em sistemas de m ultiprogram ação é o deadlock (impasse). Um processo ou thread está em estado de deadlock (ou travado) se estiver à espera por um determ i­ nado evento que não ocorrerá. No deadlock de sistem a um ou m ais processos estão travados.1*2 O restante deste capítulo irá se concentrar em processos, mas grande parte da discussão tam bém se aplicará a threads. E m sistem as de com putação de m ultiprogram ação, o com partilham ento de recursos é um a das m etas principais. Q uando recursos são com partilhados entre um conjunto de processos e cada processo m antém controle exclusivo sobre determ inados recursos a ele alocados, podem ocorrer deadlocks nos quais alguns processos nunca poderão concluir sua execução, o que pode resultar em perda de trabalho, redução de rendim ento e falha do sistema. Este capítulo discute o problem a do deadlock e resum e as quatro áreas m ais im portantes da pesquisa dc deadlocks: prevenção, evitação, detecção e recuperação de deadlock. Considera tam bém o problem a relacionado do adiam ento indefinido, tam bém denom inado inanição, no qual um processo que não está travado pode ficar esperando por um evento que talvez nunca ocorra ou que possa ocorrer em algum instante indeterm inado no futuro devido a vieses nas políticas de escalonam ento de recursos dos sistemas. Em alguns casos, fabricar um sistem a livre de deadlocks tem um preço alto. Certos sistemas, com o os de m issão crítica, esse preço deve ser pago não im portando quão alto seja, porque perm itir que um deadlock se desenvolva podería ser catastrófico, especialm ente se puser vidas hum anas em risco. Este capítulo tam ­ bém discute soluções para os problem as de deadlock e adiam ento indefinido em term os de perm utas entre sobrecarga e benefícios previstos. R evu ã d 1. Um projetista de sistem as decide tentar evitar qualquer possibilidade de deadlock criando um sistema de m ultipro­ gram ação que não com partilha recursos. O que está errado nessa idéia? 2. Q uais as semelhanças e diferenças entre deadlock e adiam ento indefinido? R c ip o ità i 1 1) O sistema seria altam ente ineficiente, porque cada processo precisaria de seu próprio conjunto de recursos. E mais, program as concorrentes assíncronos com um ente exigem recursos com partilhados com o semáforos. 2) Deadlock e adiam ento indefinido são sem elhantes, porque ocorrem quando processos esperam por um evento. O deadlock acontece porque o evento nunca ocorrerá; o adiam ento indefinido sucede, porque não se tem certeza se e quando o evento ocorrerá (devido a vieses nas políticas dc escalonam ento de recursos do sistema). 7.2 Exemplos de deadlocks Deadlocks podem se desenvolver de m uitas maneiras. Se a tarefa designada a um processo é esperar que um evento ocorra e o sistem a não tiver nenhum a provisão para sinalizar esse evento, teremos um deadlock de um só processo.3 Esses deadlocks são extrem am ente difíceis de detectar. D eadlocks em sistem as reais freqüentem ente envolvem vários processos que estão com petindo por vários recursos de diversos tipos. Vamos exam inar alguns exemplos comuns. 7.2.1 V e A À lo c Ic d & tr á fe g o A Figura 7.1 ilustra um tipo de deadlock que ocasionalm ente acontece em cidades. Vários automóveis estão tentando transitar por um bairro movimentado e o tráfego está totalm ente engarrafado. A polícia tem de resolver a confusão retirando os carros vagarosa e cuidadosamente da área congestionada. Por fim o tráfego começa a fluir normalmente, mas não sem antes causar muito aborrecimento, esforço e perda de tempo (veja no site deste livro: “Curiosidades, Ponte de pista única”). Ret/U ãcr 1. Supondo que não haja carros após os pontinhos na Figura 7.1, qual o núm ero m ínim o de carros que teriam de dar ré para liberar o deadlock e quais (ou qual) carros seriam? 2. Se os carros fossem retirados por via aérea na Figura 7.1, qual o núm ero m ínimo de carros e quais (ou qual) teriam de ser retirados para liberar o deadlock? R eipO itài: 1) Na Figura 7.1 apenas dois carros teriam de dar ré para perm itir que todos os outros eventualmente pudessem sair — qualquer um dos carros antes de um a das séries de pontinhos e, em seguida, o carro à frente dele no cruzam ento. 2) Somente um carro tem de ser retirado: qualquer um dos quatro que estão nos cruzamentos. Cajútuio 7 Veadlocks e,aduuiimto indefinido 181 F igura/ 7.1 Exwijdo cU deadlock, de, tráfego? 7.2.2 VeaMocJcHA/alocação d e recurso simples A m aioria dos deadlocks de sistemas operacionais ocorre por causa da disputa normal por recursos dedicados (recursos que podem ser usados ao longo do tempo por m uitos processos, mas por apenas um processo por vez, às vezes denom ina­ dos recursos reutilizáveis serialmente). Por exemplo, um a im pressora pode im prim ir trabalhos apenas para um processo por vez (caso contrário, partes de m uitos trabalhos seriam im pressas intercaladam ente). U m exem plo simples de deadlock de recurso é ilustrado na Figura 7.2. Esse grafo de alocação de recurso mostra dois processos sob a form a de retângulos e dois recursos sob a form a de círculos. U m a seta que liga um recurso a um processo indica que o recurso pertence ou foi alocado àquele processo. U m a seta que liga um processo a um recurso indica que o processo está requisitando, mas ainda não obteve o recurso. O diagram a m ostra um sistem a em deadlock: o Processo P, retém o Recurso R, e precisa do Recurso R2para continuar; o Processo P2retém o Recurso R2e precisa do Recurso R, para continuar. Cada processo está esperando que o outro libere um recurso que não liberará. Essa espera circular é característica de sistem as em deadlock (veja o quadro “Reflexões sobre sistemas operacionais, Espera, deadlock e adiam ento indefinido). Esse tipo de retenção irredutível de recursos às vezes é denom inado abraço mortal. Rerfião' 1. Se o deadlock de tráfego da Figura 7.1 fosse representado em um grafo de alocação de recursos, quais seriam os processos? Quais seriam os recursos? 2. Suponha que haja diversas setas ligando um processo a recursos em um grafo de alocação de recursos. O que isso significa? Com o afeta a possibilidade de deadlock? R e ip o ifa i 1 1) Os carros seriam os processos. Os recursos seriam as seções da rua que os carros ocupam. Cada carro no m om ento retém a seção da rua diretam ente abaixo dele e está requisitando a seção à frente dele. 2) Significa que o processo 182 Sistemas operacionais fu jtira , 7.2 Exemplo de deadlock de, recurso. Este sistema entrou, ene deadlock, porque, cada,processo retém, um, recurso que está, sendo requisitado pelo outro processo e nenhum,processo está, disposto a, liberar o recurso que retém,. está requisitando diversos recursos. A possibilidade de deadlock depende da alocação desses recursos a outros processos, alguns dos quais, por sua vez, estão a requisitar recursos retidos pelo processo que discutimos. 7.2.3 Deadlock ene sistem as spooling Um sistem a de spooling m elhora o rendim ento do sistem a por desassociar um program a de dispositivos lentos com o im pressoras. For exem plo, se um program a que está enviando linhas a um a im pressora tiver de esperar que cada página seja im pressa antes de poder transm itir a próxim a, sua execução será lenta. Para acelerar a execução do program a, um sistem a de spooling dirige as páginas a um dispositivo m uito m ais rápido, com o um disco rígido, no qual elas são arm a­ zenadas tem porariam ente até que possam ser impressas. Sistemas de spooling podem ser propensos a deadlock. Alguns requerem que toda a saída de um program a esteja disponível antes de poder iniciar a impressão. Diversos serviços parcialm ente concluídos que estão gerando páginas para um arquivo de spool podem ficar travados, se os espaços disponíveis no disco forem preenchidos antes da conclusão de qualquer dos trabalhos. O usuário ou adm inistrador do sistem a pode ‘m atar’ um ou mais serviços para abrir suficiente espaço de spooling para concluir os serviços restantes. O adm inistrador do sistem a norm alm ente especifica a quantidade de espaço para arquivos de spooling. Um m odo de reduzir a probabilidade de deadlocks é fornecer consideravelm ente m ais espaço para arquivos de spooling do que seria provavelm ente necessário. Essa solução pode ser inexeqüível se o espaço for caro demais. U m a solução m ais com um é restringir os spoolers de entrada, para que não aceitem serviços adicionais de im pressão quando os arquivos de spooling estiverem prestes a atingir um certo limite de saturação, tal com o 75% cheios. Isso pode reduzir o rendim ento do sistema, mas é o preço que se paga para reduzir a probabilidade de deadlock. Os sistem as de hoje são mais sofisticados do que isso. Podem perm itir que a impressão com ece antes de um trabalho estar concluído de m odo que um arquivo de spooling cheio, ou quase cheio, possa com eçar a ser esvaziado enquanto ainda houver um serviço em execução. Esse conceito tem sido aplicado a clipes de áudio e vídeo de tempo real quando o áudio e o vídeo podem ser ouvidos e vistos antes de o clipe ter sido totalm ente descarregado (stream ing). Em m uitos sistemas a alocação de espaço de spooling ficou mais dinâmica; se o espaço existente com eçar a ficar cheio, m ais espaço pode ser disponibilizado. R evU ão' 1. Suponha que um sistem a de spooling tenha um limite de saturação de 75% e restrinja o tam anho m áxim o de cada arquivo em 25% do tamanho total do arquivo de spooling. Pode ocorrer deadlock nesse sistema? 2. Suponha que um sistem a de spooling tenha um limite de saturação de 75% e restrinja o tam anho m áxim o de cada arquivo em 25% do tam anho total do arquivo de spooling. D escreva um m odo simples de garantir que nunca ocorrerá deadlock no sistema. Explique com o isso podería levar à alocação ineficiente de recursos. R e ip o itã i: i ) Sim, ainda assim pode ocorrer deadlock nesse sistema. Por exemplo, diversos serviços com eçam a transferir suas saídas. Q uando o arquivo de spooling atingir o lim ite de 75% não serão perm itidos m ais serviços, porém os Ca^üuio7 Vesulljdc &adúuiimto Udefuúdo Jgg Rej~\ôxÔes ç>o\k & ç\dôm*\ç ooecACloiAAte Esfteras, cU ã Á lo ch b a À ia m e M to m  e ju ü À o Sistemas operacionais devem gerenciar m uitos tipos diferentes de situações de espera que depen­ dem da utilização intensa de filas para isso. Processos e threads têm de esperar que um processador fiqu e disponível antes de poder executar; m uitas vezes esperam pela conclusão de requisições de E/S e pela disponibilidade de recur­ sos. As próprias requisições de E/S devem esperar pela disponibilidade de dispositivos de E/S. Processos e threads que compartilham dados podem ter de esperar até que um processo ou thread que esteja atual­ mente acessando os dados termine e saia de uma seção crítica. No rela­ cionamento produtor/consumidor, o produtor passa informações ao con­ sum idor via região compartilhada da memória; quando essa região estiver cheia, o produtor não poderá continuar a produzir mais informa­ ções, portanto deverá esperar que o consumidor esvazie uma parte dos dados; quando a região estiver vazia, o consumidor deverá esperar que o produtor gere mais dados. Você verá muitos exemplos de situações de espera por todo este livro. Sistemas operacionais devem gerenciar a espera cuidadosamente para evitar dois problemas sérios, a saber, o deadlock e o adiamento in­ definido, discutidos detalhadamente neste capítulo. Em uma situação de deadlock, processos e threads estão esperando por eventos que nunca ocorrerão; um deadlock simples de dois processos obriga cada um de­ les a esperar por um recurso retido por um dos processos e que só pode ser usado por um processo por vez. Ambos os processos param de processar, o que pode ser fatal em sistemas de missão crítica nos quais pode haver vidas humanas em jogo. Adiamento indefinido (também denominado inanição) normalmente ocorre quando um processo está à espera na fila e o sistema permite que outros processos, talvez de prio­ ridade mais alta, passem à frente. Diz-se que um fluxo constante de chegada de processos de priorida­ des mais altas adia indefinidamente os processos de prioridades mais baixas, o que, em sistem as de missão crítica, pode ser tão perigo­ so quanto um deadlock. Portanto, leve a sério a espera — se for mal gerenciada, poderão ocorrer falhas de sistema. que já com eçaram podem continuar a fazer o spooling, o que pode resultar em deadlock se não houver espaço suficiente no arquivo de spooling. 2) Um ajuste sim ples seria perm itir que som ente um dos serviços continue o seu processo de spooling de dados quando o arquivo atingir o lim ite, o que seria ineficiente, porque lim itaria o tam anho m áxim o do serviço a muito menos do que o espaço de spooling disponível. 7.2 A Exemplo: ojantar dosfilósofos O problem a do Jantar dos Filósofos5-6 de D ijkstra ilustra muitas das questões sutis inerentes à program ação concor­ rente. Eis o problema: Cinco filósofos estão sentados ao redor de uma mesa redonda. Cada um leva uma vida sim ples, alter­ nando entre pen sa r e com er macarrão. À fren te de cada filósofo está um prato de m acarrão que é sempre reabastecido p o r um empregado dedicado. Há exatamente cinco garfos sobre a mesa, um entre cada p a r adjacente de filósofos. Com er m acarrão (daquela m aneira m ais elegante) requer que um filósofo use os dois garfos adjacentes a ele (simultaneamente). D esenvolva um program a concorrente, livre de deadlock e adiamento indefinido, que m odele as atividades dos filósofos. Se a solução desse problem a não fosse livre de deadlock e adiam ento indefinido, um ou mais filósofos m orreríam de fome. O program a deve, é claro, im por exclusão m útua — dois filósofos não podem usar o m esmo garfo ao m esm o tempo. Um filósofo típico com porta-se com o mostra a Figura 7.3. Os problem as de exclusão m útua, deadlock e adiam ento indefinido estão na im plem entação do método eat. Considere a im plantação sim ples, mas perigosa, da Figura 7.4. Com o os filósofos funcionam assíncrona e concorrentem ente, é possível que cada um execute a linha 3 antes que qualquer outro execute a linha 4. N esse caso, cada filósofo reterá exatam ente um garfo e não restará m ais nenhum sobre a mesa. Todos eles sofrerão deadlock e m orrerão de fome. Um m eio de quebrar o deadlock quando cada filósofo pegar um garfo esquerdo é obrigar um ou m ais filósofos a de­ volver seus garfos esquerdos de m odo que um outro possa pegá-lo com o um garfo direito. Para im plem entar essa regra, 184 1 2 3 4 5 6 7 8 9 Sistemas o^eraxionals void typicalPhilosopher() { while ( true ) { th in k (); e a t(); } / / termine while } // termine typicalPhilosopher Figuras 73 ComfwrtameHto d&umvfilósofo nojantar. 1 2 3 4 5 6 7 8 void e a t() { pickUpLeftForkf); // pegue o garfo esquerdo pickUpRightFork(); // pegue o garfo direito eatForSomeTimel); // coma durante algum tempo putDownRightForkf); // largue o garfo direito putD ow nLeftForkl); // largue o garfo esquerdo } // eat Figuras 7A Im/Uementação do método eat. pickUpRightForkf) pode especificar que um filósofo devolva o garfo esquerdo se não puder obter o garfo direito. Porém, nesse caso, é possível (em bora improvável) que cada filósofo pegue e devolva seu garfo esquerdo repetidam ente, um após o outro, sem nunca obter os dois garfos de que necessita para com er o macarrão. N esse caso, os filósofos não sofrerão um impasse ‘de m orte’ (deadlock; dead = morto, ou de morte), mas sim um im passe ‘ao vivo’ (livelock; live = vivo, ou ao vivo), ou seja, sofrerão adiam ento indefinido e ainda assim m orrerão de fome. A solução precisa evitar o deadlock (obrigando os filósofos a largar seus garfos), mas tam bém evitar o livelock (adiam ento indefinido) garantindo que cada filósofo obtenha os dois garfos de vez em quando. Um dos exercícios pedirá que você desenvolva um a solução com pleta para o problem a do Jantar dos Filósofos. R evü ã o ' 1. A im plem entação do método eat da Figura 7.4 perm ite que os filósofos vivam em harm onia sem m orrer de fome? 2. Considere o método eat da Figura 7.4. Suponha que as Unhas 3 e 4 fossem substituídas por pickUpBothForksAtOnce()(pegue am bos os garfos ao mesmo tem po), essa im plem entação im pediría o deadlock? Im pediría que os filósofos m orressem de fom e? R e ip o iíã i: 1) Sim. Não podem os prever as velocidades relativas de processos concorrentes assíncronos. É possível que nem todos os cinco filósofos peguem seus garfos esquerdos ao mesmo tempo. Vários deles poderão pegar os dois garfos que necessitam e, então, largá-los dando aos outros filósofos um a chance de comer. 2) Sim, evitaria o deadlock supondo que pickUpBothForksAtOnceO pode ser executada atomicamente. Ainda assim permitiría adiamento indefinido, que podería ocorrer, por exemplo, se dois dos filósofos continuam ente pegassem dois garfos e comessem, largassem os garfos e os pegassem novamente antes que qualquer um dos outros filósofos pudesse pegá-los; os outros filósofos morreríam de fome. 7 .3 Problema relacionado: adiam ento indefinido Em qualquer sistem a em que os processos tenham de esperar por causa de decisões de alocação de recursos e de esca­ lonamento, um processo pode ser atrasado indefinidam ente enquanto outros recebem a atenção do sistema. E ssa situação, denom inada adiam ento indefinido, bloqueio indefinido ou inanição, pode ser tão devastadora quanto o deadlock. Adiam ento indefinido pode ocorrer por causa dos vieses de um a política de escalonam ento de recursos. Q uando re­ cursos são escalonados por prioridade, é possível que um dado processo fique esperando por um recurso indefinidamente enquanto continuarem a chegar processos de prioridades m ais altas. Esperar é um fato da vida e certam ente é um aspecto Ca^üuio7 Veculljdc e,aMcuiiettto LuxiejuuÁo Jg£ im portante do que acontece dentro de sistem as de computador, portanto, os sistemas devem ser projetados para gerenciar com justiça e eficientemente os processos que estão à espera. Alguns sistem as im pedem o adiam ento indefinido elevando a prioridade de um processo gradativamente enquanto ele espera por um recurso — essa técnica é denom inada envelheci­ m en to (aging). Eventualm ente a prioridade do processo à espera ultrapassará as prioridades de todos os outros processos, e ele será atendido. R ev u ã a 1. O Algoritmo de Dekker e o Algoritmo de Peterson impediam que um processo fosse adiado indefinidamente para en­ trar em sua seção crítica. Descreva com o o adiamento indefinido foi evitado. Com o está relacionado ao envelhecimento? 2. Suponha que um processo interativo pareça estar ‘m ortinho da Silva’. Isso significa que ele está definitivamente em deadlock? Podería estar indefinidamente adiado? Há outras possibilidades? R e ip o iíà i: i ) Tanto o A lgoritm o de D ekker quanto o A lgoritm o de Peterson davam preferência ao processo à espera quando o recurso tom ava-se disponível novamente, o que é sem elhante ao envelhecim ento (aging), porque o processo à espera ganha um a prioridade m ais alta por estar esperando. 2) Essa é um a pergunta interessante. Do ponto de vista do usuário um processo interativo parecería estar ‘m ortinho da Silva’ se o sistem a sim plesm ente parasse de atender às solici­ tações do usuário interativo. O processo podería estar em deadlock, ou não. Podería estar sofrendo adiam ento indefinido, ou não. Também podería estar à espera por um evento que fosse acontecer em pouco tem po, podería estar preso em um laço infinito ou realizando um cálculo dem orado que logo acabaria. Q uem quer que já tenha sofrido com um sistem a que parece estar ‘pendurado’ sabe com o isso pode ser frustrante. Quais serviços o sistem a operacional deveria fornecer para ajudar o usuário nessas situações? A bordarem os essas questões por todo o livro. 7A Conceitos recurso N a qualidade de gerente de recursos o sistem a operacional é responsável pela alocação de um vasto conjunto de re­ cursos de vários tipos, e é isso que, em parte, torna o projeto de um sistem a operacional tão interessante. C onsideram os recursos que são p reem p tiv o s, com o processadores e m em ória principal. Processadores talvez sejam os recursos que m ais freqüentem ente sofrem preem pção em um sistem a de com putação. Eles podem ser alternados rapidam ente (multiplexados) entre todos os processos ativos que estão disputando os serviços do sistem a para garantir que esses processos prossigam com velocidades razoáveis. Sem pre que um processo particular chega a um ponto em que não pode usar um processador efetivam ente (por exem plo, durante um a longa espera pela conclusão de entrada/saída, o sistem a operacional despacha um outro processo para aquele processador). Com o verem os nos capítulos 9, 10 e 11, um program a usuário que esteja atualm ente ocupando um a faixa particular de localizações na m em ória principal pode ser rem ovido ou sofrer preem pção por um outro program a. A ssim , a preem pção é extrem am ente crítica para o sucesso de sistem as de com pu­ tação de m ultiprogram ação. Certos recursos são n ão p reem p tiv o s — não podem ser removidos do processo ao qual são designados até que esse os liberem voluntariamente. Por exem plo, unidades de fita e scanners norm alm ente são designados a um processo particular por períodos de minutos ou horas. Alguns recursos podem ser c o m p a rtilh a d o s entre diversos processos, enquanto outros são dedicados a um único pro­ cesso por vez. Em bora um processador isolado norm alm ente só possa pertencer a um processo por vez, sua m ultiplexação entre m uitos processos cria a ilusão de com partilham ento sim ultâneo. Unidades de disco às vezes são dedicadas a um único processo, mas em geral contêm arquivos que podem ser acessados por m uitos processos. D iscos podem ser multiplexados entre muitos processos que estão requisitando E/S. D ados e program as certam ente são recursos que o sistem a operacional deve controlar e alocar. Em sistem as de m ul­ tiprogram ação, m uitos usuários podem querer usar um editor de program a ao m esm o tem po. Se o sistem a operacional mantivesse na m em ória principal um a cópia separada do editor para cada program a, havería um a quantidade significa­ tiva de dados redundantes, desperdiçando m emória. U m a técnica m elhor é o sistem a operacional carregar um a cópia do código na m em ória e disponibilizar a cópia para cada usuário. Se fosse perm itido a um processo m odificar esse código com partilhado, outros processos poderíam agir sem previsibilidade. Consequentem ente esse código deve ser re e n tra n te , o que significa que não é m odificado enquanto executa. Código que pode ser modificado, mas é reinicializado cada vez que é usado, denom ina-se re u tilizáv el seria lm en te. Código reentrante pode ser com partilhado por diversos processos sim ultaneam ente, ao passo que código serialm ente reutilizável pode ser usado corretam ente apenas por um único pro­ cesso por vez. Q uando cham am os recursos com partilhados particulares, devemos ter o cuidado de declarar se eles podem ser usados por diversos processos sim ultaneam ente ou por apenas um processo por vez. Esse últim o tipo — recursos reutilizáveis serialm ente — são os que tendem a se envolver em deadlocks. 186 Sistemas ofterationais R cvu ã ty 1. (V/F) Processos não sofrem deadlock com o resultado da disputa por um processador. 2. (V/F) Recursos não preem ptivos devem ser hardware. R eA poífai l 1) Verdadeiro. O processador é um recurso preem ptivo que pode ser facilm ente retirado de um processo, designado a outros processos e devolvido ao processo original habilitando-o a prosseguir norm alm ente. 2) Falso. Certos recursos de softw are não são preem ptivos, com o os m onitores. 7 .5 Quatro condições necessárias para/ deoAlodc Coffman, Elphick e Shoshani7 provaram que as quatro condições seguintes são necessárias para existir deadlock: 1. Um recurso pode ser adquirido exclusivam ente por um único processo por vez (condição de exclusão m ú tu a). 2. Um processo que obteve um recurso exclusivo pode reter esse recurso enquanto espera para obter outros recursos (condição de esp e ra, tam bém denom inada condição de posse e espera). 3. U m a vez que o processo obtenha um recurso, o sistem a não pode retirá-lo do controle do processo até que esse tenha term inado de utilizar o recurso (condição de n ão -p reem p ção). 4 . Dois ou mais processos ficam travados em um a ‘cadeia circular’ na qual cada processo está esperando por um ou mais recursos que o processo seguinte da cadeia tetém (condição de e sp e ra circ u la r). Com o essas condições são necessárias, a existência de um deadlock im plica que cada um a delas deve estar em práti­ ca. Com o veremos mais adiante, essa observação nos ajuda a desenvolver esquem as para evitar deadlocks. Tomadas em conjunto, todas as quatro condições são necessárias e suficientes para existir deadlock (se todas ocorrerem , o sistem a sofrerá deadlock). R e ríiã o ' 1. Descreva com o as quatro condições necessárias para deadlock se aplicam a sistem as de spooling. 2. Qual das quatro condições seria violada se um usuário pudesse rem over serviços de um sistem a de spooling? Re&pa&tãi 1 1) Dois serviços quaisquer não podem escrever dados sim ultaneam ente para a m esm a localização no arquivo de spooling. Serviços com spooling parcial continuam no arquivo até haver mais espaço disponível. N enhum serviço pode rem over outro do arquivo de spooling. Por fim, quando o arquivo de spooling está cheio, cada serviço espera por todos os outros serviços para liberar espaço. 2) Isso violaria a condição de ‘não-preem pção’. 7.6 Soluçõespara/o deadlock Deadlock tem sido um a das áreas mais produtivas da pesquisa da ciência da com putação e de sistem as operacionais. H á quatro áreas principais de interesse na pesquisa do deadlock — prevenção de deadlock, evitação de deadlock, detecção de deadlock e recuperação de deadlock. N a p rev en ção d e d ead lo ck nossa preocupação é condicionar um sistem a a afastar qualquer possibilidade de ocorrer deadlocks. A prevenção é um a solução lim pa no que concerne ao deadlock em si, mas, muitas vezes, m étodos de prevenção podem resultar em m á utilização de recursos. N a evitação d e d ead lo ck a meta é im por condições menos restritivas do que na prevenção, na tentativa de conseguir m elhor utilização dos recursos. M étodos de evitação não condicionam previam ente o sistem a a afastar todas as possibili­ dades de deadlock. Ao contrário, perm item que a possibilidade exista, mas, sem pre que um deadlock esteja na im inência de acontecer, ele é cuidadosam ente desviado. M étodos de d etecção de d ead lo ck são usados em sistem as nos quais podem ocorrer deadlocks. A m eta é determ inar se ocorreu um deadlock e identificar os processos e recursos que estão envolvidos. M étodos de re c u p e ra ç ã o d e d ead lo ck são usados para lim par deadlocks de um sistem a de m odo que esse possa fun­ cionar livre deles e para que os processos que sofreram deadlock possam concluir sua execução e liberar seus recursos. A recuperação é, na m elhor das hipóteses, um problem a confuso que, em geral, requer que um ou mais processos em deadlock sejam expurgados do sistema. Os processos expurgados são reiniciaiizados norm alm ente desde o com eço quando houver recursos disponíveis suficientes, porém grande parte ou todo o trabalho já executado por eles será perdido. ReviuVr 1. Q uais as diferenças e semelhanças entre prevenção e evitação de deadlock? 2. Alguns sistem as ignoram o problem a do deadlock. D iscuta os custos e benefícios dessa abordagem. Ca^üuio7 Deadlodc &aduuiiettto indefinido Jg? R e ip o ílã i 1) A prevenção de deadlock tom a-o impossível, mas resulta em baixa utilização de recursos. Já na evitação, quando um a am eaça de deadlock se aproxim a, ela é desviada e a utilização de recursos é m ais alta. Sistem as que utilizam prevenção ou evitação estarão livres de deadlocks. 2. Sistemas que ignoram deadlocks podem falhar quando ocorrer um , o que é um risco inaceitável em sistemas de m issão crítica, mas pode ser adequado em outros nos quais raram ente ocorrem deadlocks, e o ‘custo’ de tratar um acontecim ento desses ocasional é mais baixo do que o de im plem entar esquem as de prevenção ou evitação de deadlocks. 7 .7 Prevenção d&deadlock E sta seção considera vários m étodos de prevenção de deadlocks e exam ina os efeitos que causam sobre usuários e sistem as, especialm ente do ponto de vista do desem penho.8,9, 10, 12,13 Havender,14 observando que um deadlock não pode ocorrer se um sistem a negar qualquer um a das quatro condições necessárias, sugeriu as seguintes estratégias de prevenção de deadlock: • Cada processo deve requisitar todos os recursos de que precisa de uma só vez e não pode continuar até que todos tenham sido concedidos. • Se for negada mais um a requisição a um processo que retém certos recursos, ele deve liberar seus recursos originais e, se necessário, requisitá-los novamente junto com os recursos adicionais. • Deve ser imposta uma ordenação linear de recursos a todos os processos; se um processo recebeu certos recursos, ele somente poderá requisitá-los novam ente m ais tarde, conform e a ordem. N as seções seguintes exam inarem os cada estratégia independentem ente e discutirem os com o cada um a delas nega um a das condições necessárias (veja no site deste livro: “Curiosidades, Proibidos porcas, parafusos e rosqueam entos”). Note que Havender apresenta três estratégias, e não quatro. A prim eira condição necessária — que processos exijam a utilização exclusiva dos recursos requisitados por eles — não é um a condição que desejam os quebrar, porque querem os perm itir especificam ente recursos dedicados (reutilizáveis serialmente). R evü ã o ' 1. Q ual a prem issa básica da pesquisa de H avender sobre prevenção de deadlock? R e ip o itã /l 1) N ão pode ocorrer deadlock em sistemas nos quais qualquer um a das condições necessárias para deadlock seja impedida. 7.7.1 Negação d a condição ‘desespera, A prim eira estratégia de Havender requer que todos os recursos de que um processo precisa para concluir sua tarefa devem ser requisitados ao mesmo tempo. O sistem a deve concedê-los na base do ‘tudo ou nada’. Se todos os recursos de que um processo necessita estiverem disponíveis, o sistem a poderá conceder-lhe todos ao m esm o tem po, e o processo poderá continuar a executar. Se os recursos não estiverem todos disponíveis, o processo deverá esperar até que estejam. Porém, enquanto espera, o processo não pode reter nenhum recurso. Assim , a condição de ‘espera’ é negada e não podem ocorrer deadlocks. Em bora essa estratégia evite deadlock, desperdiça recursos. Por exemplo, um program a que requer quatro unidades de fita em um determ inado instante da execução deve requisitar, e receber, todas as quatro antes de com eçar a executar. Se precisar de todas as quatro unidades durante a execução inteira do programa, o desperdício não será sério. M as suponha que o program a precise som ente de um a unidade de fita para iniciar a execução (ou, pior ainda, de nenhum a unidade) e que, em seguida, não precise das unidades restantes durante várias horas. Im por que o program a deva requisitar, e receber, todas as quatro unidades de fita antes de iniciar a execução significa que recursos substanciais ficarão ociosos por várias horas. Um m odo de conseguir m elhor utilização de recursos nessas circunstâncias é dividir o program a em diversos threads que executam relativam ente de m odo independente um do outro. Assim, a alocação de recursos é controlada por cada thread, e não pelo processo inteiro, o que pode reduzir o desperdício, mas envolve um a sobrecarga m aior no projeto e execução da aplicação. Essa estratégia de H avender podería causar adiam ento indefinido se, por exemplo, favorecesse processos à espera, cujas necessidades de recursos são m enores do que as daqueles que estão tentando acum ular muitos recursos. U m fluxo contínuo de chegada de processos com poucas necessidades de recursos podería adiar indefinidamente um processo com necessidades mais substanciais. U m a m aneira de evitar que isso aconteça é adm inistrar as necessidades dos processos que estão à espera seguindo a ordem ‘prim eiro a chegar, prim eiro a ser atendido’. Infelizm ente, acum ular todo o com plem ento de recursos para um processo com necessidades substanciais causaria considerável desperdício, pois, enquanto estivessem acum ulando-se gradualm ente, os recursos ficariam ociosos até todos estarem disponíveis. 188 Sistemas ojwaciotuus Em am bientes de com putadores de grande porte, cujos recursos são caros, há um a certa controvérsia sobre de quem devem ser cobrados os recursos não utilizados. Pelo fato de os recursos estarem sendo acum ulados para um usuário espe­ cífico, alguns projetistas acham que é esse usuário que deve pagar por eles, mesmo que fiquem ociosos. Outros projetistas dizem que isso destruiría a previsibilidade da cobrança de recursos; se o usuário tentasse executar o processo em um dia m ovim entado, os encargos seriam muito mais altos do que no m om ento em que a m áquina estivesse apenas levemente carregada. R w uão' 1. Explique com o negar a condição ‘de espera’ pode reduzir o grau de m ultiprogram ação de um sistema. 2. D escreva sob quais condições um processo pode ser indefinidam ente adiado ao usar o esquem a de H avender para negar a condição ‘de espera’. R e ip o iíà i: i ) Se os processos de um sistem a requisitarem mais recursos do que os disponíveis para execução concor­ rente, o sistem a deve obrigar alguns desses processos a esperar até que outros term inem e devolvam seus recursos. N a pior das hipóteses o sistem a pode ficar lim itado a executar som ente um processo por vez. 2) Um processo podería requisitar um núm ero substancial de recursos de um sistema. Se o sistem a operacional der prioridade m ais alta a processos que requisitarem menos recursos do sistema, o processo que está requisitando todos os recursos será adiado indefinidamente, enquanto processos que requisitarem menos recursos prosseguirão. 7.7.2 Negação tia, condição de- ‘não 'preemjtção ’ A segunda estratégia de H avender nega a condição de ‘não-preem pção’. Suponha que um sistem a perm ita que processos retenham recursos enquanto requisitam alguns adicionais. C ontanto que restem recursos suficientes para sa­ tisfazer todas as requisições, o sistem a não pode sofrer deadlock. M as considere o que acontece quando um a requisição de recursos adicionais não puder ser atendida. A gora um processo retém recursos dos quais um segundo processo pode precisar para prosseguir, enquanto o segundo processo pode reter recursos de que o prim eiro necessita — um deadlock de dois processos. A segunda estratégia de H avender determ ina que, quando um a requisição de recursos adicionais feita por um processo que retenha recursos for negada, esse processo deverá liberar os recursos que retém e, se necessário, requisitá-los nova­ mente, junto com os recursos adicionais. Essa estratégia efetivamente nega a condição de ‘não-preem pção’ — os recursos podem realm ente ser retirados de um processo que tem a posse deles antes da conclusão desse processo. Também nesse caso os meios para evitar deadlocks podem ser custosos. Quando um processo libera recursos, pode perder todo o trabalho que realizou até aquele ponto. Tal preço pode parecer alto, mas a verdadeira questão é: “Quantas vezes esse preço tem de ser pago?”. Se isso ocorrer com pouca freqüência, essa estratégia fornecerá um meio de custo relativam ente baixo para evitar deadlocks. Contudo, se ocorrer freqüentem ente, o custo será substancial e os efeitos, de­ vastadores, particularm ente quando processos de alta prioridade ou com prazo determ inado não puderem ser concluídos a tempo por causa de repetidas preempções. E ssa estratégia podería levar a adiam ento indefinido? Depende. Se o sistem a favorecer processos cujas requisições de recursos são pequenas em detrim ento de processos que estão requisitando recursos substanciais, só isso já levará a adiamento indefinido. Pior ainda, à m edida que o processo requisitar recursos adicionais, essa estratégia de Havender determ inará que ele entregue todos os recursos que tem e requisite um núm ero ainda maior. Portanto, o adiam ento indefinido pode ser um problem a quando o sistema for m uito movimentado. E tam bém , essa estratégia requer que todos os recursos sejam preem ptivos, o que nem sempre é o caso (por exemplo, impressoras não devem sofrer preem pção durante o processam ento de um serviço de impressão). Rcviiãa 1. Qual o custo prim ário de negar a condição de ‘não-preem pção’? 2. Qual das duas prim eiras estratégias de Havender para deadlock você acha a mais aceita por todos? Por quê? R d ip a ilà i: 1) U m processo pode perder todo o trabalho que realizou até o ponto em que seus recursos sofreram preem pção. E também , o processo podería sofrer adiam ento indefinido dependendo da estratégia de alocação de recursos do sistema. 2) A m aioria das pessoas provavelmente preferiría a prim eira estratégia, a saber, exigir que um processo re­ quisite antecipadam ente todos os recursos de que necessitará. A segunda estratégia determ ina que um processo entregue os recursos que já tem, possivelm ente causando um desperdício de trabalho. O interessante é que a prim eira estratégia tam bém podería causar desperdício, pois os processos adquirem gradualm ente recursos que ainda não podem usar. Capítulo 7 DeadlocJc e,adiamento indefinido JgQ 7.7.3 Negação d a condição d&1espera circular3 A terceira estratégia de Havender nega a possibilidade de espera circular. N essa estratégia designam os um número único para cada recurso (por exem plo, unidade de disco, im pressora, scanner, arquivo) que o sistem a gerencia e criam os um a o rd e n a ç ã o lin e a r de recursos. Então, um processo deve requisitar seus recursos em um a ordem estritam ente ascendente. Por exem plo, se um processo requisitar o recurso R3 (onde o subscrito 3 é o núm ero do recurso), som ente poderá requisitar subseqüentem ente recursos cujo núm ero seja m aior do que 3. Pelo fato de todos os recursos terem exclusivam ente um núm ero e porque os processos devem requisitar recursos em ordem ascendente, não é possível desenvolver uma espera circular (Figura 7.5) [Nota: U m a prova dessa propriedade é direta. Considere um sistem a que im ponha um a ordenação linear de recursos na qual R e R sejam recursos num erados por inteiros i e j , respectivam ente (i “*j). Se o sistem a tiver um a característica de deadlock de espera circular, de acordo com a Figura 7.5, pelo menos um a seta (ou conjunto de setas) apontará para cim a, de R. para R;, e uma seta (ou conjunto de setas) apontará para baixo, de R. para R. se j > i. Entretanto, Processo Pi obteve os recursos R3 . R4 . Rô e R7 e está requisitando o recurso Rg (como indicado pela linha pontilhada). Nenhuma espera circular pode ser desenvolvida porque todas as setas devem apontar para cima. F igura 7.5 Ordenamento linear de, recursos de, Havenderpara, evitar deadlock. m SUtWiAS OjMTílciotUlti a ordenação linear dos recursos com a exigência para que os sejam solicitados em ordem ascendente im plica que nenhum a seta, em tem po algum, possa ir de R para R. se j > i. Portanto, não pode ocorrer deadlock nesse sistema.] A negação da condição de ‘espera circular’ foi im plem entada em diversos sistemas operacionais herdados, mas não sem dificuldades.15,16,I7,18 Uma desvantagem dessa estratégia é que ela não é tão flexível ou dinâm ica com o seria o dese­ jado. Os recursos precisam ser requisitados em ordem ascendente por núm ero do recurso. Esses números são designados para o sistem a do com putador e é preciso ‘viver com eles’ por longos períodos (m eses ou até anos). Se forem adicionados novos recursos ou removidos recursos antigos em um a instalação, talvez os program as e sistem as existentes precisem ser reescritos. U m a outra dificuldade é determ inar o ordenam ento dos recursos de um sistema. Claram ente, os núm eros dos recursos devem ser designados para refletir a ordem em que a m aioria dos processos os utiliza. No caso dos processos que seguem essa ordem, pode-se esperar um a operação m ais eficiente. Mas, no caso de processos que precisam de recursos em ordem diferente da especificada pelo ordenam ento linear, os recursos devem ser adquiridos e retidos, possivelm ente por longos períodos, antes que sejam realm ente usados, o que pode resultar em mau desempenho. U m a meta im portante dos sistem as operacionais de hoje é prom over a portabilidade do software através de m últiplos am bientes. Os program adores devem desenvolver suas aplicações sem que o hardw are e o softw are lhes im ponham res­ trições desvantajosas. O ordenam ento linear de H avender realm ente elim ina a possibilidade de um a espera circular, mas reduz a capacidade de um program ador escrever, com facilidade e livrem ente, código de aplicação que m axim izará o desem penho de um a aplicação. RcvU cur 1. Com o um ordenam ento linear para alocação de recursos reduz a portabilidade da aplicação? 2. (V/F) Im por ordenam ento linear para requisições de recursos resulta em desem penho m ais alto do que negar a condição de ‘não-preem pção’. R e ip o ííà i: 1) Sistem as diferentes norm alm ente terão conjuntos distintos de recursos e ordenarão recursos diferen­ tem ente, portanto, um a aplicação escrita para um sistem a poderá precisar ser modificada para executar efetivam ente em outro sistema. 2) Falso. H á situações em que um a dada solução resulta em desem penho mais alto porque exige uma sobrecarga insignificante. Se cada processo de um sistem a requisitar conjuntos de recursos desarticulados, a negação da ‘não-preem pção’ será bastante eficiente. Se um processo usar recursos em um a ordem correspondente ao ordenam ento linear do sistema, então negar a condição ‘de espera circular’ poderá resultar em desem penho m ais alto. 7.8 Bvibação de, deadlock, cone o Algoritmo do BaJUjtieiro de, Üijkstra, N o caso de alguns sistemas é impraticável implem entar as estratégias de prevenção de deadlock que discutimos na seção anterior. Todavia, m esm o existindo as condições necessárias para um deadlock, ainda assim é possível evitá-lo alocando cuidadosam ente recursos do sistema. Talvez o mais fam oso algoritmo para evitar deadlock seja o Algoritmo do Banqueiro de Dijkstra, assim denom inado porque a estratégia é modelada segundo um banqueiro que concede em préstim os por meio de um a reserva de capital e recebe pagam entos que são reintegrados ao capital.19,20,21,22,23Aqui nós parafraseam os o algo­ ritm o no contexto da alocação de recursos de sistem as operacionais. Subseqüentem ente, m uito trabalho foi desenvolvido no assunto evitação de deadlock.24,25,26,27,28,29,30,31 O Algoritm o do Banqueiro define com o um sistem a particular pode evitar deadlock controlando cuidadosam ente a distribuição dos recursos aos usuários (veja no site deste livro: “Curiosidades, A crônim os”). Um sistem a agrupa todos os recursos que gerencia em tipos de recursos. Cada tipo de recurso corresponde a recursos que fornecem funcionalidade idêntica. Para simplificar nossa apresentação do Algoritm o do Banqueiro, lim itam os nossa discussão a um sistem a que adm inistra somente um tipo de recurso. O algoritm o pode ser estendido facilm ente a reservatórios de recursos de vários tipos, o que ficará para os exercícios. O A lgoritm o do Banqueiro evita deadlock em sistem as operacionais que exibem as seguintes propriedades: • O sistem a operacional com partilha um núm ero fixo de recursos, r, entre um núm ero fixo de processos, n. • Cada processo especifica previam ente o núm ero máxim o de recursos que requer para concluir seu trabalho. • O sistem a operacional aceita a requisição de um processo, se a necessidade máxima daquele processo não exceder o núm ero total de recursos disponíveis no sistema, t (o processo não pode requisitar mais do que o núm ero total de recursos disponíveis no sistema). • Às vezes um processo pode ter de esperar para obter um recurso adicional, mas o sistem a operacional garante um tem po de espera finito. Ca^üuio7 • VeaModc &aMaiíimto indefinido JÇJ Se o sistema operacional conseguir satisfazer à necessidade máxima de recursos de um processo, o processo garantirá que o recurso será usado e liberado para o sistem a operacional em um tempo finito. D iz-se que o sistem a está em estado seguro se o sistem a operacional puder garantir que todos os processos atuais possam concluir seu trabalho em um tempo finito. Se não, diz-se que o sistem a está em estado inseguro. Também definimos quatro term os que descrevem a distribuição de recursos entre processos. • Convencionemos que max(P.) seja o núm ero máxim o de recursos que o processo P. requer durante sua execução. Por exem plo, se o processo P3 nunca requisitar m ais do que dois recursos, então max(P3) = 2. • Convencionemos que loan(P.) represente o empréstimo (loan) corrente de um recurso pelo processo P., no qual em préstim o quer dizer o núm ero de recursos que o processo já obteve do sistema. Por exem plo, se o sistem a alocou quatro recursos ao processo P5, então loan(P5) = 4. • D igam os que claim(P.) seja a solicitação de empréstimo (claim) corrente de um processo no qual a solicitação de um processo é igual à sua necessidade m áxim a menos seu em préstim o corrente. Por exem plo, se o processo P7 tiver um a necessidade m áxim a de seis recursos e um em préstim o corrente de quatro recursos, então temos: c la im ( • P7) = m ax( P7) - lo a n ( P7) = 6 -4 = 2 Seja a o núm ero de recursos ainda disponíveis para alocação. Isso equivale ao núm ero total de recursos (f) menos a som a dos em préstim os para todos os processos do sistema, isto é, n a = l o a n ( P .) i= 1 Portanto, se o sistem a tiver um total de 3 processos e 12 recursos e tiver alocado 2 recursos ao processo P p 1 recurso ao processo P 2e 4 recursos ao processo P3, então o núm ero de recursos disponíveis será: a = 12 -(2 + 1 + 4 ) = 1 2 - 7 = 5 O A lgoritm o do Banqueiro de D ijkstra determ ina que recursos sejam alocados a um processo som ente quando as alo­ cações resultarem em estados seguros. Desse modo, todos os processos perm anecem em estados seguros o tem po todo e o sistem a nunca sofrerá deadlock. R w U cur 1. (V/F) Um estado inseguro é um estado de deadlock. 2. D escreva as restrições que o A lgoritm o do Banqueiro im põe aos processos. R e ip o ità i l 1) Falso. U m processo que está em estado inseguro pode eventualm ente sofrer deadlock ou pode concluir sua execução sem sofrer deadlock. O que tom a o estado inseguro é sim plesm ente que, nesse estado, o sistem a operacional não pode garantir que todos os processos concluam seu trabalho; um sistem a que está em estado inseguro podería even­ tualm ente sofrer deadlock. 2) Antes de executar, solicita-se que cada processo especifique o núm ero máxim o de recursos que pode requisitar a qualquer instante durante sua execução. N enhum processo pode requisitar mais do que o número total de recursos do sistema. Cada processo tam bém deve garantir que, tão logo lhe seja alocado um recurso, o processo eventualm ente o devolverá ao sistem a dentro de um tempo finito. 7.8.1 ExentfUo d&unv estado seguro Suponha que um sistem a contenha 12 recursos equivalentes e 3 processos com partilhando os recursos, com o na Figura 7.6. A segunda coluna contém a necessidade m áxim a para cada processo, a terceira coluna, o em préstim o corrente para cada processo e a quarta coluna, a solicitação de em préstim o de cada processo. O núm ero de recursos disponíveis, a, é 2; isso é calculado subtraindo-se a som a das solicitações correntes do núm ero total de recursos, / = 12. Esse estado é ‘seguro’ porque os três processos têm possibilidade de terminar. N ote que o processo P2 tem, correntem en­ te, um em préstim o de 4 recursos e eventualm ente precisará de um m áxim o de 6, ou seja, 2 recursos adicionais. O sistema tem 12 recursos, dos quais 10 estão correntem ente em uso e 2 disponíveis. Se o sistem a alocar os 2 recursos disponíveis a P2, satisfazendo a necessidade m áxim a de P2, então P2poderá executar até concluir. N ote que, após P 2terminar, liberará 6 recursos, capacitando o sistem a a atender im ediatam ente às necessidades m áxim as de P, (3) e P 3(3), habilitando am bos esses processos a terminar. D e fato, todos os processos podem term inar com base no estado seguro da Figura 7.6. m Sistemas operacionais Processo M iA X ( P . ) ÍOMl( P ) (necessidade. máxim a) (em préstim o T o ta l d e r e c u r s o s , \ , = 1 2 c o r r e n te s ) cía im ( P ) (sotictàiçÃô corrente) 1 3 4 5 2 3 R e c u r s o s d is p o n ív e is , a, = 2 Figurar 7.6 Estado seguro. R eM cuy 1. N a Figura 7.6, assim que P2 finalizar sua execução, P, e P2 devem executar seqüencialm ente um após o outro ou poderíam executar concorrentem ente? 2. Por que tratamos inicialm ente de perm itir que P2 term ine em vez de escolher P, ou P3? R e ib o tfõ i: i ) p , e P 3 necessitam , cada um , de mais 3 recursos para finalizar. Q uando P2 terminar, liberará 6 recursos, o que e suficiente para P, e P3executarem concorrentem ente. 2) Porque P2 é o único processo cuja solicitação pode ser satisfeita pelos 2 recursos disponíveis. 7.8.2 Exemplo um estado inseguro Suponha que os 12 recursos de um sistem a estejam alocados com o m ostra a Figura 7.7. Som ando os valores da terceira coluna e subtraindo o total de 12, obtem os um valor de 1 para a . N esse ponto, não im portando qual processo requisite o recurso disponível, não podem os garantir que todos os 3 processos term inarão. De fato, suponha que o processo P, requi­ site e obtenha o últim o recurso disponível. Pode ocorrer um deadlock de três vias se cada processo precisar requisitar no m ínimo m ais um recurso antes de liberar quaisquer recursos para o reservatório. Nesse caso, é im portante notar que um estado inseguro não implica a existência de deadlock, nem mesmo que um deadlock ocorrerá eventualmente. O que um estado inseguro implica é sim plesm ente que alguma sequência de eventos nefastos possa levar a um deadlock. R ev íiã o ' 1. Por que o deadlock é possível, mas não garantido, quando um sistem a entra em um estado inseguro? 2. Qual o núm ero m ínimo de recursos que teria de ser adicionado ao sistem a da Figura 7.7 para transform á-lo em estado seguro? Reipoifai: i) Processos poderíam devolver seus recursos mais cedo, aum entando o núm ero disponível até o ponto em que o estado do sistem a voltasse a ser seguro e todos os processos pudessem concluir. 2) A dicionando um recurso, o (necessidade> ioaun( P ) (em préstim o cíaÀm( P ) (solicitação vná/xivna,) corrente,') corrente) V M M c( P ) Processo p, 10 5 3 p2 p3 T o ta l d e r e c u r s o s , t, = 12 Figurco 7.7 Estado inseguro. 8 2 2 3 1 2 R e c u r s o s d is p o n ív e is , a, = 1 Cajútuio 7 VeoAiock e,aMam^nto indefinido JQ £ num ero de recursos disponíveis fica sendo 2, o que perm ite que P, term ine e devolva seus recursos, habilitando tanto P2 quanto P3 a terminar. Portanto, o novo estado é seguro. 7.8.3 Exewftlo d& transição de-estude seguro para; estado inseguro N ossa política de alocação de recursos deve considerar cuidadosam ente todas as requisições de recursos antes de atendê-las, senão um processo que está em estado seguro poderá entrar em estado inseguro. Por exemplo, suponha que o estado corrente de um sistem a seja seguro, com o m ostra a Figura 7.6. O valor corrente á t a 6 2. A gora suponha que o Processo P3 requisite um recurso adicional. Se o sistem a atendesse a essa requisição, o novo estado seria o da Figura 7.8. A gora o valor corrente de a é 1, o que não é suficiente para satisfazer à solicitação corrente de qualquer processo, portanto o estado agora é inseguro. Ret/U cur 1. Se o Processo P2requisitasse um recurso adicional na Figura 7.6, o sistem a estaria em estado seguro ou em estado inseguro? 2. (V/F) Um sistem a não pode transitar de um estado inseguro para um estado seguro. R e íp o itü i: i ) O sistem a ainda estaria em estado seguro, porque há um cam inho de execução que não resultará em deadlock. Por exemplo, se P2 requisitar um outro recurso, poderá concluir a execução. Então haverá 6 recursos disponíveis, o que é suficiente para a finalização de P, e P3. 2) Falso. À m edida que os processos liberam recursos, o núm ero de recursos disponíveis pode tom ar-se suficientemente grande para o estado do sistem a transitar de inseguro para seguro. 7.8A Alocuçào der recursospelo Algoritmo do Banqueiro A gora já deve ter ficado claro com o funciona a alocação de recursos sob o Algoritm o do Banqueiro de Dijkstra. As condições ‘exclusão m útua’, ‘de espera’ e ‘não-preem pção’ são perm itidas — processos podem reter recursos ao mesmo tempo que requisitam e esperam recursos adicionais, e os recursos retidos por um processo não podem sofrer preem pção. Com o sempre, os processos reclam am a utilização exclusiva dos recursos que requisitam . Processos insinuam -se no sis­ tem a requisitando um recurso por vez; o sistem a pode conceder ou negar cada solicitação. Se um a requisição for negada, o processo reterá quaisquer recursos alocados e esperará durante um tem po finito até que a solicitação seja eventualm ente atendida. O sistema atende somente a requisições que resultam em estados seguros. Requisições de recursos que resultariam em estados inseguros são negadas repetidam ente até que possam ser eventualm ente satisfeitas. Com o o sistem a é sempre mantido em estado seguro, m ais cedo ou m ais tarde (em um tempo finito) todas as requisições podem ser satisfeitas e todos os usuários podem finalizar. R e tfiã o ' 1. (V/F) O estado definido na Figura 7.9 é seguro. 2. Que núm ero m ínimo de recursos adicionados ao sistem a da Figura 7.8 tom aria o estado seguro? Reipaitãi: 1) Falso. Não há garantia de que todos esses processos terminarão. P 2 poderá term inar usando os 2 recur­ sos rem anescentes. Todavia, uma vez term inado P 2, restarão somente 3 recursos disponíveis, o que não é suficiente para d a im (P ) ( n e c e s s id a d e ; P) (empréstimo máxim a) c o r r e n te ;) corrente;) H M /X c( P . ) Processo 4 ÍO M t( (solicitação 6 1 4 3 2 8 6 2 T o ta l d e r e c u r s o s , t , = 1 2 F igura, 7.8 Transição de, estado seguro para, inseguro. R e c u r s o s d is p o n ív e is , a, = 1 194 S U tW iA S OjMTílciotUlti Processo IS U IX ( P ) Pi p2 p. 5 3 10 loatt( P ) doÁMi^ P ) 1 1 4 5 5 2 a = 2 V-lguras 7.9 Descrição de, estado de, tris processos. satisfazer a solicitação de 4 recursos de P,, nem a solicitação de 5 recursos de Pr 2) A dicionando um ou m ais recursos poderiam os perm itir que P2 term inasse e devolvesse 3 recursos. Esses, mais o recurso adicionado, habilitariam P, a terminar, devolvendo 5 recursos e perm itindo a finalização de P3. 7.8.5 Veficiêtuzas do Algoritmo do Bcuujtteiro O A lgoritm o do Banqueiro é atraente porque perm ite que processos que poderíam ter de esperar sob um a situação de prevenção de deadlock, prossigam . M as o algoritm o tem algumas deficiências. • Requer que haja um núm ero fixo de recursos para alocar. Porque os recursos freqüentem ente precisam de serviços devido a avarias ou m anutenção preventiva, não podem os contar que seu núm ero perm aneça fixo. Similarmente, sistem as operacionais que suportam dispositivos que podem ser substituídos sem precisar desligar o com putador (hot swappable devices) — por exem plo, dispositivos USB — perm item que o núm ero de recursos varie dinam i­ camente. • O algoritm o requer que a população de processos perm aneça fixa, o que tam pouco é razoável. Nos sistem as inte­ rativos e de m ultiprogram ação atuais, a população de processos está constantem ente mudando. • O algoritm o requer que o banqueiro (o sistem a) atenda a todas as solicitações dentro de um ‘tempo finito’. Sistemas reais, em especial os de tempo real, claram ente precisam de garantias m uito m elhores do que essas. • Similarmente, o algoritmo requer que clientes (processos) paguem todos os seus empréstimos (devolvam todos os re­ cursos) dentro de um ‘tempo finito’. Mais um a vez, sistemas reais precisam de garantias muito melhores do que essa. • O algoritm o requer que o processo declare previam ente suas necessidades máximas. Com a alocação de recursos tom ando-se cada vez m ais dinâm ica, fica mais difícil saber de antem ão as necessidades máxim as de um processo. D e fato, um dos principais benefícios das linguagens de program ação de alto nível e das interfaces gráficas com o usuário ‘am igáveis’ de hoje é que os usuários não precisam conhecer detalhes de nível tão baixo quanto a utilização de recursos. O usuário ou o program ador espera que o sistem a ‘im prim a o arquivo’ ou ‘envie a m ensagem ’ e não quer se preocupar com os recursos que o sistem a talvez precise em pregar para honrar tais solicitações. Pelas razões citadas, o Algoritm o do Banqueiro de D ijkstra não é implem entado nos sistem as operacionais atuais. De fato, poucos sistem as podem sustentar a sobrecarga incorrida por estratégias de evitação de deadlocks. Rertião' 1. Por que o A lgoritm o do Banqueiro falha em sistemas que suportam dispositivos hot swappable (que podem ser trocados sem desligar o com putador)? R êip a ítõ /I 1) O Algoritm o do Banqueiro requer que o núm ero de recursos de cada tipo perm aneça fixo. Dispositivos hot swappable podem ser adicionados e rem ovidos do sistem a a qualquer instante, o que significa que o núm ero de recursos de cada tipo pode variar. 7.9 Vetecçào de, deaAlock, D iscutim os prevenção e evitação de deadlock — duas estratégias para assegurar que não ocorram deadlocks em um sistema. Uma outra estratégia é perm itir que eles ocorram e, então, localizá-los e removê-los, se possível. D etecção de d ead lo ck s é um processo que determ ina se existe um deadlock e identifica os processos e recursos envolvidos nele.32’33,34* 35.36.37.38.39.4o q s algoritm os de detecção de deadlocks geralm ente concentram -se em determ inar se existe espera circular adm itindo que existam as outras condições necessárias para deadlock. Algoritm os de detecção de deadlocks podem resultar em significativa sobrecarga de tempo de execução. Assim, enfren­ tamos novam ente as perm utas tão com uns em sistem as operacionais — a sobrecarga envolvida na detecção de deadlocks C&püulo7 VeaModc &aMaiíimto indefinido JÇ £ é justificada pelas econom ias potenciais propiciadas pela sua localização e rom pim ento? Por enquanto ignorarem os essa questão e nos concentrarem os no desenvolvim ento de algoritm os capazes de detectar deadlocks. 7.9.1 Qrafos d&aloaição d c recursos Para facilitar a detecção de deadlocks é usada um a notação popular (Figura 7.10) na qual um grafo com setas indica alocações e requisições de recursos.41 Q uadrados representam processos, e círculos grandes representam classes de recursos idênticos. Círculos menores desenhados dentro dos círculos grandes indicam a quantidade de recursos idênticos de cada classe. Por exemplo, um círculo grande denom inado ‘R j’ que contém três círculos pequenos indica que há três recursos equivalentes do tipo R, disponíveis para alocação neste sistema. A Figura 7.10 ilustra as relações que podem ser indicadas em um grafo de requisições e alocação de recursos. Na Figura. 7.10(a) o processo P, está requisitando um recurso do tipo R,. A seta que sai de P, toca apenas a extrem idade do círculo grande, indicando que a requisição do recurso está sob consideração. N a Figura 7.10(b) um recurso do tipo R2 (do qual existem dois) foi alocado ao processo P2. A seta é desenhada desde o círculo pequeno que está dentro do círculo grande R 2 até o quadrado P2, indicando que o sistem a alocou um recurso específico daquele tipo ao processo. A Figura 7.10(c) indica um a situação um pouco mais próxim a de um deadlock potencial. O Processo P3 está requisi­ tando um recurso do tipo R3, mas o sistem a alocou o único recurso R3 ao processo P4. A Figura 7.10(d) indica um sistem a em deadlock no qual o Processo P5 está requisitando um recurso do tipo R4, o único dos quais o sistem a alocou ao processo P6. O Processo P6 está requisitando um recurso do tipo R5, o único dos quais o sistem a alocou ao Processo P5. Esse é um exemplo de ‘espera circular’ necessária para causar um deadlock no sistema. Grafos de requisição e alocação de recursos mudam à m edida que processos requisitam recursos, obtêm -nos e eventual­ m ente os devolvem ao sistem a operacional. R evu ã o ' 1. Suponha que um processo tenha o controle de um recurso do tipo R r É im portante dem onstrar qual círculo pequeno aponta para o processo no grafo de alocação de recursos? Pi (a) Pi está requisitando um recurso do tipo Ri, do qual há dois recursos idênticos. (b) Um dos dois recursos idênticos do tipo R2 foi alocado ao processo P2 . (c) O processo P3 está requisitando o recurso R^, que foi alocado ao processo P4. R4 0 r5 (0 u ra y 7 .1 0 | Q rafos d& cdoczição e, re q u isiç ã o d& recursos. (d) O recurso P5 foi alocado ao processo R5 e está sendo requisitado pelo processo Pe, ao qual foi alocado o recurso R 4 que está sendo requisitado pelo processo P5 (a clássica 'espera circular'). 196 S titw u u operncíôKAà 2. Qual condição necessária para deadlock é m ais fácil de identificar: por meio de um grafo de alocação de recursos ou analisando os dados de alocação de recursos de todos os processos do sistema? RêipOitsUI 1) Não; todos os recursos do m esm o tipo devem fornecer funcionalidade idêntica, portanto, não im porta qual dos círculos pequenos dentro do círculo R, aponta para o processo. 2) Grafos de alocação de recursos facilitam a identificação de esperas circulares. 7.9.2 Redução d&grafos d&alocação d& recursos U m a técnica útil para detectar deadlocks envolve a redução de grafos, pela qual são determ inados os processos, se houver, que podem concluir sua execução e os processos que continuarão em deadlock (assim com o os recursos envolvidos naquele deadlock), se houver.42 Se as requisições de recurso de um processo puderem ser atendidas, dizem os que um grafo pode ser red u zid o daquele processo. Essa redução equivale a m ostrar com o o grafo ficaria se o processo pudesse concluir sua execução e devolver seus recursos ao sistema. Reduzim os um grafo de um processo retirando as setas que se dirigem dos recursos àquele processo (recursos alocados àquele processo) e retirando as setas que se dirigem daquele processo até os recursos (as requisições de recursos correntes daquele processo). Se um grafo puder ser reduzido de todos os seus processos, então não haverá deadlock. Se um grafo não puder ser reduzido de todos o seus processos, os processos irredutíveis constituirão o conjunto de processos em deadlock daquele grafo. A Figura 7.11 m ostra um a série de reduções de grafos que dem onstram que um conjunto particular de processos não está em deadlock. A Figura 7.10(d) m ostra um conjunto irredutível de processos que constituem um sistem a em deadlock. É im portante notar que a ordem em que as reduções do grafo são realizadas não interessa. D eixam os as provas desse re­ sultado para os exercícios (veja o Exercício 7.29). Revuão' 1. Por que a detecção de deadlock podería ser um a política m elhor do que a prevenção ou a evitação de deadlock? Por que podería ser um a política pior? 2. Suponha que um sistem a tente reduzir a sobrecarga da detecção de deadlocks fazendo detecção de deadlocks so­ m ente quando houvesse um grande núm ero de processos no sistema. Cite um a desvantagem dessa estratégia. R e ip o itã i 1 1) Em geral a detecção de deadlock coloca menos restrições sobre a alocação de recursos aum entando assim a utilização desses recursos. Entretanto, requer que o algoritmo de detecção de deadlock seja executado regularmente, o que pode resultar em sobrecarga significativa. 2) Com o pode ocorrer deadlock entre dois processos, é possível que o sistema nunca detecte alguns deadlocks se o núm ero de processos no sistem a for pequeno. 7.10 RecuftercLÇÂô deadlodc U m a vez que um sistem a tenha entrado em deadlock, esse deve ser rom pido pela remoção de um a ou m ais das quatro condições necessárias. Em geral diversos processos perderão um pouco ou todo o trabalho que já realizaram. Contudo, o preço a pagar pode ser pequeno em com paração a deixar o sistem a em um estado em que não possa usar alguns de seus recursos. A recuperação de deadlocks é com plicada por diversos fatores. Prim eiro, pode não estar claro que o sistem a esteja em deadlock. Por exemplo, a m aioria dos sistem as contém processos que acordam periodicam ente, realizam certas tarefas e então voltam a dormir. Com o esses processos não term inam antes de o sistem a ser desligado e porque raram ente entram em estado ativo, é difícil determ inar se estão em deadlock. Segundo, a m aioria dos sistemas não fornece os meios para suspender um processo indefinidamente, retirá-lo do sistem a e retom ar a operação (sem perda de trabalho) mais tarde. N a verdade, alguns processos, com o os de tem po real que devem funcionar continuam ente, apenas não se prestam a ser suspensos e retomados. Adm itindo que existissem as capacidades efetivas de suspensão e retomada, elas certam ente envol­ veríam considerações de sobrecarga e poderíam exigir a atenção de um adm inistrador de sistem as altam ente qualificado, e esse adm inistrador nem sempre está disponível. Por fim, a recuperação de deadlock é com plicada, porque o deadlock pode envolver m uitos processos (dezenas ou até centenas). D ado que mesmo com um núm ero pequeno de processos, a recuperação de deadlocks podería dem andar considerável trabalho; tratar de um deadlock entre muitas centenas (ou até mais) de processos podería ser um a tarefa monumental. Em sistemas atuais, a recuperação é ordinariam ente realizada pela retirada forçada de um processo do sistem a e re­ tom ada de seus recursos.43,44 O sistem a ordinariam ente perde o trabalho que o processo retirado realizou, mas perm ite que os processos rem anescentes terminem. Às vezes é necessário retirar diversos processos até que sejam recuperados Ca^vtuio 7 Veadlodc e,adhiMettto indefinido JÇ J Reduzido de P9 fig u ra , 7.11 Reduções d&grafo determinando que, não existe, nenhum, deadloch. recursos suficientes para perm itir que os processos rem anescentes finalizem. Recuperação parece, de certa m aneira, um termo inadequado, porque alguns processos na verdade são ‘m ortos’ em benefício de outros. Processos podem ser retirados segundo algum a ordem de prioridade, e tam bém nesse caso enfrentam os diversas difi­ culdades. Por exemplo, os processos em deadlock podem não ter prioridade, portanto o sistem a podería ter de tom ar uma decisão arbitrária. As prioridades tam bém podem estar incorretas ou um pouco atrapalhadas por considerações especiais, com o escalo n am en to p o r p ra z o no qual um processo de prioridade relativam ente baixa tem um a prioridade alta tem ­ porariam ente por causa de algum prazo que está prestes a se esgotar. A lém do mais, talvez seja preciso um considerável esforço para determ inar qual processo retirar. O mecanismo de suspensão/retom ada perm ite que o sistem a retenha tem porariam ente um processo (causando a preempção tem porária de seus recursos) e, quando for seguro, retom e o processo retido sem perda de trabalho. A pesquisa nessa área é im portante por outras razões além da recuperação de deadlock. Por exemplo, um m ecanism o de suspensão/retom ada 198 Sistemasojteraxiofuus pode ser aplicado a um sistem a com o um todo perm itindo que um usuário desligue todo o sistem a e reinicie m ais tarde sem perda de trabalho. Essa tecnologia tem sido incorporada em muitos sistemas de laptops nos quais a vida lim itada da batería requer que os usuários m inim izem o consum o de energia. A interface avançada de configuração e energia {Ad­ vanced Configuration and Power Interface— A C PI), um a especificação popular para gerenciam ento de energia, define um estado adorm ecido no qual o conteúdo da m emória, registradores e outras inform ações de estado de sistem a são gravados em um elem ento não volátil (com o um disco rígido), e o sistem a é desligado. No W indows X P esse recurso é conhecido com o ‘suspender para o disco’ ou ‘hibernar’. Q uando o sistem a é reiniciado, ele volta ao ponto em que entrou no estado adorm ecido, sem perda de trabalho.45 Verificação/reversão de estado, precursora da suspensão/retomada, é am plam ente usada em sistemas bancários atuais. A verificação/reversão de estado enfrenta falhas de sistem a e deadlocks tentando preservar o máxim o possível de dados de cada processo term inado e facilita as capacidades de suspensão/retom ada lim itando a perda de trabalho ao instante em que a últim a verificação foi feita (o instante em que o últim o estado do sistem a foi salvo). Q uando um processo term ina em um sistem a (por acidente ou intencionalm ente com o resultado de um algoritm o de recuperação de deadlock), o siste­ m a realiza um a reversão de estado desfazendo todas as operações relacionadas com o processo term inado que tenham ocorrido desde a últim a verificação. Q uando bancos de dados têm muitos recursos (talvez m ilhões ou mais) que devem ser acessados exclusivamente, pode haver risco de deadlock. Para garantir que os dados do banco de dados continuem em um estado consistente quando os pro­ cessos em deadlock forem term inados, os sistemas de banco de dados norm alm ente realizam alocações de recursos usando transações. As m udanças especificadas por um a transação tom am -se perm anentes apenas se a transação for concluída com sucesso. Discutirem os transações m ais detalhadam ente no Capítulo 13, “Arquivos e sistem as de bancos de dados” . Deadlocks poderíam provocar conseqüências horrendas em certos sistemas de tem po real. U m sistem a de controle de processo de tempo real que m onitora uma refinaria de petróleo deve funcionar sem interrupção para a segurança e adequação da operação das instalações industriais. Um m arca-passo com putadorizado, literalmente, não deve ‘perder nenhum a batida’ do coração. N ão se pode arriscar deadlocks nesses am bientes. O que aconteceria se um deadlock se desenvolvesse? É claro que teria de ser detectado e rem ovido imediatamente. M as isso é sem pre possível? Essas são algum as das considerações que tiram o sono de projetistas de sistem as operacionais. R& M cur 1. (V/F) Um sistem a pode elim inar deadlock escolhendo aleatoriam ente um processo irredutível em um grafo de alocação de recursos. 2. Por que um sistem a que reinicia um processo que ele próprio ‘m atou’ para rom per um deadlock pode apresentar mau desem penho? R e ip o itã i: i ) Falso. Pode haver m últiplas esperas circulares dentro do sistem a quando um deadlock é detectado. 2) Prim eiro, porque m atar um processo causa perda de trabalho. Segundo, porque o processo reiniciado executará o m esm o código que causou o deadlock inicial, e se o estado do sistem a não m udou, o sistem a pode entrar em deadlock repetidam ente. 7.11 Estratégias JLeaAlodc em/sistemas atuais e/futuros Em sistem as de com putadores pessoais e estações de trabalho, o deadlock geralm ente tem sido considerado um aborrecim ento lim itado. A lguns sistem as im plem entam os m étodos básicos de prevenção de deadlock sugeridos por Havender, enquanto outros ignoram o problem a — esses m étodos parecem satisfatórios. Em bora ignorar deadlocks tal­ vez pareça perigoso, na realidade essa abordagem pode ser bastante eficiente. Considere que os sistem as de hoje podem conter m ilhares ou m ilhões de objetos reutilizáveis serialm ente nos quais processos e threads podem sofrer deadlock. O tem po exigido para executar um algoritm o de detecção de deadlock pode aum entar exponencialm ente com o núm ero de objetos serialm ente reutilizáveis do sistem a. Se o deadlock for raro, o tem po de processador devotado à verificação de deadlocks reduzirá significativam ente o desem penho do sistem a. Em sistem as que não são de m issão crítica e nem críticos para negócios, ignorar o deadlock em favor do desem penho m uitas vezes vale m ais a pena do que solucionar um deadlock ocasional. Em bora alguns sistem as ignorem deadlocks que ocorram devido a processos usuários, é m uito mais im portante evitar deadlocks no sistem a operacional. Sistemas com o o M icrosoft W indows oferecem suporte de depuração que perm item aos desenvolvedores testar m inuciosam ente drivers e aplicações para garantir que adquiram recursos sem causar deadlocks (por exemplo, não tentem obter travas em rotinas recursivas, ou especificar aquisição de travas em um a certa ordem).46 O interessante é que logo que esses program as são liberados, m uitas vezes os m ecanism os de teste são desabilitados para m elhorar a eficiência.47 Cajútuio 7 Veadlocks e,aMjuiiMtto indefinido JQQ Em sistem as de tem po real, de m issão crítica ou críticos para negócios, a possibilidade de deadlock não pode ser tolerada. Pesquisadores desenvolveram técnicas que tratam deadlocks e, ao m esm o tem po, m inim izam a perda de dados e m antêm o bom desem penho. Por exemplo, o deadlock é com um ente abordado em sistem as de bancos de dados distri­ buídos que poderíam fornecer acesso concorrente a bilhões de registros para m ilhões de usuários por m eio de m ilhares de localizações.48 Devido a seu grande tam anho, os sistem as de bancos de dados distribuídos norm alm ente não empregam algoritm os de prevenção de deadlock e evitação de deadlock. Em vez disso, confiam na detecção e recuperação de dead­ lock via verificação/reversão de estado (usando transações).49 Essas técnicas estão além do escopo deste capítulo; veja o Capítulo 17, “Introdução a sistemas distribuídos” , para um a iniciação a esses métodos. Dadas as tendências atuais, o deadlock continuará sendo um a área im portante de pesquisa por várias razões: • M uitos sistem as de grande escala são orientados mais a operações assíncronas paralelas do que a operações seriais do passado. O m ultiprocessam ento é com um e a com putação paralela será dominante. Redes e sistem as distribuídos são ubíquos. Sim plesm ente falando, há m ais operações ocorrendo concorrentem ente, m ais conflitos por recursos e, portanto, mais chances de deadlock. Em conseqüência, a pesquisa sobre detecção e recuperação de deadlock em sistem as distribuídos tom ou-se muito ativa. • Com o a tendência crescente dos projetistas de sistemas operacionais é considerar dados com o um recurso, o número de recursos que os sistemas operacionais têm de adm inistrar está aum entando drasticam ente. Isso m ostra-se particu­ larmente evidente em servidores Web e sistem as de bancos de dados que requerem intensa utilização de recursos e alto desem penho, o que tom a impraticáveis a m aioria das técnicas de prevenção de deadlock e m ais im portantes os algoritm os de recuperação de deadlock. Pesquisadores desenvolveram algoritmos avançados baseados em transação que asseguram alta utilização de recursos enquanto m antêm um baixo custo de recuperação de deadlock.50 • Centenas de m ilhões de com putadores são incorporados em dispositivos comuns, particularm ente nos pequenos e portáteis com o telefones celulares, PDAs e sistem as de orientação geográfica. Esses cada vez m ais caracterizados com o sistem as em um chip (System s on a Chip — SoC), são lim itados por um pequeno conjunto de recursos e pelas dem andas das tarefas de tempo real.51,52 N esses sistemas a alocação de recursos livres de deadlock é essencial, porque os usuários não podem confiar em um adm inistrador para detectar e livrar o sistem a de um deadlock. Ret/Uão' 1. Por que a prevenção de deadlock não é um a preocupação prim ária para m uitos sistemas operacionais? 2. Por que pode ser mais difícil detectar o deadlock em sistemas distribuídos do que em um com putador isolado? R e ip a ifa i: 1) O deadlock é raro e m uitas vezes considerado um aborrecim ento de m enor im portância pela m aioria dos usuários de com putadores pessoais que, em geral, está m ais preocupada com as características e o desempenho dos sistemas operacionais. 2) Pode ser difícil detectar deadlock em sistemas distribuídos, porque cada com putador é adm inistrado por um sistem a operacional diferente, o que exige que cada sistem a operacional colete inform ações de outros com putadores para m ontar seu grafo de alocação de recursos. R esu m o Um p ro b lem a que surge em sistem as de m ultiprogram ação é o deadlock. U m processo ou thread está em estado de deadlock (ou está travado) se estiver esperando por determ inado evento que não ocorrerá. No deadlock de sistem a um ou m ais processos estão em deadlock. A maioria dos deadlocks se desenvolve por causa da disputa normal por recursos dedicados (recursos que podem ser usados por apenas um usuário por vez). Espera circular é característica de sistemas em deadlock. Um exem plo de um sistem a propenso a deadlock é o sistem a de spooling. U m a solução com um é restringir os spoolers de entrada para que não aceitem m ais serviços de impressão quando os arquivos de spooling estiverem prestes a atingir um certo lim ite de saturação. Os sistemas de hoje perm item que a im pressão com ece antes de um serviço estar concluído para que um arquivo de spooling cheio, ou quase cheio, possa com eçar a ser esvaziado ou parcialm ente libe­ rado mesmo que ainda haja um serviço em execução. Esse conceito tem sido aplicado a clipes de áudio e vídeo de tempo real quando o áudio e o vídeo com eçam a ser ouvidos e vistos antes de ser totalm ente descarregados (streaming). Em qualquer sistem a que m antenha processos à espera enquanto ele tom a decisões de alocação de recursos e esca­ lonam ento de processos, é possível atrasar indefinidamente o escalonamento de um processo enquanto outros recebem a atenção do sistema. Essa situação, denominada variadamente de adiam ento indefinido, bloqueio indefinido ou inanição, pode ser tão devastadora quanto o deadlock. A diam ento indefinido pode ocorrer por causa de vieses das políticas de escalonam ento de recursos do sistema. Alguns sistemas 200 Sistemas ojwaciotuus im pedem o adiam ento indefinido elevando a prioridade de um processo enquanto ele espera por um recurso — essa técnica é denom inada envelhecimento (aging). Recursos podem ser preem ptivos (por exem plo, proces­ sadores e m em ória principal), o que significa que podem ser retirados de um processo sem perda de trabalho, ou não preem ptivos, o que significa que não podem ser removidos do processo ao qual foram designados (por exemplo, unida­ des de fita e scanners). Dados e program as certam ente são recursos que o sistem a operacional deve controlar e alocar. Código que não pode ser modificado enquanto estiver em uso é denom inado reentrante. Código que pode ser modifi­ cado, mas é reinicializado cada vez que for usado é deno­ minado reutilizável serialmente. Código reentrante pode ser com partilhado por diversos processos sim ultaneam ente, ao passo que código serialmente reutilizável pode ser usado por som ente um processo por vez. Q uando cham am os recursos com partilhados particulares, devem os ter o cuidado de declarar que eles podem ser usados por diversos processos sim ultaneam ente ou por apenas um processo por vez. Esse último tipo — recursos reutilizáveis serialm ente — abrange os que tendem a se envolver em deadlocks. As quatro condições necessárias para existir deadlock são: um recurso pode ser adquirido exclusivam ente por um único processo por vez (condição de exclusão m útua); um processo que obteve um recurso exclusivo pode retê-lo en­ quanto espera para obter outros recursos (condição de espera, também denom inada condição de posse e espera); uma vez que um processo obtenha um recurso, o sistem a não pode retirá-lo do controle do processo até que este tenha terminado de utilizar o recurso (condição de não-preempção); e dois ou m ais processos ficam travados em um a ‘cadeia circular’ na qual cada processo está esperando por um ou mais recursos que o processo seguinte da cadeia está retendo (condição de espera circular). C om o essas condições são necessárias para que um deadlock exista, a existência de um deadlock im plica que cada um a delas deva estar em prática. Tomadas em conjunto, todas as quatro condições são necessárias e suficientes para a ocorrência de um deadlock (se todas ocorrerem , o sistem a estará em deadlock). As quatro principais áreas de interesse na pesquisa do deadlock são prevenção de deadlock, evitação de deadlock, detecção de deadlock e recuperação de deadlock. N a pre­ venção de deadlock, nossa preocupação é condicionar um sistem a a afastar qualquer possibilidade de ocorrer dead­ locks. Havender observou que um deadlock não pode ocorrer se um sistem a negar qualquer um a das quatro condições necessárias. A prim eira condição necessária, que processos exijam a utilização exclusiva dos recursos que requisitam, não é um a que desejam os quebrar, porque querem os per­ m itir especificamente recursos dedicados (reutilizáveis se­ rialmente). N egar a condição ‘de espera’ requer que todos os recursos de que um processo precisa para concluir sua tarefa sejam requisitados de um a só vez, o que pode resultar em substancial subutilização de recursos e causar preocupa­ ções sobre com o cobrar pelos recursos. N egar a condição de ‘não-preem pção’ pode custar caro porque o processo perde trabalho quando os recursos sofrem preem pção. A negação da condição de ‘espera circular’ utiliza um ordenam ento linear de recursos para evitar deadlock. E ssa estratégia pode aum entar a eficiência em relação às outras estratégias, mas não sem dificuldades. N a evitação de deadlock a meta é impor condições menos restritivas, do que na prevenção de deadlock, na tentativa de conseguir m elhor utilização dos recursos. M étodos de evita­ ção perm item que a possibilidade de deadlock exista, mas, sempre que um deadlock esteja na im inência de acontecer, ele é cuidadosam ente desviado. O Algoritm o do Banqueiro de Dijkstra é um exemplo de algoritm o de evitação de dead­ lock. No A lgoritm o do Banqueiro, o sistem a garante que a necessidade máxima de recursos de que um processo precisa não exceda o núm ero de recursos disponíveis. D iz-se que o sistem a está em estado seguro se o sistem a operacional puder garantir que todos os processos atuais possam con­ cluir seu trabalho dentro de um tempo finito. Se não, diz-se que o sistema está em um estado inseguro. O A lgoritm o do Banqueiro de D ijkstra requer que recursos sejam alocados a processos som ente quando as alocações resultarem em estados seguros. O Algoritmo tem várias deficiências (como requerer um núm ero fixo de processos e recursos) que im pe­ dem que ele seja im plem entado em sistem as reais. M étodos de detecção de deadlock são usados em sis­ tem as nos quais podem ocorrer deadlocks. A m eta é deter­ m inar se ocorreu um deadlock, e identificar os processos e recursos envolvidos no deadlock. Algoritm os de detecção de deadlocks podem resultar em significativa sobrecarga de tem po de execução. Para facilitar a detecção de deadlocks, um grafo com setas indica alocações e requisições de re­ cursos. D eadlocks podem ser detectados usando redução de grafos. Se as requisições de recurso de um processo puderem ser atendidas, dizem os que um grafo pode ser re­ duzido daquele processo. Se um grafo puder ser reduzido de todos os seus processos, não haverá deadlock. Se um grafo não puder ser reduzido de todos o seus processos, então os processos irredutíveis constituirão o conjunto de processos em deadlock do grafo. M éto d os de recu p eração de d ead lo ck são usados para lim par deadlocks de um sistem a para que este possa funcionar livre de deadlocks e para que os processos que sofreram deadlock possam concluir sua execução e liberar seus recursos. A recuperação com um ente requer que um ou m ais processos em deadlock sejam expurgados do sis­ tema. O m ecanism o de suspensão/retom ada perm ite que o sistem a retenha tem porariam ente um processo (causando a preem pção tem porária de seus recursos) e, quando for seguro, retom e o processo retido sem perda de trabalho. A verificação/reversão de estado facilita as capacidades de suspensão/retom ada lim itando a perda de trabalho ao ins­ tante em que a últim a verificação foi feita (o últim o estado salvo de um sistema). Q uando um processo term ina em um sistem a (por acidente ou intencionalm ente com o resultado de um algoritmo de recuperação de deadlock), o sistema rea­ liza um a reversão de estado desfazendo todas as operações Capítulo 7 relacionadas ao processo term inado que tenham ocorrido desde a últim a verificação. Para garantir que os dados do banco de dados continuem em um estado consistente quando os processos em deadlock forem term inados, sistem as de banco de dados normalmente realizam alocações de recursos usando transações. Em sistem as de com putadores pessoais e de estações de trabalho, o deadlock em geral tem sido considerado um aborrecim ento limitado. A lguns sistem as im plem entam os m étodos básicos de prevenção de deadlock sugeridos por Havender, enquanto outros ignoram o problem a — esses m étodos parecem satisfatórios. Em bora ignorar deadlocks Deadlock, e,aduiuceitto indefinido 201 possa parecer perigoso, na realidade essa abordagem pode ser bastante eficiente. Se o deadlock for raro, o tem po de processador devotado à verificação de deadlocks reduz sig­ nificativamente o desem penho do sistema. Todavia, dadas as tendências atuais, o deadlock continuará a ser um a área importante da pesquisa à medida que aumentam o número de operações concorrentes e o núm ero de recursos, o que, por sua vez, aum enta a possibilidade de deadlock em sistemas de m ultiprocessadores e sistem as distribuídos. A lém disso, m uitos sistem as de tem po real que estão se tom ando cada vez m ais dom inantes exigem alocação livre de recursos de deadlock. Exercícios 7.1 Defina deadlock. 7.2 Dê um exemplo de deadlock envolvendo somente um único processo e um único recurso. 7.3 Dê um exemplo de deadlock simples de recurso envolvendo três processos e três recursos. Desenhe o grafo de alocação de recursos apropriado. 7.4 O que é adiamento indefinido? Qual a diferença entre adia­ mento indefinido e deadlock? Qual a semelhança entre adiamento indefinido e deadlock? 7.5 Suponha que um sistema permita adiamento indefinido de certas entidades. Na qualidade de projetista de sistemas, como você fornecería meios para evitar o adiamento indefinido? 7.6 Discuta as consequências do adiamento indefinido em cada um dos seguintes tipos de sistema: a. processamento em lote b. tempo compartilhado c. tempo real 7.7 Um sistema requer que os processos que estão chegando de­ vam esperar pelo serviço se o recurso necessário estiver ocupado. O sistema não usa envelhecimento (aging) para elevar as prioridades dos processos à espera para evitar adiamento indefinido. Que outros meios o sistema podería usar para evitar adiamento indefinido? 1 2 3 4 5 6 7 8 7.8 Em um sistema de n processos, um subconjunto de m desses processos está atualmente sofrendo adiamento indefinido. É possí­ vel que o sistema determine quais processos estão sendo adiados indefinidamente? 7.9 (O Jantar dos Filósofos) Uma das contribuições mais deli­ ciosas de Dijkstra é o seu problema do Jantar dos Filósofos.53,54 Ele ilustra muitas das questões delicados inerentes à programação concorrente. O seu objetivo é formular um programa concorrente (com um monitor) que simule o comportamento dos filósofos. Seu programa deve estar livre de deadlock e de adiamento indefinido — caso contrário, um ou mais filósofos poderão morrer de fome. O seu programa deve, é claro, impor exclusão mútua — dois filósofos não podem usar o mesmo garfo ao mesmo tempo. A Figura 7.12 mostra o comportamento de um filósofo típico. Comente cada uma das seguintes implementações de um filósofo típico: a. Veja a Figura 7. 13. b. Veja a Figura 7. 14. c. Veja a Figura 7. 15. d. Veja a Figura 7. 16. typicalPhilosopher() { while ( true ) { th in k l); e a t(); } //te rm in e while } // termine typicalPhilosopher Figura, 7.12 | Comportamento dofilósofo típico para, o Exercício 7.9. 1 2 3 4 typicalPhilosopher)) { while ( true ) { ura, 7. 13 Comportamento dofilósofo típico para, o Exercício 7.9 (a,) (parte, 1 de,2). 202 5 6 7 8 9 10 11 12 13 14 15 16 Sistemas operacionais th in k f); pickUpLeftForkf); pickUpRightForkf); e a tf); putD ow nLeftForkf); putDownRightForkf); } / / termine while } // termine typicalPhilosopher Figura/ 7.13 \ Comportamento dofilósofo típico posa, o Exercício 7.9 (a,) (parte, 2 de, 2). 1 2 3 4 5 6 7 8 9 10 11 12 13 14 typicalPhilosopherf) { while ( tr u e ) { th in k f); pickUpBothForksAtOncef); e a tf); putDownBothForksAtOncef); } / / termine while } // termine typicalPhilosopher Pujura, 7.14 Comportamento dofilósofo para, o Exercido 7.9 (b). 1 2 3 4 5 typicalPhilosopher() { while ( t r u e ) { th in k f); 6 7 8 9 10 11 12 13 14 15 16 17 18 19 while ( notHoldingBothForks) { pickU pLeftForkf); if ( rightForkNotAvailable) { putD ow nLeftForkf); } / / termine if else { pickUpRightForkf); } / / termine while } / / termine else 20 21 e a t(); Pujura, 7.15 Comportamento dofilósofo para, o Exercício 7.9 (o) (parte, 1 de, 2). Capítulo 7 22 23 24 25 26 27 203 putD ow nLeftForkf); putDownRightFork(); } / / termine while } // termine typicalPhilosopher zU ju r a , 7. 1 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 DerullocJc e,adiamento indefinido Comportamento dofilósofo para, o . typicalPhilosopher() { while ( t r u e ) { th in k f); if ( philosopherlD mod 2 == { pickU pLeftForkl); pickl)pRightFork(); e a t(); putD ow nLeftFork(); putDownRightFork(); } // termine if else { pickUpRightFork(); pickUpLeftFork(); e a t(); putDownRightFork(); putD ow nLeftFork(); } // termine else } / / termine while } // termine typicalPhilosopher Figura, 7.16 \ Comportamento dofilósofo para, o BKerdcio 7.9 (d/). 7.10 Defina e discuta cada um dos seguintes conceitos de re­ cursos. a. recurso preemptivo b. recurso não preemptivo c. recurso compartilhado d. recurso dedicado e. código reentrante f. código reutilizável serialmente g. alocação dinâmica de recurso. 7.11 Cite as quatro condições necessárias para existir um deadlock. Proponha um breve argumento intuitivo para a necessidade de cada condição individual. 7.12 Discuta cada uma das condições necessárias de deadlock no contexto do deadlock de tráfego ilustrado na Figura 7.1. 7.13 Quais as quatro áreas de pesquisa de deadlock citadas no texto? Discuta brevemente cada uma. 7.14 O método de Havender para negar a condição ‘de espera’ requer que os processos devam requisitar todos os recursos de que precisam antes de o sistema permitir que eles prossigam. O sistema concede recursos na base do ‘tudo ou nada’. Discuta os prós e os contras desse método. 7.15 Por que o método de Havender para negar a condição de ‘não-preempção’ não é um modo popular para evitar deadlock? 7.16 Discuta os prós e os contras do método de Havender para negar a condição de ‘espera circular’. 7.17 Como o ordenamento linear de Havender para negar a con­ dição de ‘espera circular’ impede que se desenvolvam ciclos nos grafos de alocação de recursos? 7.18 Um processo requisita e libera repetidamente recursos dos tipos R, e Rj, um por vez e nessa ordem. Há exatamente um recurso de cada tipo. Um segundo processo também requisita e libera re­ petidamente esses recursos, um por vez. Sob quais circunstâncias 204 Sistemas operacioftais esses processos poderíam sofrer deadlock? Se isso acontecer, o que podería ser feito para evitar deadlock? 7.19 Explique a atração intuitiva pela evitação de deadlock em detrimento da prevenção de deadlock. 7.20 Discuta se cada um dos estados descritos nas figuras 7.17 e 7.18 é seguro ou inseguro no contexto do Algoritmo do Banqueiro de Dijkstra. Se o estado for seguro, mostre como é possível que todos os processos finalizem. Se for inseguro, mostre como é possível ocorrer deadlock. 7.21 O fato de um estado ser inseguro não implica necessaria­ mente que o sistema sofrerá deadlock. Explique por que isso é verdade. Dê um exemplo de estado inseguro e mostre como todos os processos poderíam concluir sem ocorrer um deadlock. 7.22 O Algoritmo do Banqueiro de Dijkstra tem uma série de deficiências que impedem sua utilização efetiva em sistemas reais. Comente por que cada uma das seguintes restrições pode ser con­ siderada uma deficiência do Algoritmo do Banqueiro. a. O número de recursos a ser alocado permanece fixo. b. A população de processos permanece fixa. c. O sistema operacional garante que as requisições de recursos serão atendidas em tempo finito. d. Usuários garantem que devolverão os recursos que retêm dentro de um tempo finito. e. Usuários devem declarar previamente suas necessidades máximas de recursos. 7.23 (Algoritmo do Banqueiro para vários tipos de recursos) Considere o Algoritmo do Banqueiro de Dijkstra como discutido na Seção 7.8, “Evitação de deadlock com o algoritmo do banqueiro de Dijkstra”. Suponha que um sistema que esteja utilizando esse esquema de evitação de deadlock tenha n processos e m tipos di­ ferentes de recursos; admita que possam existir vários recursos de cada tipo e que o número de recursos de cada tipo seja conhecido. Desenvolva uma versão do Algoritmo do Banqueiro de Dijkstra que habilitará esse sistema a evitar deadlock. [Sugestão: Sob quais circunstâncias seria garantida a conclusão da execução de um processo particular, o qual então podería devolver os recursos ao reservatório?] 7.24 O Algoritmo do Banqueiro de Dijkstra ainda podería fun­ cionar adequadamente se os recursos pudessem ser requisitados Processo ííu ix P2 p3 p< P) c la in c ( 1 4 5 0 3= 1 3 2 3 2 lô O  t( P) i p3 | p2 $ p, f Processo P) 4 6 8 2 p, Figura, 7.17 ( em grupos? Explique sua resposta cuidadosamente. 7.25 Um sistema que usa o Algoritmo do Banqueiro para evitação de deadlock tem cinco processos (1,2, 3,4 e 5) e usa recursos de quatro tipos diferentes (A, B, C e D). Há vários recursos de cada tipo. O estado do sistema demonstrado nas figuras 7.19 e 7.20 é seguro? Explique sua resposta. Se o sistema for seguro, mostre como todos os processos poderíam concluir sua execução com sucesso. Se o sistema for inseguro, mostre como podería ocorrer deadlock. 7.26 Suponha que um sistema com n processos e m recursos idênticos use o Algoritmo do Banqueiro para evitar deadlock. Es­ creva uma função booleana isSafeStatel ( in t [ ] [ ] maximumNeed, in t [ ] [ ] loans. in t[] a v a ila b le ) que determine se o sistema está em um estado seguro. 7.27 Suponha que um sistema use o Algoritmo do Banqueiro com n processos, m tipos de recursos e vários recursos de cada tipo. Escreva uma função booleana isSafeState2( in t [ ] [ ] maximumNeed, in t[][] loans, in t[] a v a ila b le ) que determine se o sistema está em um estado seguro. 7.28 Em um sistema no qual é possível ocorrer um deadlock, sob quais circunstâncias você usaria um algoritmo de detecção de deadlock? 7.29 No algoritmo de detecção de deadlock que emprega a técnica de reduções do grafo mostre que, não importando a ordem das re­ duções do grafo, o resultado será o mesmo estado final. [Sugestão: Após a redução, não importa em que ordem aumenta o reservatório de recursos disponíveis.] 7.30 Por que a recuperação de deadlock é um problema tão difí­ cil? 7.31 Por que é difícil escolher quais processos devem ser ‘expur­ gados’ na recuperação de deadlock? 73 2 Um método de recuperação de deadlock é matar o processo(s) de prioridade mais baixa envolvido(s) no deadlock. Esse(s) processo(s) poderia(m) ser reiniciado(s), e mais uma vez seria permitido que disputasse(m) recursos. Qual problema potencial podería se desenvolver em um sistema que usasse tal algoritmo? Como você resolvería o problema? 7.33 Por que o deadlock provavelmente será um problema mais crítico nos futuros sistemas operacionais do que é hoje? I4í AsX ( P) 8 8 8 Figura, 7.18 Descrição de, recursospara, o Estado B. ÍOOMrÇ P ) 4 3 5 3=2 cíauvt( P,J 4 5 3 Capitulo 7 Necessidade, EMpréstimo corrente Processo 1 2 3 4 5 205 DeadlocJc e,adiamento indefinido Solicitando corrente M á x im a , A B C D A B C D A B C D 1 0 2 3 4 0 3 4 0 2 2 1 5 0 1 0 2 1 6 3 3 3 2 5 6 2 5 7 5 2 4 1 7 0 1 2 2 5 8 4 2 3 0 2 2 2 2 3 5 0 2 0 2 0 0 2 0 4 2 1 Figura, 7.19 \ Estádio de, sistema, descrevendo empréstimo corrente>, necessidadle, máxima, e, solicitação atual. Total de, recursos Recursos dispOEtCueís A B C D A B C D 13 13 9 13 3 4 0 1 Figura, 7.20 E sta d o d& s iste m a , d e sc re v e n d o o n ú m e ro to ta l d o recu rso s c os recu rso s d is p o n ív e is . 7.34 As falhas de recursos fazem com que, em geral, um recurso não utilizável aumente ou reduza a probabilidade de deadlocks e adiamento indefinido? Explique sua resposta. 7.35 A vasta maioria dos sistemas de computador em uso hoje permite que, no mínimo, alguns tipos de situações de deadlock e adiamento indefinido se desenvolvam, e muitos desses sistemas não oferecem meios automáticos de detecção e recuperação para esses problemas. Na verdade, muitos projetistas acreditam que é praticamente impossível certificar que um sistema esteja absoluta­ mente livre de possibilidades de deadlock e adiamento indefinido. Indique como essas observações devem afetar o projeto de sistemas de ‘missão crítica’. 7.36 A Tabela da Figura. 7.21 mostra um sistema em estado inseguro. Explique como todos os processos podem conseguir terminar a execução sem que o sistema entre em deadlock. 7.37 Um sistema tem três processos e quatro recursos idênticos. Cada processo requer no máximo dois recursos a qualquer dado instante. a. Pode ocorrer deadlock nesse sistema? Explique. b. Se houver m processos e cada um puder requisitar até n recursos, quantos recursos devem estar disponíveis no sistema para garantir que nunca ocorra deadlock? c. Se houver m processos e r recursos no sistema, que núme­ ro máximo n de recursos cada processo poderá requisitar, se todos os processos devem ter o mesmo número máximo? Projetos sugeridos 7.38 Elabore um trabalho de pesquisa sobre como sistemas ope­ racionais atuais tratam o deadlock. 7.39 Pesquise como sistemas de tempo real garantem que nunca ocorra deadlock. Como conseguem eliminar deadlock e, mesmo assim, manter o desempenho? Processo p. loMl( P.) 1 1 5 a= 1 Figura, 7.21 \ Exemplo de, um, sistema, em, um, estádio inseguro. 7.40 Determine como servidores Web e outros sistemas críticos de negócios abordam o problema do deadlock. MUVX( P.) 5 3 10 clainc( P.) 4 2 5 70b Sistemas o^ ocíõkaís Simulações sugeridas 7.41 (Projeto de Detecção e Recuperação de Deadlock) Escreva um programa de simulação para determinar se ocorreu um deadlock em um sistema com n recursos idênticos e m processos. Cada pro­ cesso pode gerar um conjunto de recursos que quiser (por exemplo, 3 do recurso A, 1 do recurso B, e 5 do recurso C). Então, requisite os recursos de cada conjunto um por vez em ordem aleatória com pausas aleatórias entre tipos. Cada processo deve reter todos os recursos que obteve até ter adquirido todos eles. Deadlocks deverão começar a se desenvolver. Agora, a intervalos de poucos segundos, um outro thread deverá verificar se há deadlocks, informar quando ocorreu um e começar a matar os threads envolvidos no deadlock. Experimente heurísticas diferentes para escolher processos para matar, e verifique qual tipo de heurística resulta no melhor tempo médio entre deadlocks. 7.42 (Projeto de Simulação de Prevenção de Deadlocks) Escreva um programa de simulação comparando os vários esquemas de prevenção de deadlocks discutidos na Seção 7.7, “Prevenção de deadlock”. Em particular, compare prevenção de deadlock pela negação da condição ‘de espera’ (Seção 7.7.1, “Negação da con­ dição ‘de espera’”) com a prevenção de deadlock pela negação da condição de ‘não-preempção’ (Seção 7.7.2, “Negação da condição de ‘não-preempção’). Seu programa deve gerar uma amostra de população de usuários, de tempos de chegada de usuários, de ne­ cessidade de recursos de usuários (suponha que o sistema tenha n recursos idênticos) em termos de necessidades máximas, e também de quando os recursos realmente são adquiridos e assim por diante. Cada simulação deve acumular dados estatísticos sobre tempos de retomo de serviços (jobs), utilização de recursos, número de serviços que estão progredindo por vez (suponha que serviços pos­ sam progredir quando tiverem uma parte dos n recursos de que necessitam correntemente) e semelhantes. Observe os resultados de suas simulações e tire conclusões sobre a efetividade relativa desses esquemas de prevenção de deadlock. 7.43 (Projeto de Simulação de Evitação de Deadlock) Escreva um programa de simulação para examinar o desempenho de um sistema com n recursos idênticos e m processos que funcione sob o algoritmo de alocação de recursos do banqueiro. Modele seu programa segundo o que desenvolveu no Exercício 7.42. Exe­ cute sua simulação e compare os resultados com os observados nas suas simulações de prevenção de deadlocks. Comente suas conclusões sobre a efetividade relativa dos esquemas de evitação de deadlocks versus esquemas de prevenção de deadlocks estu­ dados. 7.44 (Comparação entre Prevenção e Evitação de Deadlocks) Crie um programa que simule serviços que chegam com várias necessidades de recursos (liste cada recurso que será necessitado e em que instante será necessitado). Esse programa pode ser do tipo driver baseado em números aleatórios. Use sua simulação para determinar como estratégias de prevenção de deadlock e de evitação de deadlock resultam em utilização mais alta de recursos. Notas 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. S. S. Isloor e T. A. Marsland, “The deadlock problem: an overview”, Computer, v. 13, n° 9, set. 1980, p. 58-78. D. Zobel, “The deadlock problem : a classifying bibliography”, Operating Systems Review, v. 17, na 4, out. 1983, p. 6-16. R. C. Holt, “Some deadlock properties of Computer systems”, ACM Computing Surveys, v. 4, na 3, set. 1972, p. 179-196. E. G. Coffman Jr., M. J. Elphick e A. Shoshani, “System deadlocks”, Computing Surveys, v. 3, na 2, jun. 1971, p. 69. E. W. Dijkstra, “Cooperating sequential processes”, Technological University. Eindhoven, Holanda, 1965. Reimpresso em: F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968. E. W. Dijkstra. “Hierarchical ordering of sequential processes”, Acta Informática, v. 1,1971, p. 115-138. E. G. Coffman Jr., M. J. Elphick e A. Shoshani, “System deadlocks”, Computing Surveys, v. 3, na 2, jun. 1971, p. 67-78. A. N. Habermann, “Prevention of system deadlocks”, Communications o f the ACM, v. 12, na 7, jul. 1969, p. 373377, 385. R. C. Holt, “Comments on the prevention of system deadlock”, Communications o f the ACM, v. 14, na 1, jan. 1971, p. 36-38. R. C. Holt, On deadlock prevention in Computer systems. Dissertação de doutorado —Comell University, Nova York, 1971. D. L. Pamas e A. N. Haberman, “Comment on deadlock prevention method”, Communications o f the ACM, v. 15, na 9, set. 1972, p. 840-841. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. G. Newton, “Deadlock prevention, detection, and resolution: an annotated bibliography”, ACM Operating Systems Review, v. 13, na 2, abr. 1979, p. 33-44. D. Gelemter, “A DAG based algorithm for prevention of storeand-forward deadlock in packet networks”, IEEE Transactions on Computers, v. C-30, na 10, out. 1981, p. 709-715. J. W. Havender, “Avoiding deadlock in multitasking systems”, IBM Systems Journal, v. 7, na 2, 1968, p. 74-84. R Brinch Hansen, Operating system principies. Englewood Cliffs, NJ: Prentice Hall, 1973. A. L. Scherr, “Functional structure of IBM virtual storage operating systems, part II: OS/VS2-2 concepts and philosophies”, IBM Systems Journal, v. 12, na 4, 1973, p. 382-400. M. A. Auslander, D. C. Larkin e A. L. Scherr, “The evolution of the MVS operating system”, IBM Journal o f Research and Development, v. 25, na 5, 1981, p. 471-482. L. J. Kenah, R. E. Goldenberg e S. F. Bate, VAXYVMS internais and data structures, version 4.4. Bedford, MA: Digital Press, 1988. P. Brinch Hansen, Operating system principies. Englewood Cliffs, NJ: Prentice Hall, 1973. E. W. Dijkstra, “Cooperating sequential processes”, Technological University. Eindhoven, Holanda, 1965. Reimpresso em: F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968. E. W. Dijkstra, “Cooperating sequential processes”, Technological University. Eindhover, Holanda, 1965. Reimpresso em F. Genuys (org.), Programming languages. Nova York: Academic Press, 1968. Ca^vtuio7 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. A. N. Habermann, “Prevention of system deadlocks”, Communications o f the ACM, v. 12, n2 7, jul. 1969, p. 373377, 385. H. Madduri e R. Finkel, “Extension of the Banker’s algorithm for resource allocation in a distributed operating system”, Information Processing Letters, v. 19, n2 1, jul. 1984, p. 18. J. W. Havender, “Avoiding deadlock in multitasking Systems”, IBM Systems Journal, v. 7, nc 2, 1968, p. 74-84. R. O. Fontao, “A concurrent algorithm for avoiding deadlocks”, Proceedings Third ACM Symposium on Operating Systems Principies, out. 1971, p. 72-79. D. J. Frailey, ‘A practical approach to managing resources and avoiding deadlock”, Communications o f the ACM, v. 16, n2 5, maio 1973, p. 323-329. R. Devillers, ‘‘Game interpretation of the deadlock avoidance problem”, Communications o f the ACM, v. 20, n2 10, out. 1977, p. 741-745. D. B. Lomet, “Subsystems of processes with deadlock avoidance”, IEEE Transactions on Software Engineering, v. SE-6, n2 3, maio 1980, p. 297-304. R M. Merlin e P. J. Schweitzer, ‘‘Deadlock avoidance in storeand-forward networks — I: store and forward deadlock”, IEEE Transactions on Communications, v. COM-28, n2 3, mar. 1980, p. 345-354. P. M. Merlin e P. J. Schweitzer, “Deadlock avoidance in store-and-forward networks — II: other deadlock types”, IEEE Transactions on Communications, v. COM-28, n2 3, mar. 1980, p. 355-360. T. Minoura, “Deadlock avoidance revisited”, Journal o f the ACM, v. 29, n2 4, out. 1982, p. 1023-1048. J. E. Murphy, “Resource allocation with interlock detection in a multitask system”, AFIPS FJCC Proceedings, v. 33, n2 2, 1968, p. 1169-1176. G. Newton, “Deadlock prevention, detection, and resolution: an annotated bibliography”, ACM Operating Systems Review, v. 13, n2 2, abr. 1979, p. 33-44. V. Gligor e S. Shattuch, “On deadlock detection in distributed Systems”, IEEE Transactions on Software Engineering, v. SE-6, n2 5, set. 1980, p. 435-440. G. S. Ho e C. V. Ramamoorthy, “Protocols for deadlock detection in distributed database system s” , IEEE Transactions on Software Engineering, v. SE-8, n2 6, nov. 1982, p. 554-557. ’ R. Obermarck, “Distributed deadlock detection algorithm”, ACM Transactions on Database Systems, v. 7, n22, jun. 1982, p. 187-208. K. M. Chandy e J. Misra, “Distributed deadlock detection”, ACM Transactions on Computer Systems, v. 1, n2 2, maio 1983, p. 144-156. J. R. Jagannathan e R. Vasudevan, “Comments on ‘protocols for deadlock detection in distributed database systems*”, IEEE Transactions on Software Engineering, v. SE-9, n2 3, maio 1983, p. 371. L. J. Kenah, R. E. Goldenberg e S. F. Bate, VAX/VMS internais and data structures, version 4.4. Bedford, MA: Digital Press, 1988. 40. 41. 42. 43. 44. Vead/ódc &aMAUcento indefinido QQJ Pun H. Shiu, YuDong Tan e Vincent J. Mooney, “A novel parallel deadlock detection algorithm and architecture”, Proceedings o f the Ninth International Symposium on Hardware/Software Codesign, abr. 2001. R. C. Holt, “Some deadlock properties of Computer systems”, ACM Computing Surveys, v. 4, n2 3, set. 1972, p. 179-196. R. C. Holt, “Some deadlock properties of Computer systems”, ACM Computing Surveys, v. 4, n2 3, set. 1972, p. 179-196. L. J. Kenah, R. E. Goldenberg e S. F. Bate, VAX/VMS internais and data structures, version 4.4. Bedford, MA: Digital Press, 1988. K. Thomas, “Programming locking applications”, IBM Corporation, 2 0 0 1 , www-124.ibm.com/developerworks/oss/dlm/ currentbook/dlmbookjndex.html. 45. 46. Compaq Com puter Corporation, Intel Corporation, M icrosoft Corporation, Phoenix Technologies Ltd., Toshiba Corporation, “Advanced configuration and power management”, rev. 2.0b, 11 out. 2002, p. 238. “Driver development tools: Windows DDK, deadlock detection”, MSDN Library, 6 jun. 2003, msdn.microsoft.com/ library/en-us/ddtools/hh/ddtools/dv_8pk j.asp. 47. “ Kernel-m ode driver architecture: Windows DDK, preventing errors and deadlocks while using spin locks”, MSDN Library, 6 jun. 2 0 0 3 , msdn.microsoft.com/library/en-us/ kmarch/hhAmardi/synchro_5ktj.asp. 48. 49. 50. 51. 52. 53. 54. N. Krivokapic, A. Kemper e E. Gudes, “Deadlock detection in distributed database systems: a new algorithm and comparative performance analysis”, The VLDB Journal — The International Journal on Very Large Data Bases, v. 8, n2 2, 1999, p. 79-100. N. Krivokapic, A. Kemper e E. Gudes, “Deadlock detection in distributed database systems: a new algorithm and comparative performance analysis”, The VLDB Journal — The International Journal on Very Large Data Bases, v. 8, n2 2, 1999, p. 79-100. N. Krivokapic, A. Kemper e E. Gudes, “Deadlock detection in distributed database systems: a new algorithm and comparative performance analysis”, The VLDB Journal — The International Journal on Very Large Data Bases, v. 8, n2 2,1999, p. 79-100. P. Magarshack e P. Paulin, “System-on-chip beyond the nanometer wall”, Proceedings o f the 40th Conference on Design Automation. Anaheim, CA: ACM Press, 2003, p. 419-424. L. Benini, A. Macei e M. Poncino, “Energy-aware design of embedded memories: a survey of technologies, architectures, and techniques”, ACM Transactions on Embedded Computer Systems (TECS), v. 2, n2 1, 2003, p. 5-32. E. W. Dijkstra, “Solution of a problem in concurrent programming control”, Communications o f the ACM, v. 8, n25, set. 1965, p. 569. E. W. Dijkstra, “Hierarchical ordering of sequential processes”, Acta Informática, v. 1, 1971, p. 115-138. Mesmo os cias, osplanetas e, ette, centro observam grau, prioridade, e, lugar... W illiam Shakespeare N ada que, está/ em progressão pod&janer em seuplano original. Se assimfor, podemos tam bém pensar em em balar u m hom em adulto no berço d e u m infante. Edm und Burke Para todo problem a h á u m a solução que é simples, elegante e errada. H. L. M encken Não h á nada m ais indispensável nos negócios do que o despacho. Joseph A ddison Objetivos Este capítulo apresenta: • Os objetivos do escalonamento de processador. • Escalonamento preemptivo v e rs u s escalonamento não preemptivo. • O papel das prioridades no escalonamento. • Critérios de escalonamento. • Algoritmos de escalonamento comuns. • Os conceitos de escalonamento por prazo e de tempo real. • Escalonamento de threads Java. Capítulo 8 Esculonuutmto de processador 209 8.1 Introdução Já discutim os com o a m ultiprogram ação habilita um sistem a operacional a usar seus recursos m ais eficientemente. Quando um sistem a pode escolher os processos que executa, deve ter uma estratégia — denom inada política de escalona­ mento de processador (ou disciplina) — para decidir quais processos executar em determ inado instante. U m a política de escalonam ento deve tentar satisfazer alguns critérios de desem penho, com o m axim izar o núm ero de processos que term i­ nam por unidade de tempo (rendim ento), m inim izar o tempo que cada processo espera antes de executar (latência), evitar adiam ento indefinido de processos, assegurar que cada processo conclua antes de seu prazo estabelecido, ou m axim izar a utilização do processador. A lguns desses objetivos, com o m axim izar a utilização e o rendim ento do processador são com ­ plem entares; outros conflitam entre si — um sistema que garanta que os processos term inarão antes de seus prazos pode não atingir o m aior rendim ento possível. N este capítulo discutirem os os problem as para determ inar quando processadores devem ser designados e a quais processos. Em bora nos concentrem os em processos, m uitos dos tópicos que descreverem os aplicam -se tam bém a jobs e thrcads. R evu ã o ' 1. Q uando um sistem a que garante que processos term inarão antes de seus prazos de execução não conseguem o m aior rendim ento? 2. Q uais os critérios de desem penho m ais im portantes em um sistem a operacional? Por que essa é um a pergunta difícil de responder? R e ip o iíã i: í ) Isso ocorre, por exemplo, quando vários processos curtos são atrasados enquanto o sistem a despacha um processo longo que precisa cum prir seu prazo de execução. 2) N enhum critério particular de desem penho é m ais importante do que os outros em todos os sistem as operacionais. Depende dos objetivos do sistema. Por exemplo, em sistem as de tempo real, prestar serviços imediatos e previsíveis a processos e threads é m ais im portante do que um a alta taxa de utilização do processador. Em supercom putadores que executam cálculos longos, a utilização do processador é norm alm ente mais im portante do que m inim izar a latência. 8.2 Níveis de escalonautento N esta seção considerarem os três níveis de escalonam ento (Figura 8.1). Escalonamento de alto nível, tam bém denom i­ nado escalonamento de jobs ou escalonamento de longo prazo — determ ina quais jobs o sistem a perm ite que disputem ativamente os recursos do sistema. As vezes esse nível é denom inado escalonamento de admissão, porque determ ina quais jobs são adm itidos no sistema. U m a vez adm itidos, os jobs são inicializados e tom am -se processos ou grupos de processos. A política de escalonam ento de alto nível determ ina o grau de multiprogramação — o núm ero total de processos em um sistem a em determ inado instante.1A entrada de muitos processos em um sistem a pode saturar os recursos do sistem a levando a mau desem penho. N esse caso, a política de escalonam ento de alto nível pode decidir proibir tem porariam ente que novos jobs entrem até que outros sejam concluídos. Depois de a política de escalonam ento de alto nível ter adm itido um jo b (que pode conter um ou m ais processos) no sistema, a política de escalonamento de nível intermediário determ ina quais processos terão perm issão de com petir por processadores. Essa política atende às flutuações de curto prazo da carga do sistema. Suspende e retom a processos tem po­ rariam ente para conseguir um a operação tranqüila do sistem a e ajudar a cum prir certas metas de desem penho no âm bito geral do sistema. O escalonador de nível interm ediário funciona com o um buffer entre a adm issão de jobs no sistem a e a designação de processadores a processos que representam esses jobs. A política de escalonamento de baixo nível de um sistem a determ ina quais processos ativos o sistem a designará a um processador quando o próxim o ficar disponível. Em m uitos dos sistem as atuais, os únicos escalonadores são os de níveis baixo e interm ediário. (Nesse caso a inicialização do jo b é realizada pelo escalonador de nível interm ediário.) Escalonadores de alto nível norm alm ente são lim itados a sistem as de grande porte (m ainfram es) que executam proces­ sam ento em lote. M uitas vezes as políticas de escalonam ento de baixo nível atribuem um a prioridade a cada processo, que reflete a im portância desse processo — quanto mais im portante for, m aior será a probabilidade de que a política de escalonam ento o selecione para ser executado em seguida. Discutirem os prioridades na Seção 8.4, “Prioridades” , e em todo este capí­ tulo. O escalonador de baixo nível (tam bém denom inado despachante) tam bém designa (despacha) um processador ao processo selecionado. O despachante funciona muitas vezes por segundo e, portanto, deve residir na m em ória principal o tem po todo. Neste capítulo discutirem os muitas políticas de escalonam ento de baixo nível, apresentarem os cada um a no contexto de certos objetivos e critérios de escalonam ento (que abordarem os na Seção 8.5, “Objetivos de escalonam ento” e na Seção 210 S U tw u is o jte ra à o fu iti E ntrada de jo b Inicialização de jo b Escalonamento de alto nivel Processos suspensos à espera de ativação A tiva r B loqueio o u e s g o ta m e n to F ü ju rO s 8 .1 J k | f i S uspender Escalonamento de nível intermediário D espacho Escalonamento de baixo nível N ív e is d e , etodoruuM znbo. 8.6, “Critérios de escalonam ento”) e descreverem os com o se relacionam umas com as outras. Coffman e K leinrock discu­ tem políticas de escalonam ento populares e indicam com o usuários conhecedores de qual política o sistem a usa realm ente podem conseguir m elhor desem penho tom ando medidas apropriadas.2 Ruschitzka e Fabry apresentam um a classificação de algoritmos de escalonam ento e form alizam a noção de prioridade.3 Revuão' 1. Com o um escalonador interm ediário deveria responder a flutuações na carga do sistema? 2. Qual nível de escalonador deve ficar residente na m em ória principal? Por quê? R e ip o itã i: i ) O escalonador interm ediário pode proibir que processos prossigam até o escalonador de baixo nível quando o sistem a ficar sobrecarregado e pode perm itir que esses processos prossigam quando a carga do sistem a voltar ao normal. 2) O escalonador de baixo nível deve m anter residência na m em ória principal, porque ele executa freqüentem ente exigindo que a m em ória responda rapidam ente para reduzir a sobrecarga de escalonam ento. Capítulo 8 Escalonamento de,processador 211 8.3 Escalonamento preemptivo versus escalonamento não preemptivo Disciplinas de escalonam ento podem ser preem ptivas ou não preemptivas. U m a disciplina é não preemptiva se, um a vez que o sistem a tenha designado um processador a um processo, não puder retirar aquele processador daquele processo. U m a disciplina é preemptiva se o sistema puder retirar o processador do processo que estiver executando. Sob um a dis­ ciplina de escalonam ento não preemptiva, cada processo, um a vez recebido um processador, executa até concluir ou até devolver voluntariam ente seu processador. Sob um a disciplina preem ptiva de escalonam ento, o processador pode executar um a parte do código de um processo e então fazer um chaveam ento de contexto. O escalonam ento preem ptivo é útil em sistem as nos quais processos de alta prioridade exigem resposta rápida. Em sistem as de tempo real (discutidos na Seção 8.9, “Escalonam ento de tempo real”), por exemplo, as conseqüências de não responder a um a interrupção poderíam ser catastróficas.4,5>6*7Em sistemas interativos de tempo com partilhado, o escalo­ nam ento preem ptivo ajuda a garantir tem pos de resposta aceitáveis ao usuário. A preem pção não deixa de ter um custo — chaveamentos de contexto incorrem em sobrecarga (veja o quadro “Reflexões sobre sistemas operacionais, Sobrecarga”). Para tom ar a preem pção efetiva, o sistem a deve m anter m uitos processos na m em ória principal, de modo que o processo seguinte esteja pronto quando um processador se tom ar disponível. Com o verem os no Capítulo 10, “Organização da m e­ m ória virtual”, norm alm ente apenas um a parte de cada processo está na m em ória principal a qualquer instante; as partes menos ativas em geral estão em discos. Em sistem as não preem ptivos, processos curtos podem sofrer longas esperas para serem atendidos enquanto são concluídos processos m ais longos, mas os tem pos de retom o são m ais previsíveis, porque os processos de alta prioridade que chegam não podem desalojar os processos que estão à espera. Com o um sistem a não preem ptivo não pode retirar um processo de um processador até que o processo conclua a execução, program as errantes que nunca são concluídos (porque entraram em laço infinito) podem nunca entregar o controle do sistema. E mais, em um sistem a não preemptivo, a execução de processos não im portantes pode fazer que processos im portantes fiquem esperando. Para evitar que usuários m onopolizem o sistem a (acidental ou proposital mente), um sistem a preem ptivo pode retirar o processador de um processo. Com o discutido no Capítulo 3, “Conceito de processos” , norm alm ente tal operação é im ple­ m entada instalando-se um relógio de interrupção ou um tem porizador de intervalo que gere uma interrupção periodica­ mente, perm itindo que o sistem a execute. Tão logo um processador seja designado a um processo, esse executa até liberar voluntariam ente seu processador ou até ocorrer um a interrupção do relógio ou algum a outra interrupção. Então o sistem a pode decidir se o processo em execução deve continuar ou algum outro processo ‘seguinte’ deve executar. O relógio de interrupção ajuda a garantir tem pos de resposta razoáveis para usuários interativos, evita que o sistem a fique suspenso em um laço infinito do usuário e perm ite que processos respondam a eventos que dependam de tempo. Processos que precisam executar periodicam ente dependem do relógio de interrupção. Rôflcxccç çobrc $\Àoo&r<%doi\A.te Sobrecarga, Em última instância, sistemas de computador existem para exe­ cutar aplicações para seus usuá­ rios. Embora certamente realizem tarefas im portantes, consom em valiosos recursos do sistem a no processo; esse consum o é de­ nom inado sobrecarga porque os recursos não estão sendo usados diretam ente pelas aplicações de usuários para realizar trabalho útil. Projetistas de sistemas operacio­ nais buscam minimizar a sobrecarga e, ao mesmo tempo, maximizar a parte dos recursos do sistema que pode ser alocada a aplicações de usuário. Como veremos, a sobre­ carga pode melhorar o desempe­ nho aprim orando a utilização de recursos; também pode reduzir o desempenho para fornecer um nível mais alto de proteção e segurança. À medida que a capacidade dos computadores continuar a crescer e os custos diminuírem, o consumo de recursos perdidos pela sobrecar­ ga poderá se tornar uma questão secundária. Todavia, p ro je tista s devem estar conscientes da carga de trabalho de um sistema quando considerarem a sobrecarga. Por exemplo, uma grande sobrecarga para uma carga pequena poderá ficar relativam ente pequena sob uma carga pesada; uma pequena sobrecarga para uma carga peque­ na poderá tornar-se relativamente grande sob uma carga pesada. m S U tw u is o jte ra à o fu iti Ao projetar um m ecanism o de escalonam ento preem ptivo, deve-se considerar cuidadosam ente a arbitrariedade de sistem as de prioridade. Não tem sentido construir um m ecanism o sofisticado para im plem entar fielmente um esquem a de preem pção por prioridade quando as próprias prioridades não são designadas significativamente. R evU ão' 1. Q uando o escalonam ento não preem ptivo é m ais apropriado do que o escalonam ento preemptivo? 2. Um program a que entra em laço infinito pode m onopolizar um sistem a preem ptivo? R e ip o ifa i: i ) Escalonam ento não preem ptivo proporciona tempos de retorno previsíveis, o que é im portante para sistem as de processam ento em lote que devem inform ar aos usuários tempos exatos de conclusão de um job. 2) Depende da prioridade do processo e da política de escalonam ento. Em geral, um sistem a preem ptivo que contém um processo que está executando um laço infinito experim entará redução de rendim ento, mas ainda assim poderá executar outros processos periodicamente. Porém, um processo de alta prioridade que entrar em laço infinito poderá executar indefinidamente se todos os outros processos do sistem a tiverem um a prioridade m ais baixa. Em geral, sistemas preem ptivos são menos afetados por tais program as do que sistemas não preemptivos. N orm alm ente sistemas operacionais lidam com essas situações lim itando o tem po m áxim o que um processo pode usar um processador. 8.4 Prioridades Escalonadores muitas vezes usam prioridades para determ inar com o escalonar e despachar processos. Prioridades podem ser designadas estaticam ente ou m udar dinam icam ente. Prioridades quantificam a im portância relativa dos processos. Prioridades estáticas perm anecem fixas, portanto, m ecanism os baseados em prioridade estática são relativam ente fáceis de im plem entar e incorrem em sobrecarga relativam ente baixa. Contudo, esses m ecanism os não são responsivos a m udanças no am biente, m esm o os que poderíam aum entar o rendim ento e reduzir a latência. M ecanism os de prioridade dinâmica são responsivos a mudanças. Por exemplo, o sistem a pode querer elevar a prio­ ridade de um processo que esteja retendo um recurso im portante que um outro processo de prioridade m ais alta precisa. A pós o prim eiro processo devolver o recurso, o sistem a baixa a prioridade, para que o processo de prioridade m ais alta possa executar. Esquem as de prioridade dinâm ica são m ais com plexos de im plem entar e têm sobrecargas m aiores do que esquem as estáticos. Com sorte a sobrecarga é justificada pelo aum ento de responsividade do sistema. Em sistemas multiusuários, um sistema operacional deve fornecer serviços razoáveis a um a grande comunidade de usuá­ rios, mas também deve atender a situações nas quais um membro da com unidade de usuários precisa de tratam ento especial. Um usuário que tenha um jo b im portante 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 m ais alto de serviço. R ev íiã o ' 1. Por que vale a pena incorrer no custo m ais alto e na m aior sobrecarga de um m ecanism o de prioridade dinâm ica? 2. Por que um escalonador dinâm ico decide favorecer um processo de prioridade baixa que requisita um recurso subtilizado? R eipaítãi: i) U m m ecanism o de prioridade dinâm ica cuidadosam ente projetado podería resultar em um sistem a m ais responsivo do que um m ecanism o de prioridade estática. 2) O recurso subutilizado provavelmente está disponível, perm itindo que um processo de baixa prioridade conclua e saia do sistem a m ais cedo do que um processo de prioridade mais alta que está à espera por um recurso saturado. 8.5. Objetivos d& escalonamento Um projetista de sistemas deve considerar um a variedade de fatores ao desenvolver um a disciplina de escalonam ento, com o o tipo do sistem a e as necessidades do usuário. Por exemplo, a disciplina de escalonam ento para um sistema de tempo real deve ser diferente da disciplina para o sistem a interativo de um com putador 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: • M axim ize o rendimento. U m a disciplina de escalonam ento deve tentar atender ao m aior núm ero de processos por unidade de tempo. • M axim ize o número de processos interativos que estão recebendo tempos de resposta ‘aceitáveis \ • M axim ize a utilização de recursos. Os m ecanism os de escalonam ento devem m anter os recursos do sistem a ocu­ pados. Capítulo 8 EscsdonoMieato d&processador ^J3 • Evite adiam ento indefinido. Um processo não deve experim entar um tempo de espera sem lim ite antes de receber um serviço ou enquanto o estiver recebendo. • Imponha prioridades. Se o sistema designar prioridades a processos, o m ecanism o de escalonam ento deve favorecer os processos de prioridade mais alta. • M inim ize sobrecarga. Curiosam ente, em geral esse objetivo não é considerado dos m ais im portantes. Sobrecarga freqüentem ente resulta em desperdício de recursos, mas um a certa porção dos recursos do sistem a se investida efetivamente com o sobrecarga pode m elhorar muito o desem penho geral do sistema. • Assegure a previsibilidade. M inim izando a variância estatística dos tempos de resposta de processos, um sistem a pode garantir que os processos recebam níveis de serviços previsíveis (veja o quadro “Reflexões sobre sistemas operacionais, Previsibilidade”). Um sistema pode cum prir esses objetivos de diversas maneiras. Em alguns casos o escalonador pode im pedir o adiamento indefinido de processos por meio do envelhecimento (aging) — elevando gradativam ente a prioridade de um processo enquanto ele espera ser atendido. Eventualm ente sua prioridade se tom a alta o suficiente para que o escalonador selecione aquele processo para executar. O escalonador pode aum entar o rendim ento favorecendo processos cujos requisitos podem ser satisfeitos rapidam ente ou cuja conclusão libera outros processos para execução. Uma estratégia com o essa favorece processos que retêm recursos fundamentais. Por exemplo, um processo de baixa prioridade pode reter um recurso requerido por um processo de prio­ ridade m ais alta. Se o recurso for não preemptivo, o escalonador deverá conceder ao processo de prioridade baixa mais tem po de execução do que ordinariam ente recebería, para que ele libere o recurso fundam ental m ais cedo. Essa técnica é denom inada inversão de prioridade, pois as prioridades relativas dos dois processos são invertidas para que o de priori­ dade alta obtenha os recursos que requer para continuar a execução. Sim ilarm ente, o escalonador pode preferir favorecer um processo que requisite recursos subutilizados, porque o sistem a provavelm ente satisfará os requisitos desse processo em um período de tempo m ais curto. M uitos desses objetivos conflitam uns com os outros, fazendo do escalonam ento um problem a com plexo. Por exemplo, a m elhor m aneira de m inim izar tem pos de resposta é ter recursos disponíveis suficientes sem pre 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 é m enos importante. Em outros tipos de sistemas, a questão da econom ia com um ente faz com que a utilização efetiva de recursos seja um imperativo. A despeito das diferenças entre os objetivos dos sistem as, m uitas disciplinas de escalonam ento exibem propriedades similares: • Justiça. U m a disciplina de escalonam ento é justa se todos os processos sem elhantes forem tratados da mesma m aneira, e nenhum processo sofrer adiam ento indefinido devido a questões de escalonam ento (veja o quadro “R e­ flexões sobre sistem as operacionais, Justiça”). • Previsibilidade. A execução de um determ inado processo sob cargas de sistem a sim ilares deve durar aproxim ada­ m ente o mesmo período de tempo. Rô\\& XÕ ôG ÇldôlMtXÇ 0^& TA C \0\A A Í$ PrevüibilidiicU Previsibilidade é tão importante para sua vida cotidiana quanto para com putadores. O que você faria se parasse no sinal vermelho e o semáforo continuasse no vermelho durante um longo tem po, m uito mais longo do que em qualquer outro sinal vermelho que já tivesse enfrentado? Provavelmente você ficaria aborrecido e impaciente e, após esperar por um tem po que achasse razoável, poderia ficar ten­ tado a passar o sinal fechado, uma ação potencialmente perigosa. De um modo semelhante, você tem uma certa percepção do tempo que seu com putador deveria de­ morar para executar certas tarefas comuns. Garantir a previsibilidade é um desafio para os sistemas ope­ racionais, especialmente porque a carga de um sistema pode variar consid e ra velm e n te em vista da natureza das tarefas que estão em realização. A previsibilidade é impor­ tante para usuários interativos que dem andam tem pos de resposta imediatos, consistentes. Previsibi­ lidade também é importante para jobs de tem po real quando vidas hum anas podem estar em jogo (discutirem os escalonam ento de tem po real na Seção 8.9, "Escalo­ namento de tem po real"). Aborda­ remos questões de previsibilidade por todo o livro. 214 • S U tw u is o jte ra à o tu u s E scalab ilid ad e. O desem penho do sistem a deve se degradar graciosam ente (não deve entrar em colapso im ediata m ente) sob cargas pesadas. RevU cur 1. Com o as metas de redução da variância dos tem pos de resposta e da im posição de prioridades conflitam? 2. A sobrecarga de escalonam ento é sempre ‘um desperdício’? R eip o ítã i 1 1) Em sistem as preemptivos, processos de alta prioridade podem causar a preem pção de sistem as de priori­ dade mais baixa a qualquer instante, aum entando, por conseguinte, a variância dos tempos de resposta. 2) Não, a sobrecarga incorrida em operações efetivas de escalonam ento pode aum entar a utilização de recursos. 8.6 Critérios esaUoHxmte*tto Para cum prir os objetivos de escalonamento de um sistema, o escalonador deve considerar o com portamento do processo. Um processo orientado a processador tende a usar todo o tempo do processador que o sistem a aloca a ele. U m processo orientado a E/S tende a usar o processador apenas brevem ente antes de gerar uma requisição de E/S e em seguida devol­ vê-lo. Processos orientados a processador gastam a m aior parte do seu tem po usando o processador; processos orientados a E/S passam a m aior parte do seu tempo esperando que recursos externos (impressoras, unidades de disco, conexões de rede etc.) atendam a suas requisições, e som ente em tem po nominal usando processadores. U m a disciplina de escalonam ento tam bém poderia considerar se um processo é em lote ou interativo. U m processo em lote contém trabalho que o sistem a executa sem interagir com o usuário. Um processo interativo requer freqüentes entradas do usuário. O sistem a deve fornecer bons tem pos de resposta a um processo interativo, enquanto, em geral, um processo em lote pode sofrer atrasos razoáveis. Similarmente, um a disciplina de escalonam ento deve ser sensível à ur­ gência de um processo. Um processo em lote que deve ser executado durante a noite não exige respostas imediatas. Um sistem a de controle de processo de tem po real que monitora um a refinaria de petróleo deve ser responsivo para evitar uma possível explosão. Q uando a segunda edição deste livro, em inglês, foi publicada, usuários interagiam com processos em itindo requisi­ ções triviais por meio do teclado. Nesse am biente, 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. À m edida que os com putadores ficavam mais potentes, projetistas de sistem as e program adores de aplicações com eçaram a incluir características com o gráficos e GUIs para aperfeiçoar a interação am igá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 com o abrir, redimensionar, arrastar e fechar janelas. Usuários esperam que sistem as respondam rapida­ mente, para que essas ações produzam m ovim entação suave. D iferentem ente do que acontece em interfaces de texto, essa tarefa pode ser intensiva em com putação por exigir que o sistem a 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. Ç ldôlM tXÇ 0^CCAC\0\AA\6 J lM tíÇ O s Quantas vezes você expressou seu aborrecimento dizendo: "Isso não é ju s to !". Provavelm ente já ouviu a expressão "A vida não é justa". Todos sabemos, e a maio­ ria das pessoas concordaria, que a justiça é uma "coisa boa", porém não é universalm ente alcançada. D iscutim os q uestões de justiça em m uitos capítulos deste livro. Veremos estratégias de escalona­ m ento por prioridade que resultam em bom desempenho para grande parte dos usuários, processos, threads, requisições de E/S e coi­ sas semelhantes, mas a expensas de o utro s usuários, processos, threads, requisições de E/S que acabam sendo n e g lig e n cia d o s. "Isso não é justo", você diz, mas é difícil ignorar como essas estra­ tégias cum prem os objetivos do sistema, por exemplo, melhorando o seu desempenho geral. Sistemas operacionais devem te r a justiça em mente, mas sempre dentro do contexto de outras considerações. Questões de justiça são particular­ m ente importantes no projeto de estratégias de escalonamento de recursos, como veremos quando exam inarm os o escalo n am en to de processador neste capítulo e o escalonamento de disco no Capítulo 12, "Otimização do desempenho do disco". Capítulo 8 BscaíonoMieato deprocessador ^1 5 No caso de um processo em lote, essa redução tem porária de serviço pode ser aceitável, em bora talvez não o seja para processos que executem em tempo real (como aplicações multimídia). E m um sistem a que em prega prioridades, o escalonador deve favorecer processos de prioridades m ais altas. Escalonadores podem basear suas decisões na freqüência com que um processo de prioridade m ais alta causou a preem pção de um outro de prioridade mais baixa. Sob certas disciplinas, processos que sofrem preem pções freqüentes recebem um tratam ento m enos favorecido. Isso porque o curto tem po de execução do processo antes da preem pção não justifica a sobrecarga incorrida em um chaveam ento de contexto toda vez que um processo é despachado. Pode-se argum entar o contrário, ou seja, que tal processo deve receber tratam ento m ais favorável para com pensá-lo porque foi ‘m altratado’ anteriorm ente. Políticas de escalonam ento preem ptivo com um ente mantêm inform ações sobre quanto tempo real de execução cada processo recebeu. A lguns projetistas acham que um processo que recebeu pouco tempo de execução deve ser favorecido. Outros acham que um processo que recebeu m uito tempo de execução podería estar próxim o do térm ino e deveria ser favorecido para chegar logo ao fim, liberar seus recursos para o uso de outros processos e sair do sistem a o mais cedo pos­ sível. D e m aneira similar, um escalonador pode m anter um a estimativa de quanto tem po ainda falta antes de um processo terminar. É fácil provar que os tempos médios de espera podem ser m inim izados executando-se prim eiram ente os processos que exigem o m ínimo de tempo de execução antes de concluir. Infelizm ente, um sistem a raram ente sabe exatam ente quanto tempo m ais cada processo precisa para concluir. R evu ã o ' 1. Processos interativos geralm ente são orientados a processador ou orientados a E/S? E processos em lote? 2. O escalonador raram ente sabe exatam ente quanto tem po cada processo ainda precisa para finalizar. Considere um sistem a que escalona processos com base nessa estimativa. Com o os processos podem abusar dessa política? R eipO ifa i: 1) Processos interativos norm alm ente esperam pela entrada de usuários, portanto, em geral são orientados a E/S, mas um processo interativo certam ente pode entrar em um a fase durante a qual é prim ariam ente orientado a pro­ cessador. Processos em lote não interagem com usuários e com um ente são orientados a processador. Processos em lote que requerem acesso freqüente ao disco ou a outros dispositivos de E/S são orientados a E/S. 2) Os processos tenderíam a subestim ar os tem pos que faltam até sua conclusão para receber tratam ento favorável de um escalonador. 8.7 Algoritmos de escalonamento Nas seções anteriores discutim os políticas de escalonam ento que especificam os objetivos do escalonador (m axim izar rendim ento ou im por prioridades). Nas subseções seguintes discutirem os algoritm os de escalonam ento que determinam , durante a execução, quais processos executam em seguida. Esses algoritm os decidem quando e por quanto tempo cada processo executa; escolhem preem ptibilidade, prioridades, tempo de execução, tempo até a conclusão, justiça e outras características de processo. Com o verem os, alguns sistemas requerem a utilização de um tipo particular de escalonador (sistem as de tem po real norm alm ente requerem escalonadores preem ptivos, por prioridade). Outros confiam no com por­ tam ento do processo ao tom ar decisões de escalonam ento (favorecem processos orientados a E/S). 8.7.1 EsadonAM£*ito i>rUtteuro-a,-eMtrar-iwUH£Íro~a,-scur (PIFO) Talvez o algoritm o de escalonam ento mais sim ples seja o F IF O (First-ln-First-Out), tam bém denom inado primeiro-achegar-prim eiro-a ser-atendido (First-C om e-First-Served— FCFS) (Figura 8.2). Os processos são despachados conform e o m omento em que chegaram à fila de prontos. O FIFO é não preem ptivo — uma vez obtido um processador, o processo executa até o fim. O FIFO é ju sto no sentido de que escalona processos segundo o m om ento em que chegaram ; desse modo, todos os processos são tratados igualmente, porém , de certa m aneira é injusto porque processos longos fazem pro­ cessos curtos esperar, e processos não im portantes fazem processos im portantes esperar. O FIFO não é útil para escalonar processos interativos, pois não pode garantir tem pos de resposta curtos. O FIFO raram ente é usado com o esquem a mestre nos sistem as de hoje, mas é freqüentem ente encontrado dentro de outros esquemas. Por exemplo, muitos esquem as de escalonam ento despacham processos segundo a prioridade, mas pro­ cessos com a m esm a prioridade são despachados na ordem FIFO. R et/ílã o ' 1. Pode ocorrer adiam ento indefinido em um sistem a que utiliza escalonador FIFO ? Suponha que todos os processos eventualm ente executam até o fim (nenhum processo entra em laço infinito). 2. (V/F) O escalonam ento FIFO raram ente é encontrado nos sistemas atuais. a iò Sistema* operacionais Fila de prontos Processador Conclusão Fujara, 8.2 Escalonamento primeiro -a 'entrar-primeiro -a/-sair. Reipoiík: i) Não, não pode ocorrer adiam ento indefinido porque os processos que chegam têm de entrar no final da fila, o que significa que não podem im pedir que processos que já estejam à espera executem. 2) Falso. O FTFO pode ser encontrado dentro de m uitos algoritm os de escalonam ento atuais (por exemplo, escalonadores por prioridade que despa­ cham processos de m esm a prioridade na ordem FIFO). 8.7.2 EsaUcKammto p er alternância circular (RR) N o escalonam ento por alternância circular (.Round-Robin — RR) (Figura 8.3), processos são despachados na ordem FIFO, mas recebem um a quantidade lim itada de tempo de processador denom inada intervalo de tempo ou quantum.8 Se um processo não concluir antes de seu quantum expirar, o sistem a causará sua preem pção e passará o processador para o próxim o processo à espera. Em seguida, o sistem a colocará o processo que sofreu preem pção no final da fila de prontos. N a Figura 8.3, o processo P, é despachado para um processador onde executa, ou até o fim, caso em que sai do sistema, ou até que seu intervalo de tempo expire, quando sofre preem pção e é colocado no final da fila de prontos. O escalonador então despacha o processo P2. A alternância circular é efetiva para am bientes interativos nos quais o sistem a precisa garantir tempos de resposta razoáveis. O sistem a pode m inim izar a sobrecarga de preem pção por m eio de m ecanism os eficientes de chaveam ento de contexto e mantendo os processos à espera na m em ória principal. Com o o FIFO, a alternância circular é com um ente encontrada dentro de algoritm os de escalonam ento de processador m ais sofisticados, mas raram ente é o esquem a mestre. Com o veremos em toda esta seção, muitos outros algoritm os sofis­ ticados de escalonam ento de processador degeneram ou para FIFO ou para alternância circular, quando todos os processos têm a m esm a prioridade. Por essa razão, o FIFO e a alternância circular são dois dos três algoritm os de escalonam ento requeridos pela especificação POSIX para sistemas de tempo real (discutirem os escalonam ento de tempo real na Seção 8.9, “Escalonam ento de tem po real”).9 Alternância/ circular egoísta/ (SRR) Kleinrock discutiu um a variante da alternância circular denom inada alternância circular egoísta (Selfish Round-Robin — S R R ) que usa o envelhecim ento (aging) para elevar gradativam ente as prioridades dos processos ao longo do tem po.10 Fila de prontos Figura/ 8.3 Escalonamento por alternância/ circular. Nesse esquem a, ao entrar em um sistema, cada processo fica prim eiram ente em um a 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 alternância circular juntam ente com outros processos que tam bém estão na fila ativa, o que significa que processos mais velhos são favorecidos sobre os que acabaram de entrar no sistema. N a SSR, a prioridade de um processo aum enta a um a taxa a enquanto está na fila de espera, e a uma taxa b, onde b < a , quando está na fila ativa. Q uando b < a, os processos da fila de retenção envelhecem a um a taxa m ais alta do que os que estão na fila ativa, portanto, eventualm ente entrarão na fila ativa e disputarão um processador. O ajuste dos parâm etros a t b causa im pacto sobre o modo com o a idade de um processo afeta a latência m édia e o rendim ento. Por exemplo, à Capítulo 8 Eícalonauimto de,processador m edida que a fica muito m aior do que b, os processos que entram no sistema passarão pouco tem po, ou nenhum , na fila de retenção. Se b « a , os processos passarão um a quantidade insignificante de tem po na fila de retenção, portanto, a SRR degenera para alternância circular. Se b - a, cada processo do sistem a funciona à m esm a taxa, portanto, SRR degenera para FIFO. O Exercício 8.23 exam ina algum as propriedades do esquem a SRR. TamM tko do (jUMCtuno A determ inação do tam anho do quantum, q, é crítica para a operação efetiva de um sistem a de com putação com esca­ lonam ento preem ptivo.11 O quantum deve ser pequeno ou grande? Deve ser fixo ou variável? Deve ser o mesmo para todos os processos ou deve ser determ inado separadam ente para cada processo? Prim eiro, vamos considerar o com portam ento do sistem a quando o quantum tom a-se extrem am ente grande ou ex­ trem am ente pequeno. À m edida que o quantum tom a-se grande, processos tendem a receber o tempo que precisam para concluir, portanto, o esquem a de alternância circular degenera para FIFO. À m edida que o quantum tom a-se pequeno, o chaveam ento de contexto predom ina; o desem penho eventualm ente se degrada até o ponto em que o sistem a passa grande parte do seu tempo fazendo chaveam ento de contexto e realizando pouco, ou nenhum , trabalho. Exatam ente onde, entre zero e infinito, o quantum deve ser estabelecido? Considere o seguinte experim ento. Suponha que os valores estam pados na face de um m ostrador circular variem entre q = 0 e q = c, onde c é um valor extrem am ente grande. Com eçam os com o m ostrador posicionado em zero. À m edida que giram os o mostrador, o quantum do sistem a aumenta. Suponha que o sistem a esteja em funcionam ento e que haja m uitos processos interativos. Quando com eçam os a girar o mostrador, os tam anhos dos quanta estão perto de zero e a sobrecarga de chaveam ento de contexto consom e a m aioria dos ciclos do processador. Os usuários interativos defrontam -se com um sistem a vagaroso com tem pos de resposta ruins. Conform e aum entam os o quantum, os tem pos de resposta melhoram. A porcentagem do processador consum ida por sobrecarga é suficientemente pequena para que os processos recebam um pouco de serviço do processador, mas os tem pos de resposta ainda não estão tão rápidos quanto cada usuário gostaria. Ao continuarm os a girar o mostrador, os tem pos de resposta m elhoram e, eventualm ente, alcançam os um tam anho de quantum com o qual grande parte dos processos interativos recebe respostas im ediatas do sistema, mas ainda não está claro se o ajuste do quantum é ótimo. G iramos o m ostrador um pouquinho mais, e os tem pos de resposta ficam ligeiram ente melhores. G iram os o m ostrador novamente, e os tempos de resposta voltam a ficar vagarosos. O quantum vai ficando m aior até que eventualm ente tom a-se grande o suficiente para que cada processo execute até o final após receber o processador. O escalonam ento está degenerando para FIFO, pelo qual processos m ais longos fazem os m ais curtos esperar, e o tempo m édio de espera aum enta enquanto processos m ais longos executam até a finalização antes de devolver o processador. Considere o valor de quantum supostam ente ótim o que resultou em bons tem pos de resposta. É um a pequena fração de segundo. Exatam ente o que esse quantum representa? É grande o suficiente para que a vasta m aioria de requisições interativas requeira m enos tem po do que a duração do quantum . Q uando um processo interativo com eça a executar, em geral usa o processador apenas brevem ente — por um tempo apenas suficiente para gerar um a requisição de E/S, e então bloqueia — ponto em que o processo entrega o processador ao processo seguinte. O quantum é m aior do que esse tempo entre com putação e E/S. Cada vez que um processo obtém o processador, há um a grande possibilidade de o processo executar até gerar um a requisição de E/S, o que m axim iza a utilização da E/S e proporciona tem pos de resposta relati­ vam ente rápidos para processos interativos. E faz isso causando um m ínim o de im pacto sobre os processos orientados a processador que continuam a obter a parte do leão do tempo do processador, porque processos orientados a E/S bloqueiam logo após a execução. E quanto é, exatam ente, o quantum ótim o em segundos? O bviam ente o tam anho varia de sistem a para sistem a e sob cargas diferentes. Varia tam bém de processo para processo, mas nosso experim ento particular não mede as diferenças entre processos. N o Linux, o quantum -padrão designado para um processo é 100 ms, mas pode variar de 10 m s a 200 ms dependendo da prioridade e do com portam ento do processo. Processos de alta prioridade e processos orientados a E/S recebem um quantum m aior do que processos de baixa prioridade e processos orientados para processador.12 No W indow XP, o quan­ tum -padrão designado a um processo é um valor específico da arquitetura igual a 20 ms na m aioria dos sistemas. Esse valor pode variar dependendo de o processo executar no prim eiro plano ou no segundo plano da G U I.13 Q uando todos os processos são orientados a processador, a sobrecarga adicional reduz o desem penho do sistema. Contudo, m esm o quando som ente processos orientados a processador estão ativos, a preem pção ainda é útil. Por exemplo, considere que processos orientados a processador poderíam estar controlando um sistem a de tempo real de m issão crítica — seria desastroso se um processo entrasse em laço infinito ou até mesmo um a fase em que dem andasse mais tempo de processador do que o esperado. M ais sim plesm ente, m uitos sistemas orientados a processador suportam processos interativos ocasionais, portanto a preem pção é necessária para assegurar que processos interativos que estejam chegando recebam bons tem pos de resposta. m Sistemas ojteraciofuus RcvUcur 1. Im agine girar o m ostrador de quantum de um sistem a que contém apenas processos orientados a E/S. Após um ponto q = c, aum entar o valor do quantum resulta em pouca ou nenhum a alteração no desem penho do sistema. O que o ponto c representa e por que não há nenhum a alteração no desem penho do sistem a quando q > c? 2. O texto descreve um valor ótim o de quantum que habilita cada processo orientado a E/S a gerar um a requisição de E/S e então bloquear. Por que isso é difícil de im plem entar? R e ip a ítã i 1 1) Esse ponto seria o mais longo período de com putação entre requisições de E/S para quaisquer processos do sistema. A um entar o valor de q para além de c não afeta nenhum processo, porque cada um deles bloqueia antes da expiração do quantum , portanto os processos não podem aproveitar a vantagem do tem po adicional de processador aloca­ do a eles. 2) No caso geral, é impossível prever o cam inho de execução que um program a adotará, o que significa que o sistem a não pode determ inar com precisão quando um processo gerará um a E/S. Portanto, é difícil determ inar o tamanho ótim o do quantum, porque ele é diferente para cada processo e pode variar ao longo do tempo. 8.73 EsudoHajntewtoporproc£SSO'HiM~curtO'prÍMi£Íro (SPE) O escalonam ento por processo-mais-curto-primeiro ( Shortest-Process-First — SPF) é um a disciplina de escalona­ m ento não preem ptiva na qual o escalonador seleciona o processo à espera com o m enor tem po de execução estim ado até a conclusão. O SPF reduz o tem po m édio de espera em relação ao FIFO .14 Entretanto, a variância dos tem pos de espera é m aior (são m ais imprevisíveis) do que no FIFO, especialm ente para processos grandes. O SPF favorece processos curtos à custa dos mais longos. M uitos projetistas defendem que, quanto mais curto o processo, m elhor serviço deveria receber. Outros não concordam porque essa estratégia não incorpora prioridades (determinadas pela im portâ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. O SPF seleciona processos para atender de um m odo que garanta que o próxim o será concluído e sairá do sistem a tão logo seja possível, o que tende a reduzir o núm ero de processos à espera e tam bém o número de processos que estão esperando atrás de processos grandes. O resultado é que o SPF pode m inim izar o tempo m édio de espera dos processos à m edida que esses passam pelo sistema. Um problem a fundam ental do SPF é que ele requer conhecim ento exato do tem po de execução de um processo e essa inform ação geralmente não está disponível. Portanto, o SPF precisa confiar em estimativas de tempo de execução fornecidas pelo usuário ou pelo sistema. Em am bientes de produção em que os m esm os processos são executados repetidam ente, o sistem a pode ser capaz de m anter heurísticas razoáveis para o tem po de execução. Em am bientes de desenvolvim ento, o usuário raram ente sabe por quanto tempo um processo executará. Um outro problem a de depender de estimativas de duração de processos usuários é que esses podem fornecer estim ati­ vas baixas (e talvez inexatas) para que o sistem a atribua prioridades m ais altas a seus programas. Todavia, se um processo executar por m ais tempo do que o estimado, o sistema poderá term iná-lo e reduzir a prioridade dos outros processos daquele usuário, até mesmo invocando penalidades. Um segundo método é executar o processo pelo tempo estim ado mais uma pequena porcentagem extra e, então, ‘colocá-lo na prateleira’ (preservá-lo na sua form a atual) para que o sistem a possa reiniciá-lo m ais tarde.15 O SPF deriva de um a disciplina denom inada jo b mais curto prim eiro (Shortest Job First — SJB) que pode ter funcio­ nado bem no escalonam ento de jobs em fábricas, mas é claram ente inadequada para escalonam ento de baixo nível em sistem as operacionais. O SPF, assim com o o FIFO, é não preem ptivo e, por isso, não é adequado para am bientes nos quais é preciso garantir tempos de resposta razoáveis. R e ríiã o ' 1. Por que o SPF é mais desejável do que o FIFO quando o rendim ento é um objetivo prim ário do sistem a? 2. Por que o SPF é inadequado para escalonam ento de baixo nível nos sistemas operacionais de hoje? R e ip c itã i 1 1) O SPF reduz o tempo médio de espera, aumentando o rendimento. 2) O SPF não oferece aos processos tem ­ pos de resposta rápidos, o que é essencial nos sistemas amigáveis ao usuário, de multiprogramação, interativos de hoje. 8.7A EscaloKaMtmtoporpr6xMH&^X&'db'resposfa'PíuiU'itttto (HRRN) Brinch Hansen desenvolveu a política próxima-taxa-de-resposta-mais-alta (Highest-Response-Ratio-Next— HRRN) que corrige algum as das deficiências do SPF, particularm ente o viés excessivo contra processos m ais longos e o favoritismo Capítulo 8 EscalonoMieato deprocessador £JQ excessivo em relação a processos curtos. A HRRN é um a disciplina de escalonam ento não preem ptiva na qual a prioridade de cada processo é um a função não apenas do seu tempo de serviço, mas tam bém do tem po que passou à espera pelo ser­ viço.16 U m a vez obtido o serviço, o processo executa até o fim. H RRN calcula prioridades dinâm icas segundo a fórm ula prioridade = tempo de espera + tempo de serviço tempo de serviço Com o o tem po de serviço aparece no denom inador, processos m ais curtos recebem preferência. Entretanto, porque o tempo de espera aparece no numerador, processos mais longos que estão à espera tam bém receberão tratam ento favorável. Essa técnica é sim ilar ao envelhecim ento (aging) e im pede que um escalonador adie processos indefinidamente. R ev íiã o ' 1. (V/F) Com o escalonam ento HRRN, processos curtos são sempre escalonados antes dos longos. 2. O processo P, declarou um tempo de serviço de 5 segundos e está esperando há 20 segundos. O processo P2 declarou um tem po de serviço de 3 segundos e está esperando há 9 segundos. Se o sistem a usar HRRN, qual processo executará prim eiro? R e ip o itã i 1 1) Falso. Quanto m ais tem po o processo esperar, mais provável será que ele seja escalonado antes dos processos m ais curtos. 2) N esse caso, o processo P, tem um a prioridade 5 e o P2, um a prioridade 4, portanto o sistem a executa P, antes. 8.7.5 EscaíofuunMHtopor wMKor-tewpo-d^^execu^Ão-restaMte^(SRT) O escalonamento por menor-tempo-de-execução-restante (Shortest-Remaining-Time — SRT) é a contraparte preemptiva do SPF que tenta aum entar o rendim ento atendendo pequenos processos que chegam. O SRT era efetivo para sistemas de processam ento de jobs que recebiam um fluxo de entrada de jobs; agora já não têm m ais utilidade para a m aioria dos sistem as operacionais. No SRT o escalonador seleciona o processo com o m enor tem po estim ado de execução até o final. No SPF, quando um processo com eça a executar, continua até o final. No SRT, um processo recém -chegado cujo tempo estim ado de execução até o final é m enor provoca a preem pção de um processo em execução cujo tem po estim ado de execução até o final é maior. Novamente, o SRT requer que as estimativas do com portam ento futuro do processo sejam efetivas, e o projetista deve levar em conta o potencial abuso da estratégia de escalonam ento da parte do usuário. O algoritm o deve m anter inform ações sobre o tempo que está sendo gasto no serviço do processo em execução e realizar preem pções ocasionais. Processos que acabaram de chegar cujos tempos de execução são curtos executam quase im ediatam ente. Todavia, o tempo m édio de espera e a variância dos tempos de espera dos processos m ais longos são ainda m aiores do que no SPF. Esses fatores contribuem para um a sobrecarga m aior no SRT do que no SPF. O algoritm o SRT teoricam ente oferece tem pos de espera mínim os, mas, em certas ocasiões, devido à sobrecarga de preem pção, o SPF pode se sair melhor. Por exemplo, considere um sistem a no qual um processo em execução esteja quase no final e chegue um novo processo cujo tem po estim ado de serviço seja pequeno. O processo em execução deve sofrer preem pção? A disciplina do SRT faria a preem pção, mas essa pode não ser a alternativa ótim a. Uma solução é garantir que um processo em execução não possa mais sofrer preem pção quando o tem po de execução restante atingir um determ inado nível baixo. Um problem a semelhante surge quando um processo recém-chegado requer um tempo ligeiramente menor para concluir do que o processo em execução. Em bora o algoritm o im pusesse corretam ente a preem pção do processo em execução, essa podería não ser a política ótima. Por exemplo, se a sobrecarga de preem pção for m aior do que a diferença dos tempos de serviço entre os dois processos, a preem pção resultará em desem penhos inferiores. Com o esses exem plos ilustram , o projetista de sistem as operacionais deve pesar cuidadosam ente a sobrecarga de m e­ canism os de gerenciam ento de recursos contra os benefícios esperados. Vemos tam bém que políticas de escalonam ento relativam ente sim ples podem resultar em mau desem penho por razões sutis. RevU cur 1. O SRT é um algoritm o de escalonam ento de processador efetivo para sistemas interativos? 2. Por que o SRT é um algoritm o de escalonam ento ineficaz para processos de tempo real? R e ip o ifa i l 1) À prim eira vista, o SRT pode parecer um algoritm o efetivo para processos interativos se as tarefas exe­ cutadas antes da em issão de E/S forem de curta duração. Entretanto, o SRT determ ina prioridades segundo o tempo que falta para a conclusão, e não segundo o tem po de execução até E/S. Alguns processos interativos, com o um interpretador 2 2 0 S U tw u is o p e ra c io n a is de com andos, executam pelo tempo de vida da sessão, o que a colocaria no nível m ais baixo de prioridade. 2) O SRT pode resultar em grande variância de tem pos de resposta, enquanto os processos de tem po real requerem um a pequena variância de tempos de resposta para garantir que sempre concluirão suas tarefas dentro de um determ inado período de tempo. 8.7.6 Filas uiultísuAteiç retorno Q uando um processo obtém um processador, especialm ente quando ainda não teve a chance de estabelecer um padrão de com portam ento (por exemplo, por quanto tempo norm alm ente executará antes de gerar uma requisição de E/S, ou que porções da m em ória o processo está correntem ente favorecendo), o escalonador não pode determ inar a quantidade precisa de tempo de processador que o processo precisará. Processos orientados a E/S norm alm ente utilizam o processador apenas brevem ente antes de gerar um a requisição de E/S. Processos orientados a processador poderíam usar o processador durante horas por vez se o sistem a o disponibilizasse em base não preemptiva. Um algoritm o de escalonam ento norm alm ente deve favorecer processos curtos, favorecer processos orientados a E/S para que obtenham um a boa utilização do dispositivo de E/S e bons tem pos interativos de resposta, e devem determ inar a natureza de um processo o m ais rapidam ente possível e escalonar o processo de acordo. F ilas m u ltin ív eis de re to rn o (Figura 8.4) ajudam a cum prir esses objetivos.17Um novo processo entra na rede de enfileiramento no final da fila dc 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 um a E/S ou pela conclusão Nível 1 (FIFO) Use um processador AAA i uroy 8.4 Fila* iMultuiLvzU retorno. Conclusão W" Capítulo 8 EscalonaMieato processador de algum outro evento, ele sairá da rede de enfileiramento. Se o quantum de um processo expirar antes que esse devolva voluntariam ente o processador, o sistema colocará o processo no final da fila de nível mais baixo seguinte. C ontanto que use totalm ente o quantum fornecido a cada nível, o processo continua e passa para o final da fila de nível mais baixo seguinte. Usualm ente há um a fila de nível lim ite 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 preem pção em favor de outro que está chegando a um a fila de nível m ais alto. Nesse sistema, um processo que está em uma fila de nível m ais baixo pode sofrer adiam ento indefinido se uma fila de nível m ais alto contiver pelo menos um processo. Isso não pode ocorrer em sistem as cuja taxa de processos que chegam para serem atendidos é alta, ou nos quais há diversos processos orientados a E/S consum indo seus quanta. Em muitos esquem as de filas multiníveis de retom o, o escalonador aum enta o tam anho 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 enfileira­ mento, m aior será o quantum que recebe cada vez que obtém um processador. Logo veremos por que isso é apropriado. Exam inem os o tratam ento que processos recebem considerando com o essa disciplina responde a diferentes tipos de processos. Filas multiníveis de retom o favorecem processos orientados a E/S e outros processos que necessitam apenas de pequenos surtos de tem po de processador, porque esses processos entram na rede com prioridade alta e obtêm um processador rapidam ente. A disciplina escolhe um quantum grande o suficiente para a prim eira fila, de m odo que a vasta m aioria dos processos orientados a E/S (e processos interativos) em ita um a requisição de E/S antes da expiração do quan­ tum. Quando um processo requisita E/S, ele sai da rede de enfileiram ento depois de ter recebido o tratam ento favorecido desejado. O processo volta à rede quando estiver pronto novamente. Considere agora um processo orientado a processador. O processo entra na rede com prioridade alta, e o sistem a o coloca na fila de nível mais alto. N esse ponto a rede de enfileiramento não ‘sabe’ se o processo é orientado a processador ou a E/S — a m eta da rede é decidir isso rapidam ente. O processo obtém o processador rapidam ente, usa todo o seu quantum , seu quantum expira e o escalonador passa o processo para a fila seguinte de nível m ais baixo. A gora o processo tem uma prioridade mais baixa e os processos que chegam obtêm o processador prim eiro, o que significa que processos interativos ainda continuarão a receber bons tem pos de resposta, m esm o que muitos processos orientados a processador passem mais para baixo na rede de enfileiramento. Eventualm ente o processo orientado a processador não obtém o processador, recebe um quantum m aior do que na fila de nível m ais alto e novam ente usa todo o seu quantum. Então o escalonador coloca o processo no final da próxim a fila de nível m ais baixo. O processo continua a passar para filas de nível mais baixo, espera m ais tem po entre intervalos de tempo e usa todo o seu quantum cada vez que obtém o processador (a menos que sofra preem pção por um processo que chegue). Eventualm ente o processo orientado a processador chega à fila de nível mais baixo, onde percorre em alternância circular juntam ente com outros processos orientados a processador até finalizar. Portanto, filas multiníveis de retom o são ideais para separar processos em categorias segundo suas necessidades de processador. Q uando um processo sair da rede de enfileiram ento pode ser ‘m arcado’ com a identidade da fila de nível m ais baixo na qual residiu. Quando o processo entrar novam ente na rede de enfileiramento, o sistema poderá colocá-lo diretam ente na fila em que concluiu a operação da últim a vez — nesse caso o escalonador estará em pregando a heurística que diz que o com portam ento recente de um processo é um bom indicador de seu com portam ento no futuro próximo. Essa técnica perm ite ao escalonador evitar colocar um processo orientado a processador que está retom ando nas filas de nível m ais alto, em que interferiría no serviço para processos curtos de alta prioridade ou processos orientados a E/S. Infelizm ente, se o escalonador sempre colocar um processo que retom e na fila de nível mais baixo que ocupava da últim a vez que esteve no sistema, o escalonador não conseguirá responder a m udanças no com portam ento do processo (o processo pode estar transitando de orientado a processador para orientado a E/S). O escalonador pode resolver esse problema registrando não som ente a identidade da fila de nível m ais baixo na qual o processo residia, mas tam bém a quantidade de seu quantum que não foi utilizada durante sua últim a execução. Se o processo consum ir todo o seu quantum, então será colocado em um a fila de nível mais baixo (se houver um a disponível). Se o processo em itir um a requisição de E/S antes de seu quantum expirar, poderá ser colocado em um a fila de nível m ais alto. Se o processo estiver entrando em um a nova fase na qual mudará de orientado a processo para orientado a E/S, inicialm ente poderá experim entar algum a lentidão enquanto o sistem a determ inar que sua natureza está m udando, mas o algoritm o de escalonam ento responderá a essa mudança. U m a outra m aneira de tom ar o sistem a responsivo a m udanças no com portam ento de um processo é perm itir que o processo suba um nível na rede de filas de retom o cada vez que devolver voluntariam ente o processador antes de seu quantum expirar. Sim ilarm ente, o escalonador — ao designar uma prioridade — pode considerar o tem po que um processo tem gasto à espera por serviço. O escalonador pode envelhecer o processo prom ovendo-o e colocando-o na fila de nível mais alto seguinte depois de ele ter passado uma certa quantidade de tem po à espera por serviço. U m a variação com um do m ecanism o de filas multiníveis de retom o é fazer um processo passar por alternância circular diversas vezes em cada fila antes de passar para a fila de nível m ais baixo seguinte. E também , o núm ero de ciclos por que passa em cada fila pode ser aum entado à m edida que o processo passa para a fila de nível m ais baixo seguinte. Essa variação tenta refinar m ais ainda o serviço que o escalonador fornece a processos orientados a E/S e a processos orientados a processador. 222 Sistemas ojwaciotuus A fila m ultinível de retom o é um bom exem plo de m ecan ism o ad a p ta tiv o , um m ecanism o que responde às mudanças no com portam ento do sistem a que controla.18*19M ecanism os adaptativos em geral requerem m ais sobrecarga do que os não-adaptativos, mas a resultante sensibilidade a m udanças no sistem a tom a o sistem a m ais responsivo e ajuda a justificar o aum ento de sobrecarga. Com o discutirem os na Seção 20.5.2, “Escalonam ento de processo” , o escalonador de processo do Linux em prega um m ecanism o adaptativo tom ado em prestado das filas multiníveis de retom o. [Nota: N a literatura, os term os ‘escalonam ento de processo’ e ‘escalonam ento de processador’ são usados com o equivalentes.) RwU m 1. Q uais objetivos de escalonam ento devem ser avaliados ao escolher o núm ero de níveis em um a fila m ultinível de retom o? 2. Por que m ecanism os adaptativos são desejáveis nos escalonadores de hoje? R e ip a ifa i l 1) Um objetivo im portante é a variância dos tem pos de resposta. A um entar o núm ero de níveis pode fazer que processos orientados a processador esperem mais tempo, o que aum enta a variância dos tempos de resposta. U m outro objetivo a considerar é a utilização de recursos. Conform e o núm ero de níveis aum enta, muitos processos podem executar e em itir um a E/S antes da expiração de seus quanta, resultando na utilização efetiva tanto do tempo de processador quanto dos dispositivos de E/S. 2) N os com putadores de hoje muitas aplicações podem ser ao m esm o tem po com putacionalm ente intensivas e tam bém orientadas a E/S. Por exemplo, um reprodutor de vídeo de tem po real deve executar E/S para recuperar dados do videoclipe de um servidor rem oto e, então, executar operações com putacionalm ente intensivas para decodificar e exibir imagens de vídeo. D e m odo similar, um jogo interativo com o um sim ulador de voo deve responder a entradas do jogador (m ovim entos do joystick) enquanto apresenta com plicadas cenas em 3D. M ecanism os adaptativos habilitam o sistem a a fornecer respostas alternadas a esses processos ao alternarem entre com portam ento orientado a E/S e orientado a processador. 8.7-7 EscaUfULUietttoporjrtiçãojusta Sistemas geralm ente suportam vários conjuntos de processos relacionados. Por exemplo, o sistem a UNIX (e outros sistemas m ultiusuários) agrupa processos que pertencem a um usuário individual. O escalonam ento p o r fra ç ã o ju s ta (Fair Share Scheduling — FSS) suporta escalonam ento por m eio desses conjuntos de processos.20,21*22,23 O escalonam ento por fração justa habilita um sistem a a garantir justiça por meio de grupos de processos restringindo cada grupo a um subcon­ junto de recursos de sistemas. No am biente UNIX, por exemplo, o FSS foi desenvolvido especificam ente para “dar uma taxa pré-especificada de recursos de sistem a (...) a um conjunto de usuários relacionados” .24 Considerem os um exemplo no qual o escalonam ento por fração ju sta seria útil. Im agine um grupo de pesquisa cujos m em bros com partilhem um sistem a m ultiusuário; eles estão divididos em dois grupos. Os pesquisadores principais — cujo núm ero é pequeno — usam o sistem a para executar trabalhos im portantes, intensivos em com putação, com o fazer sim ulações. Os assistentes de pesquisa — em grande núm ero — usam o sistem a para trabalhos menos intensivos, com o agregar dados e im prim ir resultados. A gora im agine que m uitos assistentes de pesquisa e som ente um pesquisador principal estejam utilizando o sistema. Os assistentes de pesquisa podem consum ir a m aioria do tem po do processador em detrim ento do pesquisador principal que deve executar o trabalho m ais importante. Todavia, se o sistem a perm itisse que o grupo de assistentes de pesquisa usasse som ente 25% do tem po de processador e perm itisse que o grupo de pesquisadores principais usasse 75% , o pesquisador principal não sofreria tal degradação do serviço. D esse modo, o escalonam ento por fração ju sta assegura que o desem penho de um processo seja afetado som ente pela população de seu grupo de processo, e não pela população de usuários com o um todo. Vamos investigar com o o escalonam ento por fração ju sta funciona em um sistem a U M X . N orm alm ente o UNIX consi­ dera taxas de consum o de recursos por todos os processos (Figura 8.5). Contudo, sob o FSS, o sistem a reparte os recursos entre vários g ru p o s d e fra ç ã o ju s ta (Figura 8.6); distribui recursos não utilizados por um grupo de fração ju sta a outros grupos de fração ju sta na proporção de suas necessidades relativas. As instruções do UNIX estabelecem grupos de fração ju sta e associam usuários específicos a eles.25 Para o propósito dessa discussão, vamos adotar a prem issa de que o UNIX usa um escalonador de processo por prioridade em alternância circular ,26 Cada processo tem um a prioridade, e o escalonador associa processos de um a dada prioridade com a fila de prioridade para aquele valor. O escalonador de processo seleciona o processo pronto que está à frente na fila de prioridade m ais alta. Processos dentro de um a dada prioridade são escalonados por alternância circular. Um processo que requer mais serviços após sofrer preem pção recebe um a prioridade m ais baixa. Prioridades de núcleo são altas e aplicam -se a processos que executam no núcleo; prioridades de usuário são m ais baixas. Eventos de disco recebem prioridade m ais alta do que eventos de terminal. O escalonador designa a prioridade do usuário com o um a razão entre a utilização recente do processador e o tem po real decorrido; quanto m ais baixo o tempo decorrido, m ais alta a prioridade. Capítulo 8 Escalonamento de processador 9 9 3 F igura, S.S Escalonador d e processo-padrão do UNIX. O escalonador concede o processador aos usuários, cada, um, deles pode ter m uitos processos. (Propriedade d e A T& T Archives. Reproduzido com, a,permissão d a A T ê c T .f7 Figura, 8. G Escalonador porfração justa,. 0 escalonador porfração ju sta , d ivid e a, capacidade d e recursos do sistema, em,porções, as quais são alocadas por escalonadores d e processo designados a vários grupos defração ju sta . (Propriedade d e AT&l T Arckives. Reproduzido com, apermissão d a A T ScT .f8 Os grupos de fração justa são priorizados segundo o quanto estão próxim os de atingir seus objetivos especificados de utilização de recursos. Grupos que estão indo mal recebem prioridade m ais alta; grupos que estão indo bem recebem prioridade m ais baixa. 224 S U tw u is o p e ra c iô tu ià R evu ã o ' 1. No FSS, por que grupos que não estão atingindo suas metas de utilização de recursos devem receber prioridades mais altas? 2. Qual a diferença entre FSS e disciplinas de escalonam ento de processo-padrão? R e ip a ífa i 1 1) Processos que usam m enos recursos do que o especificado por suas metas provavelmente recebem níveis mais baixos de serviço. A um entando a sua prioridade, o sistem a assegura que esses processos executem o tem po suficiente para utilizar todos os seus recursos requeridos. 2) O FSS reparte recursos entre grupos de processos, ao passo que escalonadores de processo-padrão perm item que todos os processos disputem todos os recursos em pé de igualdade. 8.8 EscaícfiZLHteHtopor prateo No escalonamento por prazo, certos processos são escalonados para concluir em um m om ento ou prazo específico. Esses processos podem ter alto valor, se entregues a tem po, e nenhum valor, caso isso não aconteça.29-30131 O escalonam ento por prazo é com plexo. Prim eiro, o usuário deve fornecer suas exatas requisições de recursos an­ tecipadam ente para garantir que o processo seja concluído dentro do prazo. Essa inform ação raram ente está disponível. Segundo, o sistem a deve executar o processo que tem prazo sem degradar seriam ente o serviço oferecido a outros usuários. O sistem a tam bém deve planejar cuidadosam ente seus requisitos de recursos até o final do prazo, o que pode ser difícil, porque podem chegar novos processos requerendo dem andas imprevisíveis. Por fim, se houver m uitos processos com prazos ativos ao mesmo tempo, o escalonam ento poderá se tom ar extrem am ente complexo. O gerenciam ento intensivo de recursos exigido pelo escalonam ento por prazo pode gerar sobrecarga substancial (veja o quadro “Reflexões sobre sistemas operacionais, intensidade de gerenciam ento de recursos versus valor relativo do recurso”). O consum o líquido de recursos do sistem a pode ser alto, degradando o serviço para outros processos. Com o veremos na próxim a seção, o escalonam ento por prazo é im portante para o escalonam ento de processos de tempo real. Dertouzos dem onstrou que, quando todos os processos podem cum prir seus prazos independentem ente da ordem em que são executados, escalonar prim eiro os processos de prazos m ais curtos é ótim o.32Entretanto, quando o sistem a ficar sobrecarregado, esse deve alocar tem po significativo de processador ao escalonador para determ inar a ordem adequada na qual executar processos para que cum pram seus prazos. Pesquisas recentes concentram -se na velocidade33*34 ou núm ero35 de processadores que o sistem a deve alocar ao escalonador para cum prir os prazos. R m ã* 1. Por que é im portante para o usuário especificar antecipadam ente os recursos que um processo necessita? 2. Por que é difícil cum prir o prazo estabelecido para um processo? R e ip o ífa i 1 1) Porque perm ite que o escalonador garanta que haverá recursos disponíveis para o processo de m odo que ele possa concluir sua tarefa antes do seu prazo. 2) Novos processos podem chegar e apresentar dem andas imprevisíveis ao sistem a que o im peçam de cum prir o prazo de um processo, recursos podem falhar, o processo pode m udar seu com ­ portam ento drasticam ente e assim por diante. R&fyxõee zldômaç ooefâc\ow<x\$ Intensidade de,jerenciantento de recursos versu* valor relativo do recurso S is te m a s o p e ra c io n a is g e ­ renciam recursos de hardware e software. Um tema recorrente que você verá por todo este livro é que a intensidade com que sistem as operacionais precisam gerenciar recursos particulares é proporcional ao valor relativo desses recursos e à sua escassez e intensidade de uso. Por exemplo, o processador e memórias cache de alta velocidade são gerenciados muito mais inten­ samente do que o armazenamento secundário e outros dispositivos de E/S. 0 projetista de sistemas operacionais deve estar consciente das tendências que poderíam afe­ tar o valor relativo dos recursos de sistema e do tempo das pessoas, e deve responder rapidamente à mudança. Capítulo 8 Escalonamento de processador 225 8.9 Escalonamento de tampo real Um objetivo prim ário dos algoritm os de escalonam ento que apresentam os na Seção 8.7 era garantir alta utilização de recursos. Processos que devem executar periodicamente (como uma vez por minuto) requerem algoritmos de escalonamento diferentes. Por exem plo, os tempos de espera ilim itados do SPF podem ser catastróficos para um processo que verifique a tem peratura de um reator nuclear. Sim ilarm ente, um sistem a que use SRT para escalonar um processo que reproduza um videoclipe produziría um a reprodução entrecortada. Escalonamento de tempo real atende às necessidades de pro­ cessos que devem produzir saídas corretas em determ inado m omento (ou seja, que têm um a restrição de tempo).36 Um processo de tempo real pode dividir suas instruções em tarefas isoladas, cada qual deve concluir em determ inado prazo. Outros processos de tempo real podem executar certa tarefa periodicam ente, com o atualizar as localizações de aviões em um sistem a de controle de tráfego aéreo. Escalonadores de tem po real devem garantir que as restrições de tem po sejam cum pridas (veja o quadro “M iniestudo de caso, sistemas operacionais de tempo real”). Disciplinas de escalonam ento de tem po real são classificadas conform e quão bem cum prem os prazos dc um processo. Escalonamento de tempo real não crítico garante que processos de tem po real sejam despachados antes de outros pro­ cessos do sistema, mas não garante qual processo, se é que algum deles, cum prirá suas restrições de tem po.37,38 <Ainicdudo dc caço Stitw uu o^axlôKAM de, tmtfM) real Um sistema de tem po real é ricana para defesa contra possíveis diferente de um sistema-padrão, ataques de bombardeiros durante porque cada operação deve apre­ a Guerra Fria.42 Implementado no sentar resultados corretos e que re­ final da década de 50, esse sistema integrava 56 computadores digitais tornem dentro de um certo período à válvula eletrônica IBM AN/FSQ-7, de tempo.39 Sistemas de tempo real que monitoravam dados de siste­ são usados em aplicações críticas mas de radares pelo país inteiro, quanto a tem po, como sensores para rastrear todas as aeronaves de monitoração. Geralmente são presentes no espaço aéreo dos sistemas pequenos, embarcados. Estados U nido s.43,44 O siste m a Sistemas operacionais de tem po analisava essas in fo rm a çõ e s e real (Real-Time Operating Systems — RTOSs) devem ser cuidadosa­ orientava os caças interceptadom ente projetados para alcançar res, portanto, requeria respostas esses objetivos. (Escalonamento em tem po real.45 O sistema opera­ cional que realizava essa tarefa era de tempo real é discutido na Seção o maior programa de computador 8.9.) O program a de co n tro le doexistente na época.46 p ro je to SAGE (S e m i-A u to m a tic Ao contrário, hoje os RTOSs Ground Environment) pode ter sido visam ao ta m a n ho m ín im o . Há o primeiro sistema operacional de muitos disponíveis, mas o QNX e tem po real.40- 41 O SAGE era um o VxWorks são os líderes da área. projeto da Força Aérea norte-ame­ O QNX implementa as APIs-padrão POSIX com seu próprio micronúcleo e é modelado para sistemas embar­ cados. Também usa troca de men­ sagens para comunicação interprocessos.47 Similarmente, o VxWorks é um sistema de micronúcleo que obedece ao padrão POSIX e é am­ plamente usado em sistemas em­ barcados.48 O QNX funciona melhor do que o VxWorks em plataformas Intel X 86,49 mas não estava dispo­ nível em outros processadores até a versão 6.1 (a versão corrente é a 6.2).50 O VxWorks, todavia, concen­ trou-se no processador PowerPC e tem um histórico de com patibili­ dade por meio de plataform as.51 O VxW orks é, correntem ente, o RTOS mais comum para sistemas embarcados.52 Entre outros RTOSs estão o W indows CE .NET,53o OS9,54o OSE55e distribuições do Linux, como o uClinux.56 O escalonam ento de tem po real não crítico é com um ente im plem entado em com putadores pessoais nos quais uma reprodução suave de m ultim ídia é desejável, mas tolera-se interrupções ocasionais quando a carga do sistem a estiver pe­ sada. Sistemas de tempo real não crítico podem se beneficiar de taxas altas de interrupção que evitam que o sistem a fique ‘preso’ executando um processo, enquanto outros perdem seus prazos. Todavia, o sistem a pode incorrer em sobrecargas significativas se a taxa de interrupção for muito alta, resultando em mau desem penho e prazos perdidos.57 O 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 sistem a.58-59 Sistemas de tempo real críticos podem conter processos periódicos que realizam suas com putações em intervalos de tempo 2 2 6 S is te m a s o p e ra c io n a is regulares (por exemplo, coletar dados de controle de tráfego aéreo a cada segundo) e processos assíncronos que executam em resposta a eventos (por exemplo, responder a altas tem peraturas no núcleo de uma usina nuclear).60 A lgoritm os cie>escalonam ento de, tem po re a l 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 som ente um a vez, esses algoritmos tendem a ser sim ples e a incorrer em pouca sobrecarga. Eles são lim itados, pois não podem se ajustar ao com portam ento variável do processo e dependem de os recursos estarem funcionando e à disposição para garantir que sejam cum pridas as restrições de tempo. Sistem as de tem po real críticos tendem a usar algoritm os de escalonam ento estáticos, porque incorrem em baixa sobrecarga e é relativam ente fácil de provar que as restrições de prazo de cada processo sejam atendidas. O algoritm o de escalonam ento por taxa monotônica (.Rate-M onotonic — RM), por exem plo, é um algoritm o de alternância circular, preem ptivo, por prioridade, que eleva a prioridade de um processo linearm ente (m onotonicam ente) com a freqüência (a taxa) com a qual ele deve executar. E sse algoritm o de escalonam ento estático favorece processos periódicos que executam frequentem ente.61 O algoritm o por taxa monotônica com prazo pode ser usado quando um processo perió­ dico especifica um prazo que não seja igual ao seu período.62 A lgoritm os de, escalonam ento de, tem po re a l dinâm icos Algoritmos de escalonamento de tempo real dinâmicos escalonam processos ajustando suas prioridades durante a execução, o que pode causar sobrecarga significativa. Alguns algoritm os tentam m inim izar a sobrecarga de escalonam ento designando prioridades estáticas a alguns processos, e prioridades dinâm icas a outros.63 O algoritm o de escalonam ento por prazo-mais-curto-primeiro {Earliest D eadline F irst— EDF) é do tipo preemptivo que despacha prim eiro o processo com o prazo m ais curto. Se o processo que chegar tiver um prazo m ais curto do que o processo em execução, o sistem a provocará a preem pção do processo em execução e despachará o que acabou de chegar. O objetivo é m axim izar o rendim ento cum prindo os prazos do m aior núm ero de processos por unidade de tem po (análogo ao algoritm o STR) e m inim izando o tem po m édio de espera (o que evita que processos curtos percam seus prazos enquanto processos longos executam). Dertouzos provou que, se um sistem a fornecer preem pção por hardw are (tem porizadores de interrupção) e os processos de tem po real que estão em escalonam ento não forem interdependentes, o ED F m inim izará a quantidade de tem po pela qual o projeto ‘mais atrasado’ perde seu prazo.64 Todavia, m uitos sistem as de tem po real não fornecem preem pção por hardware, portanto outros algoritm os devem ser em pregados.65 O algoritm o de escalonam ento por folga-mínima-primeiro (M inimum -Laxity-First — MLF) é sim ilar ao EDF, mas baseia sua prioridade na folga de um processo. Folga é um a m edida da im portância de um processo baseada na quantidade de tem po que falta até seu prazo final e o tem po de execução que ainda resta até que sua tarefa (que pode ser periódica) tenha term inado. A folga é calculada usando-se a fórm ula L= D-(T+0, 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 tem po para concluir, a folga será 1. Se um processo tiver folga 0, deverá ser despachado im ediatam ente ou perderá seu prazo. Prioridades no escalonam ento por folga-m ínim a-prim eiro são mais precisas do que as do EDF, porque são determ inadas incluindo o tempo de processador restante que cada processo requer para concluir sua tarefa. Porém, às vezes essa inform ação não está disponível.66 R evu ã o ' 1. Por que a m aioria dos algoritm os de escalonam ento de tem po real é estática? 2. Q uando o algoritm o de folga-m ínim a-prim eiro degenera para EDF? Isso pode ocorrer? Reipoitãi: i) Sistem as de tem po real críticos devem garantir que os prazos dos processos sejam cum pridos. A lgo­ ritm os de escalonam ento estáticos facilitam provar essa propriedade para um sistem a particular e reduzem a sobrecarga da im plem entação. 2) O algoritm o de folga-m ínim a-prim eiro degenera para o algoritm o ED F quando C for idêntico para todos os processos em qualquer instante. É possível, mas altam ente improvável que isso ocorra. 8.10 Escalonamento dLe,tkreaAsJava, Como discutido na Seção 4.6, “Modelos de thread” , sistemas operacionais fornecem vários níveis de suporte para threads. Ao escalonar um processo m ultithread que im plem enta threads de usuário, o sistem a operacional não está consciente de que o processo é m ultithread e, portanto, despacha-o com o um a unidade, exigindo um a biblioteca de nível de usuário para Capítulo 8 Escalonamento de processador 227 escalonar seus threads. Se o sistem a suportar threads de núcleo, poderá escalonar cada thread independentem ente de outros dentro do m esm o processo. E ainda outros sistemas suportam ativações de escalonador que designam cada processo a um thread de núcleo, habilitando a biblioteca de nível de usuário do processo a executar operações de escalonamento. Projetistas de sistem as devem determ inar com o alocar quanta a threads e em que ordem , e com quais prioridades es­ calonar threads em um processo. Por exemplo, um a abordagem de ‘fração ju sta ’ divide o quantum alocado a um processo entre seus threads. Isso im pede que um processo multithread receba níveis altos de serviço sim plesm ente criando um grande núm ero de threads. A lém disso, a ordem na qual os threads são executados pode causar im pacto sobre seu desem penho se dependerem uns dos outros para continuar suas tarefas. N esta seção apresentam os o escalonam ento de threads Java. O escalonam ento de threads no W indows X P é discutido na Seção 21.6.2, “Escalonam ento de thread”. O escalonador Linux (que despacha am bos, processos e threads) é discutido na Seção 20.5.2, “Escalonam ento de processo”. U m a característica da linguagem de program ação Java e de sua m áquina virtual é que todo applet ou aplicação Java é multithread. Cada thread Java recebe um a prioridade na faixa entre Thread.MIN_PRIORITY (um a constante de 1) e Thread.MAX_PRI0RITY (um a constante de 10). Por padrão, cada thread recebe prioridade Thread.NORM_PRIORITY (um a constante de 5). Cada novo thread herda a prioridade do thread que o criou. Dependendo da plataform a, Java im plem enta threads em espaço de usuário ou em espaço de núcleo (veja a Seção 4.6, “M odelos de thread”).67-68 Ao im plem entar threads de usuário, o tempo de execução Java conta com intervalos de tempo (timeslicing) para executar escalonam ento preem ptivo de thread. Sem intervalos de tem po, cada thread de um conjunto de threads de prioridade igual executa até concluir, a menos que saia do estado de execução e entre no estado de espera, adorm ecido ou bloqueado, ou sofra preem pção por um thread de prioridade m ais alta. Com intervalos de tem po, cada thread recebe um quantum durante o qual pode executar. O escalonador de thread Java garante que o thread de prioridade m ais alta da m áquina virtual Java esteja executando o tempo todo. Se houver m últiplos threads no nível de prioridade, esses executarão usando alternância circular. A Figura 8.7 Threads prontos Prioridade 10 Prioridade 9 A M Prioridade 8 Prioridade 7 tl Prioridade 6 Prioridade 5 n M - Prioridade 4 Prioridade 3 Prioridade 2 r-m - K D Prioridade 1 F u jo trO / 8 .7 E sc a lo n a m e n to d e th re a d J c o rte p o r p r io r id a d e . 228 Sistemas ojteraciotuus ilustra a fila multinível de prioridade para threads Java. N a figura, supondo um com putador com um único processador, cada um dos threads, A e B, executa durante um quantum por vez em alternância circular até que am bos concluam a execução. Em seguida, o thread C executa até finalizar. O s threads D, E e F executam durante um quantum cada um, em alternância circular, até que todos concluam a execução. Esse processo continua até que todos os threads executem até o final. Note que, dependendo do sistem a operacional, threads que chegam, cuja prioridade é m ais alta, podem adiar indefinidamente a execução daqueles de prioridade mais baixa. Um thread pode cham ar o método yield da classe Thread para dar a outros threads a chance de executar. Com o o sistema operacional causa a preem pção do thread atual sem pre que um thread de alta prioridade estiver pronto, um thread não pode utilizar o m étodo yield para um thread de prioridade mais alta. Sim ilarm ente, o método yield sempre perm ite que o thread pronto de prioridade mais alta execute, portanto, se todos os threads prontos forem de prioridade m ais baixa do que o thread que está cham ando yield, o thread atual terá a prioridade mais alta e continuará executando. Conseqüentem ente, um thread utiliza o m étodo yield para dar a threads de igual prioridade um a chance para executar. Em um sistem a de inter­ valos de tem po isso é desnecessário, porque cada thread de igual prioridade executará som ente durante seu quantum (ou até perder o processador por algum a outra razão), e outros threads de igual prioridade executarão em alternância circular. Assim, o método yield é apropriado para sistem as que não são de intervalos de tempo (por exemplo, as prim eiras versões do Solaris),69 nos quais um thread ordinariam ente executaria até finalizar antes que um outro thread de igual prioridade tivesse um a oportunidade de executar. R m cu r 1. Por que Java fornece o método yield? Por que um program ador usaria yield? 2. (V/F) Um thread Java de prioridade m ais baixa nunca executará enquanto um thread de prioridade mais alta estiver pronto. R e ip o ifa i: i ) O método yield perm ite que o thread atual libere voluntariam ente o processador e deixe que um thread de igual prioridade execute. Porque aplicações Java são projetadas para ser portáveis e porque o program ador não pode ter certeza de que uma plataform a particular suporte intervalos de tempo, os program adores usam yield para garantir que suas aplicações executrão adequadam ente em todas as plataform as. 2) Verdadeiro. Escalonadores Java executarão o thread pronto de prioridade m ais alta. R esu m o Q uando um sistem a pode escolher os processos que executa, deve ter um a estratégia — denom inada política de escalonamento de processador (ou disciplina)— para decidir quais processos executar em um dado instante. Escalona­ m ento de alto nível — às vezes denom inado escalonam ento de jo b ou escalonam ento de longo prazo — determ ina quais jobs o sistem a perm ite que disputem ativamente os recursos do sistema. A política de escalonam ento de alto nível de­ term ina o grau de m ultiprogram ação — o núm ero total de processos em um sistem a em determ inado instante. Depois de a política de escalonam ento de alto nível ter adm itido um jo b (que pode conter um ou m ais processos) no sistema, a política de escalonam ento de nível interm ediário determ ina quais processos terão perm issão de com petir por um pro­ cessador. E ssa política atende às flutuações de curto prazo da carga do sistema. A política de escalonam ento de baixo nível de um sistem a determ ina quais processos prontos o sistem a designará a um processador quando o próxim o ficar disponível. Políticas de escalonamento de baixo nível comum ente atribuem um a prioridade a cada processo, que reflete a importância desse processo — quanto mais im portante for, m aior é a probabilidade de que a política de escalonam ento o selecione para ser executado em seguida. U m a disciplina de escalonam ento pode ser preemptiva ou não preemptiva. Para evitar que usuários m onopolizem o sistem a (acidental ou propositalm ente), escalonadores preem ptivos ajustam um relógio de interrupção ou um tem porizador de intervalo que gera um a interrupção perio­ dicam ente. Prioridades podem ser atribuídas estaticam ente ou alteradas dinam icam ente durante o curso da execução. Ao desenvolver uma disciplina de escalonam ento, um projetista de sistemas deve considerar um a variedade de fa­ tores, com o o tipo do sistema e as necessidades dos usuários. Esses objetivos podem incluir a m aximização do rendim en­ to, a m axim ização do núm ero de usuários interativos que recebem tempos de resposta ‘aceitáveis’, a m aximização da utilização de recursos, a evitação do adiam ento indefinido, a im posição de prioridades, a m inim ização da sobrecarga e a garantia de previsibilidade de tempos de resposta. Para cum prir esses objetivos, um sistema pode usar técnicas como envelhecimento (aging) e favorecimento de processos cujos requisitos podem ser satisfeitos rapidam ente. M uitas disci­ plinas de escalonam ento exibem justiça, previsibilidade e escalabilidade. Projetistas de sistemas operacionais podem usar objeti­ vos do sistem a para determ inar os critérios que regerão as Capítulo 8 decisões de escalonamento. Talvez a m aior preocupação seja com o um processo usará um processador (se será orientado a processador ou orientado a E/S). U m a disciplina de esca­ lonam ento tam bém pode considerar se o processo é em lote ou interativo. Em um sistem a que em prega prioridades, o escalonador deve favorecer processos de prioridades mais altas. Escalonadores empregam algoritmos que decidem sobre preem ptibilidade, prioridades, tem pos de execução e outras características de processos. O FIFO, tam bém denom ina­ do FCFS, é um algoritm o não preem ptivo que despacha processos conform e o m om ento em que chegam à fila de prontos. No escalonam ento por alternância circular (RR), processos são despachados na ordem FTFO, mas recebem um a quantidade lim itada de tem po de processador deno­ m inada intervalo de tem po ou quantum. Uma variante da alternância circular, cham ada de alternância circular egoís­ ta (SRR), coloca o processo inicialm ente em um a fila de retenção até sua prioridade atingir o nível dos processos da fila ativa, quando então é passado para a fila ativa e escalonado por alternância circular juntam ente com outros processos da fila. A determ inação do tam anho do quantum é crítica para a operação efetiva de um sistem a de com pu­ tador. O quantum ‘ótim o’ é grande o suficiente para que a vasta m aioria das requisições orientadas a E/S e interativas requeiram m enos tem po do que a duração do quantum . O tam anho do quantum ótim o varia de sistem a para sistem a e sob cargas diferentes. O escalonam ento por p rocesso-m ais-curto-prim eiro (SPF) é um a disciplina de escalonam ento não preem ptiva na qual o escalonador seleciona o processo à espera com o m enor tempo de execução estim ado até a conclusão. O SPF reduz o tempo m édio de espera em relação ao FIFO, mas aum enta a variância dos tem pos de resposta. O esca­ lonam ento por m enor-tem po-de-execução-restante (SRT) é a contraparte preem ptiva do SPF que seleciona o processo com o m enor tempo estim ado de execução até a finalização. O algoritm o SRT teoricam ente oferece tempos de espera m ínim os, mas em certas situações, devido à sobrecarga de preem pção, o SPF pode até se sair melhor. O escalona­ m ento por próxim a-taxa-de-resposta-m ais-alta (HRRN) é um a disciplina de escalonam ento não preem ptiva na qual a prioridade de cada processo é um a função não apenas do seu tem po de serviço, mas tam bém do tem po que passou esperando pelo serviço. Filas multiníveis de retom o perm item que um escalo­ nador ajuste dinam icam ente o com portam ento do processo. O próxim o processo a obter um processador é aquele que chegar à frente da fila de nível mais alto, que não estiver vazia na rede de filas m ultiníveis de retom o. Processos orientados a processador são colocados na fila de nível m ais baixo e processos orientados para E/S tendem a ser localizados nas filas de nível mais alto. Um processo em execução sofre preem pção por um processo que chegar a um a fila mais EscalonaMieato de processador 229 alta. Filas m ultiníveis representam um bom exem plo de m ecanism o adaptativo. O escalonam ento por fração ju sta (FSS) suporta esca­ lonam ento de processos e threads relacionados. H abilita um sistem a a garantir justiça para grupos de processos, restringindo cada grupo a um certo subconjunto de recur­ sos de sistema. No am biente UNIX, por exem plo, o FSS foi desenvolvido especificam ente para “fornecer um a taxa pré-especificada de recursos de sistem a (...) a um conjunto de usuários relacionados” . No escalonam ento por prazo, certos processos são esca­ lonados para concluir em um m om ento ou prazo específico. Esses processos podem ter alto valor se entregues a tempo e nenhum valor, caso isso não aconteça. O escalonam ento por prazo é difícil de implementar. Escalonam ento de tem po real deve cum prir repetida­ m ente os prazos dos processos enquanto esses executam. Escalonam ento de tem po real não crítico garante que pro­ cessos de tempo real sejam despachados antes de outros processos do sistema. Escalonam ento de tempo real crítico garante que os prazos de um processo sejam sempre cum ­ pridos. Processos de tem po real críticos devem cum prir seus prazos; caso isso não ocorra, os resultados podem ser catastróficos, resultando em trabalho inválido, falha de sistem a ou até danos aos usuários do sistema. O algoritm o de escalonam ento por taxa m onotônica (RM ) é do tipo estático de alternância circular por prioridade, que eleva a prioridade de um processo m onotonicam ente com a taxa pela qual ele deve ser escalonado. O algoritm o de escalona­ m ento por prazo-mais-curto-primeiro (EDF) é um algoritmo de escalonam ento preem ptivo que favorece o processo que tem o prazo m ais curto. O algoritm o de escalonam ento por folga-m ínim a-prim eiro (MLF) é sim ilar ao EDF, mas baseia a prioridade na folga de um processo, que m ede a diferença entre o tem po que um processo requer para finalizar e o tem po restante até atingir seu prazo final. O sistem a operacional pode despachar os threads de um processo individualm ente ou pode escalonar um processo m ultithread com o um a unidade, exigindo bibliotecas de nível de usuário para escalonar seus threads. Projetistas de sistem a devem determ inar com o alocar quanta a threads e em que ordem. Em Java, cada thread recebe um a prioridade na faixa 1-10. D ependendo da plataform a, Java im plem enta threads em espaço de usuário, ou em espaço de núcleo (veja a Seção 4.6, “M odelos de thread”). Ao implementar threads de usuário, o tempo de execução Java conta com intervalos de tempo (timeslicing) para executar escalonamento preemptivo de thread. O escalonador de thread Java garante que o thread de prioridade mais alta da máquina virtual Java esteja execu­ tando o tem po todo. Se houver m últiplos threads no mesmo nível de prioridade, esses threads executarão por m eio de alternância circular. U m thread pode cham ar o método yield para dar a outros threads de igual prioridade um a chance de executar. 230 Sistemas ojwaciotuus Exercícios 8.1 Quais as diferenças entre os seguintes três níveis de escalonadores? a. escalonador de alto nível b. escalonador de nível intermediário c. despachante 8.2 Qual nível de escalonador deveria tomar a decisão em cada uma das perguntas seguintes? a. Qual processo pronto deve receber um processador quando um deles estiver disponível? b. Qual processo de uma série de processos em lote à espera que foram passados (spooled) para disco deve ser iniciado em seguida? c. Quais processos devem ser temporariamente suspensos para aliviar a carga de curto prazo do processador? d. Qual processo temporariamente suspenso, que se sabe que é orientado para E/S, deve ser ativado para equilibrar o mix de multiprogramação? 8.3 Qual a diferença entre uma política de escalonamento e um mecanismo de escalonamento? 8.4 Eis alguns objetivos comuns do escalonamento: a. ser justo b. maximizar o rendimento c. maximizar o número de usuários interativos que rece­ bem tempos de resposta aceitáveis d. ser previsível e. minimizar sobrecarga f. equilibrar utilização de recursos g. conseguir um equilíbrio entre resposta e utilização h. evitar adiamento indefinido i. obedecer prioridades j. dar preferência a processos que retêm recursos funda­ mentais k. dar um grau mais baixo de serviço a processos com sobrecargas altas l. degradar-se graciosamente sob cargas pesadas Quais dos objetivos precedentes aplica-se mais diretamente a cada um dos seguintes? i. Se um usuário estiver esperando durante um período de tempo excessivo, favorecer esse usuário. ii. O usuário que executa um job de folha de pagamento para uma empresa de 1000 funcionários espera que o job dure aproximadamente o mesmo tempo toda semana. iii. O sistema deve admitir processos para criar um mix que manterá ocupada a maioria dos dispositivos. iv. O sistema deve favorecer processos importantes. v. Um processo importante chega, mas não pode prosse­ guir porque um processo sem importância está retendo os recursos de que o processo importante precisa. vi. Durante períodos de pico o sistema não deve entrar em colapso devido à sobrecarga necessária para gerenciar um grande número de processos. vii. O sistema deve favorecer processos orientados para E/S. viii. Chaveamentos de contexto devem executar o mais rapidamente possível. 8.5 Os itens a seguir são critérios comuns de escalonamento. a. o processo é ou não orientado para E/S b. um processador é ou não orientado para processo c. o processo é em lote ou interativo d. urgência de resposta rápida e. prioridade do processo f. freqüência com que um projeto está sofrendo preempção por processos de prioridade mais alta g. prioridades de processos à espera de recursos retidos por outros processos h. tempo de espera acumulado i. tempo de execução acumulado j. tempo de execução estimado até o final Para cada um dos seguintes, indique quais dos critérios de escalonamento citados acima é o mais apropriado. i. Em um sistema de monitoração de tempo real de uma nave espacial, o computador deve responder imediatamente a sinais recebidos da nave. ii. Embora um processo esteja recebendo serviço ocasio­ nal, seu progresso é apenas nominal. iii. Com que freqüência o processo devolve voluntariamen­ te o processador para E/S antes de seu quantum expirar? iv. O usuário está presente e esperando tempos de resposta interativos ou o usuário está ausente? v. Um objetivo do escalonamento de processador é mini­ mizar os tempos médios de espera. vi. Processos que retêm recursos demandados por outros processos devem ter prioridades mais altas. vii. Processos quase concluídos devem ter prioridades mais altas. 8.6 Quais das afirmações seguintes são verdadeiras e quais são falsas? Justifique suas respostas. a. Uma disciplina de escalonamento é preemptiva se o pro­ cessador não puder ser removido à força de um processo. b. Sistemas de tempo real geralmente usam escalonamento de processador preemptivo. c. Sistemas de tempo compartilhado geralmente usam escalonamento de processador não preemptivo. d. Tempos de retomo são mais previsíveis em sistemas preemptivos do que em sistemas não preemptivos. e. Uma deficiência de esquemas de prioridade é que o sis­ tema honrará fielmente suas prioridades, mas as prioridades podem não ser significativas. 8.7 Por que os processos deveríam ser proibidos de ajustar o relógio de interrupção? 8.8 Quais das seguintes afirmações referem-se a ‘prioridades estáticas’ e quais a ‘prioridades dinâmicas’? a. são mais fáceis de implementar b. exigem menos sobrecarga de tempo de execução c. são mais responsivas a mudanças no ambiente de um processo d. requerem deliberação mais cuidadosa sobre o valor inicial de prioridade escolhido 8.9 Cite várias razões por que o escalonamento por prazo é complexo. 8.10 Dê um exemplo mostrando por que o FIFO não é um esquema de escalonamento de processador para usuários interativos. 8.11 Usando o exemplo do problema anterior, mostre por que a alternância circular é um esquema melhor para usuários inte­ rativos. 8.12 Determinar o quantum é uma tarefa complexa e crítica. Suponha que o tempo médio de chaveamento de contexto entre os processos seja s, e que a quantidade média de tempo que um processo orientado para E/S usa antes de gerar uma requisição E/S seja t{ t» s ) . Discuta o efeito de cada uma das seguintes determi­ nações de quantum, q. Capítulo 8 EscalonoMieato de processador a. q é ligeiramente maior do que zero b. q = s c. s < q < t d. q = t e. q > t f. q é um número extremamente grande 8.13 Discuta o efeito de cada um dos seguintes métodos de atri­ buição de q. a. q fixo e idêntico para todos os usuários b. q fixo e único para cada processo c. q variável e idêntico para todos os processos d. q variável e único para cada processo i. Organize os sistemas anteriores em ordem crescente de sobrecarga de tempo de execução. ii. Organize os sistemas em ordem crescente de responsividade a variações em processos individuais e carga de sistema. iii. Relacione, uma com a outra, as respostas dadas em (i) e (ii). 8.14 Por que cada uma das afirmações seguintes é incorreta? a. SPF nunca tem um rendimento mais alto do que SRT. b. SPF é justo. c. Quanto menor o processo, melhor o serviço que deve receber. d. Como o SPF dá preferência a processos curtos, é útil no compartilhamento de tempo. 8.15 Cite algumas das deficiências de SRT. Como você modifi­ caria o esquema para conseguir melhor desempenho? 8.16 Responda a cada uma das seguintes perguntas sobre a estra­ tégia HRRN de Brinch Hansen: a. Como HRRN evita adiamento indefinido? b. Como HRRN reduz o favoritismo mostrado por outras estratégias em relação a novos processos curtos? c. Suponha que dois processos estejam esperando há aproximadamente o mesmo tempo. Suas prioridades são apro­ ximadamente as mesmas? Explique sua resposta. 8.17 Mostre como filas multiníveis de retomo cumprem cada um dos seguintes objetivos de escalonamento: a. favorecem processos curtos b. favorecem processos orientados a E/S para melhorar a utilização dos dispositivos de E/S c. determinam a natureza de um processo o mais rapida­ mente possível e escalonam o processo de acordo. 8.18 Uma heurística freqüentemente usada por escalonadores de processador é que o comportamento anterior de um processo é um bom indicador do seu comportamento futuro. Dê diversos exemplos de situações nas quais os escalonadores de processador que seguem essa heurística tomariam más decisões. 8.19 Um projetista de sistemas operacionais propôs uma rede de filas multiníveis de retomo na qual há cinco níveis. O quantum do primeiro nível é 0,5 segundo. Cada nível mais baixo tem um quantum de tamanho duas vezes maior do que o quantum do nível anterior. Um processo não pode sofrer preempção até seu quan­ tum expirar. O sistema executa processos em lote e interativos que consistem em processos orientados a processador, bem como orientados a E/S. a. Por que esse esquema é deficiente? b. Quais mudanças mínimas você proporia para tomar o esquema mais aceitável para o mix de processos que pre­ tende? 8.20 Pode-se provar que a estratégia SPF é ótima pois minimiza os tempos médios de resposta. Neste problema você demonstrará esse resultado empiricamente examinando todas as possíveis or­ ^3 1 denações de um dado conjunto de cinco processos. Suponha que cinco processos diferentes estejam esperando para ser processados e que requeiram 1,2,3,4, e 5 unidades de tempo, respectivamente. Escreva um programa que produza todas as possíveis permutações dos cinco processos (5! = 120) e calcule o tempo médio de espera para cada permutação. Classifique-os por ordem crescente de tempo médio de espera e apresente cada tempo médio ao lado do número de permutações do processo. Comente os resultados. 8.21 Prove que a estratégia SPF é ótima pois minimiza os tempos médios de resposta. [Sugestão: Considere uma lista de processos, cada qual com uma duração indicada. Escolha quaisquer dois processos arbitrariamente. Supondo que um seja maior do que o outro, mostre o efeito que colocar o processo menor à frente do maior causará sobre o tempo de espera de cada processo. Elabore uma conclusão adequada.] 8.22 Dois objetivos comuns das políticas de escalonamento são minimizar tempos de resposta e maximizar utilização de re­ cursos. a. Indique como esses objetivos se contrapõem um ao outro. b. Analise cada uma das políticas de escalonamento apre­ sentadas neste capítulo com base nessas duas perspectivas. Quais delas apresentam viés em relação à minimização de tempos de resposta de usuários? c. Desenvolva uma nova política de escalonamento que habilite um sistema a ser ajustado, para obter um bom equi­ líbrio entre esses objetivos conflitantes. 8.23 No esquema de alternância circular egoísta, a prioridade de um processo presente na fila de retenção aumenta a uma taxa a até que a prioridade seja tão alta quanto as dos processos que estão na fila de ativos, quando então o processo entra na fila de ativos e sua prioridade continua a crescer, mas agora a uma taxa b. Esta­ belecemos anteriormente que b <= a. Discuta o comportamento de um sistema SRR st b > a. 8.24 Qual a diferença entre a operação de um escalonador por fração justa e a de um escalonador de processo convencional? 8.25 Em um sistema monoprocessador com n processos, há quan­ tos modos diferentes de escalonar um caminho de execução? 8.26 Suponha que um sistema tenha implementado um escalo­ nador de fila multinível de retomo. Como poderemos adaptar esse escalonador para formar os seguintes escalonadores? a. FCFS? b. alternância circular 8.27 Quais as semelhanças e diferenças entre EDF e SPF? 8.28 Quando algoritmos de escalonamento estático de tempo real são mais apropriados do que algoritmos de escalonamento dinâmico de tempo real? 8.29 Antes de a Sun implementar seu sistema operacional Solaris corrente, o sistema UNIX da mesma Sun,70 usado primariamente para estações de trabalho, realizava escalonamento de processo atribuindo prioridades básicas (de uma alta, de -20, até uma baixa, de +20, com uma mediana de 0) e fazendo ajustes de prioridade. Os ajustes de prioridades eram calculados em resposta a mudanças nos sistemas e adicionados a prioridades básicas para calcular as prioridades correntes; o processo que tivesse a prioridade corrente mais alta era despachado antes. O ajuste de prioridades apresentava um forte viés em favor de processos que recentemente tinham usado pouco tempo de processador. O algoritmo de escalonamento ‘esquecia’ a utiliza­ ção do processador rapidamente para dar o benefício da dúvida a processos cujo comportamento mudava. O algoritmo de esca­ lonamento ‘esquecia’ 90% da recente utilização do processador em 5 *n segundos; n é o número médio de processos executáveis 232 Sistemas ojwaciotuus no último minuto.71 Considere esse algoritmo de escalonamento de processo ao responder cada uma das seguintes perguntas. a. Processos orientados a processador são mais favoreci­ dos quando a carga do sistema for pesada ou quando a carga do sistema for leve? b. Como um processo orientado a E/S desempenharia imediatamente após a conclusão de uma E/S? c. Processos orientados a processador podem sofrer adiamento indefinido? d. À medida que aumenta a carga do sistema, qual será o efeito causado pelos processos orientados a processador sobre tempos de resposta interativos? e. Como esse algoritmo responde a mudanças no com­ portamento de um processo orientado a processador para um orientado a E/S? 8.30 O sistema operacional VAX/VMS72executava em uma ampla variedade de computadores, de pequenos a grandes. No VAX/VMS a faixa de prioridades de processos é de 0 a 31, sendo 31 a mais alta atribuída a processos críticos de tempo real. Processos normais recebem prioridades na faixa de 16 a 31. As prioridades de proces­ sos de tempo real normalmente permanecem constantes; nenhum ajuste é aplicado. Processos de tempo real continuam executando (sem sofrer expirações de quantum) até sofrerem preempção por processos com prioridades mais altas ou iguais, ou até entrar em vários estados de espera. Outros processos são escalonados como do tipo normais com prioridades de 0 a 15. Entre esses estão processos interativos e processos em lote. As prioridades de processos normais variam. Suas prioridades básicas em geral continuam fixas, mas recebem ajustes dinâmicos de prioridade para dar preferência a processos orientados a E/S sobre processos orientados a processador. Um processo normal retém o processador até sofrer preempção por um processo mais importante, até que entre em um estado especial como um evento de espera ou até que seu quantum expire. Pro­ cessos que têm as mesmas prioridades correntes são escalonados por alternância circular. Processos normais recebem ajustes de prioridade de 0 a 6 acima de suas prioridades básicas. Esses incrementos positivos ocorrem, por exemplo, quando recursos requisitados ficam disponíveis ou quando uma condição pela qual um processo está esperando for sinalizada. Processos orientados a E/S tendem a obter ajustes po­ sitivos de prioridade, enquanto processos orientados a processador tendem a ter prioridades atuais próximas das suas prioridades bá­ sicas. Responda a cada uma das perguntas seguintes a respeito dos mecanismos de escalonamento de processo do VAX/VMS. a. Por que as prioridades de processos de tempo real são normalmente mantidas constantes? b. Por que processos de tempo real não são suscetíveis a expirações de quantum? c. Quais processos normais geralmente recebem preferên­ cia: os orientados a E/S ou os orientados a processador? d. Sob quais circunstâncias um processo de tempo real pode perder o processador? e. Sob quais circunstâncias um processo normal pode perder o processador? f. Como são escalonados processos normais de mesma prioridade? g. Sob quais circunstâncias processos normais recebem ajustes de prioridade? Projetos sugeridos 8.31 Elabore um estudo de pesquisa descrevendo as semelhanças e diferenças entre os modos como Windows XP, Linux e Mac OS X escalonam processos. 8.32 Embora o sistema operacional normalmente seja responsável por escalonar processos e threads, alguns sistemas permitem que processos usuários tomem decisões de escalonamento. Pesquise como isso é feito no caso de escalonamento de processos em sistemas operacionais de exonúcleo (visite www.pdos.lcs.mit.edu/ pubs.html#£xokernels) e no caso de escalonamento de threads de usuá­ rio e de ativações de escalonador. 8.33 Pesquise como o escalonamento de tempo real é implemen­ tado em sistemas embarcados. 8.34 Pesquise as políticas e mecanismos de escalonamento comumente usadas em sistemas de banco de dados. Simulações sugeridas 8.35 Uma solução para o problema de evitação do adiamento indefinido de processos é o envelhecimento (aging), no qual as prioridades dos processos que estão à espera aumentam quanto mais esperam. Desenvolva diversos algoritmos de envelhecimento e escreva programas de simulação para examinar seus respec­ tivos desempenhos. Por exemplo, pode-se forçar a elevação da prioridade de um processo linearmente ao longo do tempo. Para cada algoritmo de envelhecimento que escolher, determine quão bem são tratados os processos que estão à espera em relação aos processos de alta prioridade que estão chegando. 8.36 Um problema do escalonamento preemptivo é que a sobre­ carga de chaveamento de contexto pode tender a predominar se o sistema não for cuidadosamente ajustado. Escreva um programa de simulação que determine os efeitos da taxa de sobrecarga de chaveamento de contexto sobre o tempo de quantum típico. Dis­ cuta os fatores que determinam a sobrecarga de chaveamento de contexto e os fatores que determinam o tempo de quantum típico. Indique como a obtenção de um equilíbrio adequado entre eles (ou seja, ajustar o sistema) pode afetar radicalmente o desempenho do sistema. Capítulo 8 EscalonoMieato d&processador 233 Notas 1. 2. 3. 4. 5. 6. 7. 8. 9. T. Ibaraki, H. M. Abdel-Wahab e T. Kameda, “Design of minimum-cost deadlock-free systems”, Journal oftheACM, v. 30, na 4, out. 1983, p. 750. E. G. Coffman Jr. E L. Kleinrock, “Computer scheduling methods and their countermeasures”, Proceedings ofAFIPS, SJCCy v. 32, 1968, p. 11-21. M. Ruschitzka e R. S. Fabry, “A unifying approach to scheduling”, Communications ofthe ACM, v. 20, nfl 7, jul. 1977, p. 469-477. C. A bbot, “ Intervention schedules for real-tim e programming”, IEEE Transactions on Software Engineering, v. SE-10, nQ3, maio 1984, p. 268-274. K. Ramamritham e J. A. Stanovic, “Dynamic task scheduling in hard real-time distributed systems”, IEEE Software, v. 1, na 3, jul. 1984, p. 65-75. R. A. Volz e T. N. Mudge, “Instruction levei timing mechanisms for accurate real-time task scheduling”, IEEE Transactions on Computers, v. C-36, nu 8, ago. 1987, p. 988-993. M. Potkonjak e W. Wolf, “A methodology and algorithms for the design of hard real-time multitasking ASICs”, ACM Transactions on Design Automation o f Electronic Systems (TODAES), v. 4, na 4, out. 1999. L. Kleinrock, “A continuum of time-sharing scheduling algorithms”, Proceedings ofAFIPS, SJCC, 1970, p. 453458. “sched.h — execution scheduling (REALTIME)”, The Open Group Base Specifications Issue 6, IEEE Std. 1003.1,2003, 20. 21. 22. 23. 24. 25. 806*4076/6jd6amqqo?a=view. 26. 27. 28. 29. 30. www.opengroup.org/onlinepubs/007904975/bosedefs/sched.h.htfnl. 10. 11. 12. L. Kleinrock, “A continuum of time-sharing scheduling algorithms”, Proceedings ofAFIPS, SJCC, 1970, p. 453458. D. Potier, E. Gelenbe e J. Lenfant, “Adaptive allocation of central processing unit Quanta”, Journal oftheACM , v. 23, na 1, jan. 1976, p. 97-102. Linux source code, version 2.6.0-test3, sched.c, lines 62-135, miller.cs.wm.edu/lxr3.linux/htlp/sourceAernel/sched.c?v=2.6.0-test3. 13. 14. 15. 16. 17. 18. 19. D. Solomon e M. Russinovich, Inside Windows 2000, 3ed. Redmond: Microsoft Press, 2000, p. 338, 347. J. Bruno, E. G. Coffman Jr. E R. Sethi, “Scheduling independent tasks to reduce mean finishing tim e”, Communications o f the ACM, v. 17, na 7, jul. 1974, p. 382387. H. M. Deitei, “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. P. Brinch Hansen, “Short-term scheduling in multiprogramming systems”, Third ACM Symposium on Operating Systems Principies, Universidade de Stanford, out. 1971, p. 103-105. L. Kleinrock, “A continuum of time-sharing scheduling algorithms”, Proceedings ofAFIPS, SJCC, 1970, p. 453458. P. R. Blevins e C. V. Ramamoorthy, “Aspects of a dynamically adaptive operating system”, IEEE Transactions on Computers, v. 25, na 7, jul. 1976, p. 713-725. D. Potier, E. Gelenbe e J. Lenfant, “Adaptive allocation of central processing unit Quanta”, Journal o f the ACM, v. 23, nc 1, jan. 1976, p. 97-102. J. P. Newbury, “Immediate tumaround: an elusive goal”, Software: Practice and Experience, v. 12, na 10, out. 1982, p. 897-906. G. J. Henry, “The fair share scheduler”, Bell Systems Technical Journal, v. 63, na 8, parte 2, out. 1984, p. 18451857. C. M. Woodside, “Controllability of Computer performance tradeoffs obtained using controlled-share queue schedulers”, IEEE Transactions on Software Engineering, v. SE-12, nQ 10, out. 1986, p. 1041-1048. J. Kay e P. I^auder, “A fair share scheduler”, Communications oftheACM , v. 31, na 1, jan. 1988, p. 44-55. G. J. Henry, “The fair share scheduler”, Bell Systems Technical Journal, v. 63, na 8, parte 2, out. 1984, p. 1846. “Chapter 9, fair share scheduler”, Solaris 9 System Administrator Collection, 11 nov. 2003, docs.sun.com/db/doc/ 31. 32. 33. 34. 35. 36. 37. 38. 39. G. J. Henry, “The fair share scheduler”, Bell Systems Technical Journal, v. 63, nfl 8, parte 2, out. 1984, p. 1848. G. J. Henry, “The fair share scheduler”, Bell Systems Technical Journal, v. 63, nQ8, parte 2, out. 1984, p. 1847. G. J. Henry, “The fair share scheduler”, Bell Systems Technical Journal, v. 63, nQ8, parte 2, out. 1984, p. 1846. N. R. Nielsen, “The allocation of computing resources — is pricing the answer?”, Communications ofthe ACM, v. 13, nfl 8, ago. 1970, p. 467-474. L. J. McKell, J. V. Hansen e L. E. Heitger, “Charging for Computer resources”, ACM Computing Surveys, v. 11, nQ2, jun. 1979, p. 105-120. A. J. V. Kleijnen, “Principies of Computer charging in a university-type organization”, Communications oftheACM, v. 26, na 11, nov. 1983, p. 926-932. M. L. Dertouzos, “Control robotics: the procedural control of physical processes”, Proceedings IFIP Congress, 1974, p. 807-813. B. Kalyanasundaram e K. Pruhs, “Speed is as powerful as clairvoyance”, Journal ofthe ACM (.JACM), v. 47, na 4, jul. 2002, p. 617-643. T. Lam e K. To, “Performance guarantee for online deadline scheduling in the presence of overload”, Proceedings o f the Twelfth Annual ACM-S1AM Symposium on Discrete Algorithms, 7-9 jan. 2001, p. 755-764. C. Koo, T. Lam, T. Ngan e K. To, “Extra processors versus future information in optimal deadline scheduling”, Proceedings o f the Fourteenth Annual ACM Symposium on Parallel Algorithms and Architectures, 2002, p. 133-142. J. Stankovic, “Real-time and embedded systems”, ACM Computing Surveys, v. 28, na 1, mar. 1996, p. 205-208. J. Xu e D. L. Pamas, “On satisfying timing constraints in hard-real-time systems”, Proceedings ofthe Conference on Software fo r Criticai Systems. Nova Orleans, LO, 1991, p. 132-146. D. Stew art e P. Khosla, “R eal-tim e scheduling of dynamically reconfigurable systems”, Proceedings o f the IEEE International Conference on Systems Engineering. Dayton, OH, ago. 1991, p. 139-142. B. van Beneden, “Comp.realtime: frequently asked questions (version 3.6)”, 16 maio 2002, www .faqs.org/faqs/realtim ecomputing/faq/. 234 40. 41. 42. 43. 44. 45. 46. 47. Sistemas ojwaciotuus MITRE Corporation, “MITRE — about us — MITRE history — semi-automatic ground environment (SAGE)”, 7 jan. 2003, www.mitre.org/obout/sage.htinl. P. Edwards, “SAGE”, The Closed World. Cambridge, MA: MTT Press, 1996, www.si.umich.edu/~pne/PDF/cw.ch3.pdf. R Edwards, “SAGE”, The Closed World. Cambridge, MA: MIT Press, 1996, www.si.umich.edu/~pne/PDF/cw.ch3.pdf. MITRE Corporation, “MITRE — about us — MITRE history — semi-automatic ground environment (SAGE)”, 7 jan. 2003, www.mitre.org/obout/sa