Enviado por Do utilizador2682

Sistemas-Operacionais-DEITEL-3ª-Edicao-pdf

Propaganda
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: [email protected] 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&ia