Historia e Evolucao dos Sistemas Operacionais
Video da aula estara disponivel em breve
Por que estudar a historia dos SO?
Entender a evolucao dos sistemas operacionais nao e um exercicio de nostalgia. Cada geracao resolveu problemas que ainda existem hoje em formas diferentes. Batch processing virou CI/CD pipelines. Time-sharing virou cloud computing multi-tenant. As solucoes mudam, mas os problemas fundamentais — compartilhar recursos, isolar usuarios, maximizar throughput — sao os mesmos.
Vamos percorrer as geracoes em ordem cronologica, observando o problema que cada uma tentou resolver e a solucao que introduziu.
Geracao 0: Sem Sistema Operacional (1940s)
Os primeiros computadores — como o ENIAC (1945) e o Manchester Mark I (1948) — nao tinham sistema operacional. O programador interagia diretamente com o hardware:
- Programas eram inseridos via cabos e interruptores (e depois cartoes perfurados)
- Um unico programa rodava de cada vez, com acesso exclusivo a toda a maquina
- O programador era tambem o operador: carregava o programa, monitorava a execucao, recolhia a saida
- A CPU ficava ociosa durante a maior parte do tempo (enquanto o humano trocava cartoes)
Geracao 1: Batch Processing (1950s - 1960s)
A primeira geracao de SO resolveu o problema da ociosidade com processamento em lote (batch). Um operador humano agrupava programas semelhantes em lotes e os submetia ao computador sequencialmente, sem intervencao humana entre eles.
Fila de Jobs (cartoes perfurados)
+=======+ +=======+ +=======+ +=======+
| Job A | | Job B | | Job C | | Job D |
+=======+ +=======+ +=======+ +=======+
| | | |
v v v v
+------------------------------------------------+
| Monitor Residente (SO) |
| - Carrega proximo job automaticamente |
| - Gerencia I/O basico |
| - Contabiliza tempo de CPU |
+------------------------------------------------+
| Hardware (CPU + RAM) |
+------------------------------------------------+
Execucao: A ---> B ---> C ---> D (sequencial)
nenhuma interacao com o usuario
O monitor residente era o precursor do SO moderno. Ele ficava permanentemente em memoria e gerenciava a transicao entre jobs. Conceitos introduzidos nesta geracao:
- Job Control Language (JCL): linguagem para descrever os requisitos de cada job
- Spooling: uso de fitas/discos para buffer de entrada e saida, permitindo sobreposicao de I/O com computacao
- Protecao de memoria: o monitor precisava se proteger de jobs defeituosos
Geracao 2: Multiprogramacao (1960s)
Mesmo com batch processing, a CPU ficava ociosa durante operacoes de I/O (que eram ordens de magnitude mais lentas). A solucao: multiprogramacao — manter varios jobs em memoria simultaneamente e alternar entre eles.
Memoria RAM:
+---------------------------+
| SO (Monitor) |
+---------------------------+
| Job A (rodando) | ← usando CPU
+---------------------------+
| Job B (esperando I/O)| ← esperando disco
+---------------------------+
| Job C (pronto) | ← na fila
+---------------------------+
Sem multiprogramacao: Com multiprogramacao:
CPU: |==A==|.....|==A==|.... CPU: |==A==|==B==|==C==|==A==|
I/O: |.....|==A==|.....|==A I/O: |.....|==A==|==B==|.....|
(pontos = ocioso) CPU utilization sobe de ~30% para ~70%+
A multiprogramacao introduziu necessidades fundamentais que definem um SO moderno:
- Escalonamento de CPU: quem roda quando? Qual criterio?
- Gerencia de memoria: como alocar memoria para multiplos jobs? Como impedir que um acesse a memoria do outro?
- Protecao: um job com bug nao pode corromper outros jobs nem o SO
- Concorrencia: multiplos jobs compartilhando recursos exige sincronizacao
O OS/360 da IBM (1964) foi o sistema mais ambicioso desta era — e tambem um dos projetos de software mais problematicos da historia, como documentado por Fred Brooks em The Mythical Man-Month.
Geracao 3: Time-Sharing (1960s - 1970s)
Multiprogramacao maximizava o uso da CPU, mas os usuarios ainda nao interagiam com o computador em tempo real. Time-sharing resolveu isso: cada usuario recebe uma fatia de tempo da CPU, criando a ilusao de que cada um tem o computador so para si.
Terminais conectados ao mainframe:
[Terminal 1] [Terminal 2] [Terminal 3] [Terminal 4]
| | | |
+------+-------+------+------+------+-------+
| | |
+------v--------------v--------------v------+
| SO com Time-Sharing |
| quantum = 100ms por usuario |
+--------------------------------------------+
| Mainframe |
+--------------------------------------------+
Timeline da CPU (quantum = 100ms):
|--U1--|--U2--|--U3--|--U4--|--U1--|--U2--|--U3--|--U4--|
0 100 200 300 400 500 600 700 800 ms
Cada usuario percebe resposta "instantanea" para
comandos interativos (editar texto, compilar, etc.)
Sistemas de time-sharing introduziram:
- Terminais interativos: o usuario digita comandos e ve resultados imediatamente
- Sistemas de arquivos hierarquicos: cada usuario tem seus proprios arquivos
- Shell: interpretador de comandos como interface principal
- Memoria virtual: cada processo "pensa" que tem toda a memoria para si
O Multics (1964-1969, MIT + Bell Labs + GE) foi o projeto mais influente desta era. Embora tenha fracassado comercialmente, suas ideias — sistema de arquivos hierarquico, memoria virtual, seguranca por aneis de protecao — estao em todo SO moderno. Quando Ken Thompson e Dennis Ritchie saíram do projeto Multics, criaram o Unix (1969) como uma versao simplificada.
Geracao 4: Computacao Pessoal (1980s - 1990s)
Com microprocessadores baratos, o paradigma mudou: em vez de um computador caro compartilhado por muitos usuarios, cada pessoa tem seu proprio computador. Isso trouxe novos desafios:
- Interface grafica (GUI): o usuario nao e mais um programador. Xerox PARC inventou, Apple popularizou, Microsoft democratizou.
- Facilidade de uso sobre eficiencia: tempo de CPU e barato, tempo do usuario e caro (inversao completa da Geracao 0)
- MS-DOS (1981): single-user, single-tasking, sem protecao de memoria
- Windows 3.1/95: multitarefa cooperativa, depois preemptiva
- Mac OS (classico): GUI pioneira, mas sem protecao de memoria ate o OS X
Paralelamente, o mundo Unix continuou evoluindo com sistemas distribuidos: NFS (Network File System), RPC (Remote Procedure Call), e os primeiros clusters.
Geracao 5: Sistemas Distribuidos e Cloud (2000s - presente)
O problema voltou ao compartilhamento, mas agora em escala planetaria. Cloud computing e essencialmente time-sharing moderno: multiplos usuarios compartilham hardware em data centers, isolados por virtualizacao.
1960s Time-Sharing 2020s Cloud Computing
================== =====================
1 mainframe 1 data center (milhares de servers)
N terminais burros N usuarios via internet
Isolation: protecao de memoria Isolation: VMs + containers
Quantum: 100ms CPU slices Quantum: vCPUs + cgroups
Billing: tempo de CPU Billing: pay-per-use (CPU/RAM/storage)
Shell: linha de comando Shell: APIs REST + CLI + web console
O problema e o MESMO: compartilhar recursos de forma
justa, segura, e eficiente entre multiplos usuarios.
Tecnologias-chave desta geracao:
- Virtualizacao: VMware, KVM, Xen — rodar multiplos SOs sobre o mesmo hardware
- Containers: Docker, LXC — isolamento leve usando namespaces e cgroups do Linux
- Orquestracao: Kubernetes — gerenciar milhares de containers como um SO distribuido
- Serverless: funcoes efemeras executadas sob demanda (AWS Lambda, Cloudflare Workers)
Linha do Tempo Resumida
1945 ENIAC — sem SO, programacao por cabos
1956 GM-NAA I/O — primeiro SO batch (GM Research)
1964 OS/360 — multiprogramacao, JCL
1964 Multics — time-sharing, memoria virtual, seguranca
1969 Unix — simplificacao do Multics, escrito em C (1973)
1971 Intel 4004 — primeiro microprocessador comercial
1981 MS-DOS — SO para IBM PC
1983 GNU Project — Richard Stallman, software livre
1984 Macintosh — GUI para consumidores
1991 Linux 0.01 — Linus Torvalds, kernel livre
1995 Windows 95 — multitarefa preemptiva para consumidores
2001 Mac OS X — kernel Mach + BSD, Unix para consumidores
2007 iPhone OS — Unix-based mobile OS
2008 Android — kernel Linux para mobile
2010 OpenStack — cloud open-source
2013 Docker — containers para todos
2014 Kubernetes — orquestracao de containers
2020+ eBPF, io_uring, Rust no kernel Linux — evolucao continua
Padroes Recorrentes
Observando a historia, alguns padroes se repetem:
- Centralizacao ↔ Descentralizacao: mainframes → PCs → cloud → edge computing. O pendulo oscila.
- Eficiencia → Conveniencia → Eficiencia: quando hardware e caro, otimizamos. Quando fica barato, priorizamos produtividade. Quando escala explode, voltamos a otimizar.
- Isolamento sempre cresce: sem protecao → protecao de memoria → processos isolados → VMs → containers → microVMs (Firecracker).
- Abstracoes empilham: cada geracao constroi sobre as anteriores. Containers usam cgroups e namespaces, que sao features do kernel Linux, que descende do Unix, que simplificou o Multics.
No harness.os
A evolucao dos sistemas operacionais encontra um paralelo direto na evolucao do harness.os:
- Geracao "batch": no inicio, o harness era um conjunto de arquivos (CLAUDE.md, rules/) lidos sequencialmente por um unico agente. Um "job" por vez, sem interacao entre sessoes.
- Geracao "multiprogramacao": com o MCP server, multiplas ferramentas passaram a compartilhar o mesmo banco de dados. O harness comecou a gerenciar acesso concorrente a knowledge, decisions, e learnings.
- Geracao "time-sharing": com o mesh (marco.ai, build.ai, cortex.ai), multiplos "usuarios" (agentes) compartilham a mesma infraestrutura de conhecimento, cada um com sua visao isolada (project_id).
- Geracao "cloud": a arquitetura Scale 2 do harness.os — com MCP server centralizado e Neon Postgres — e essencialmente um modelo multi-tenant, onde cada projeto e um "tenant" com acesso a recursos compartilhados.
# "Batch era" — um arquivo, um agente, sem estado
def batch_harness():
rules = open("CLAUDE.md").read()
# agente executa, sem persistencia
# "Multiprogramacao" — estado compartilhado, multiplos tools
def multiprog_harness():
db = connect("neon://harness-db")
session = db.execute("INSERT INTO sessions ...")
knowledge = db.execute("SELECT * FROM knowledge WHERE ...")
# "Time-sharing" — multiplos agentes, isolamento por projeto
def timeshare_harness(project_id):
session = start_session(project_slug="way2fly")
# cada agente ve apenas SEU projeto
# handoffs permitem "context switching" entre sessoes
knowledge = get_knowledge(project=project_id)
end_session(summary="...", next_steps=["..."])
A mesma pressao que motivou cada geracao de SO — maximizar o uso de recursos escassos — motivou cada evolucao do harness. Tokens de LLM sao o recurso escasso moderno, assim como tempo de CPU era o recurso escasso dos anos 1960.
Homework
Compare a evolucao do harness.os com as geracoes de SO preenchendo a tabela abaixo. Para cada geracao, identifique:
- Qual era o recurso escasso na epoca?
- Qual mecanismo de compartilhamento foi introduzido?
- Qual e o equivalente no harness.os?
| Geracao | Recurso Escasso | Mecanismo SO | Equivalente harness.os |
|-----------------|-----------------|---------------------|------------------------|
| Batch | ??? | ??? | ??? |
| Multiprogramacao| ??? | ??? | ??? |
| Time-sharing | ??? | ??? | ??? |
| PC | ??? | ??? | ??? |
| Cloud | ??? | ??? | ??? |
Bonus: identifique em qual "geracao" o harness.os esta hoje, e qual seria a proxima evolucao (equivalente a "cloud" para SO).
Resumo
- Sem SO → batch → multiprogramacao → time-sharing → PC → cloud
- Cada geracao resolveu um problema de compartilhamento de recursos
- Os mesmos problemas reaparecem em cada escala: isolamento, escalonamento, protecao
- Unix (1969) e o ancestral comum de quase todos os SO modernos
- Cloud computing e time-sharing em escala planetaria com virtualizacao
Verifique seu entendimento
Qual problema principal a multiprogramacao resolveu que o batch processing sozinho nao conseguia?
Verifique seu entendimento
Cloud computing moderna pode ser vista como uma evolucao de qual conceito dos anos 1960?