Beruflich Dokumente
Kultur Dokumente
• um provedor de abstrações
• um coordenador de recursos
• um mágico: faz com que seu sistema pareça mais do que na realidade ele é (mais
de um processador, memória maior)
Problemas:
Novos problemas:
Fase 2: Computadores são rápidos; pessoas são lentas; ambos são caros. Necessário
tornar as pessoas mais produtivas.
Fase 3: Computadores são baratos; pessoas são caras. Dar um computador para
cada pessoa.
• workstation pessoal:
o SUN (Stanford University Network)
o Xerox Alto
• Apple II
• IBM PC
• MacIntosh
Problemas:
CTSS (1962):
• MIT
• um dos primeiros sistemas timesharing
• motivou o desenvolvimento do MULTICS
MULTICS (1965):
UNIX (1970):
PCs e Workstations
Hoje: redes
• Enormes:
o se o kernel do seu SO ocupa menos que 1 Mbyte, ele é considerado
pequeno
o tipicamente centenas de milhares de linhas de código
o 100-1000 homens-ano de esforço de desenvolvimento
• Complexos:
o assíncronos
o idiossincrasias de hardware (tem que executar em qualquer plataforma)
o classes diferentes de usuários apresentam diferentes demandas
o performance é crucial
• Mal compreendidos:
o os sistemas duram mais que seus criadores
o muito grandes para uma só pessoa compreender
o nunca estão completamente livres de erros (OS/360 foi liberado com
1000 "bugs")
o comportamento é difícil de prever; ajustes de performance feitos, em
geral, baseados em intuição; intuição quase sempre está errada
Conceitos em SOs:
Funcionalidade de SOs
Concorrência: usuário compartilha memória, dispositivos de E/S e processadores; no
entanto cada usuário imagina que tem sua própria máquina
Suporte a E/S: dispositivos de E/S são lentos; é desejável que a CPU não fique ociosa
durante operações de E/S. Motivação para interrupções.
Redes: usuários podem se comunicar com outras máquinas ou podem utilizar outras
máquinas
O que é um Processo?
A estrutura proc é utilizada para manter informações que têm que ficar na memória
durante toda a vida do processo. A estrutura user contem o restante do estado do
processo, e pode ser paginada para o disco.
Uniprogramação e Multiprogramação
/*
* Copyright (c) 1985 by Sun Microsystems, Inc.
*/
#ifndef _sun4m_pcb_h
#define _sun4m_pcb_h
/*
* Sun software process control block
*/
#include
/*
* The system actually supports one more than the above number.
* There is always one window reserved for trap handlers that
* never has to be saved into the pcb struct.
*/
#ifndef LOCORE
#include
struct pcb {
/* this struct MUST be 1K aligned -- checked for in assym.s */
struct l1pt pcb_l1pt; /* level 1 page table */
label_t pcb_regs; /* saved pc and sp */
int pcb_psr; /* processor status word */
int pcb_uwm; /* user window mask */
struct rwindow pcb_wbuf[MAXWIN]; /* user window save buffer
*/
char *pcb_spbuf[MAXWIN]; /* sp's for each wbuf */
int pcb_wbcnt; /* number of saved windows in pcb_wbuf
*/
#endif !LOCORE
/* pcb_flags */
#define AST_SCHED 0x80000000 /* force a reschedule */
#define AST_CLR 0x80000000
#define PME_CLR 0
#define AST_NONE 0
/* pcb_flags */
#define CLEAN_WINDOWS 0x1 /* keep user regs clean */
#define FIX_ALIGNMENT 0x2 /* fix unaligned references */
#endif /*!_sun4m_pcb_h*/
O SO tem que assegurar que os processos não interfiram uns com os outros. Isto
significa:
• garantir que todos os processos tenham acesso aos recursos, como memória e
CPU: escalonamento
• controlar o estado dos processos, de tal modo que um processo não possa
modificar arbitrariamente o estado de outro processo: proteção
Estados de um processo
A qualquer instante, um processo pode estar em um dos seguintes estados (Fig. 2-2):
De outros processos. O sistema Unix tem uma primitiva (system call) fork que cria uma
cópia do processo existente. Por exemplo, um shell Unix cria uma cópia dele mesmo
cada vez que você quer executar um programa. Uma cópia espera enquanto a outra
executa o comando. Como o fork funciona:
Problema: os dois processos são idênticos. Como fazer para executar um programa
diferente?
Um probleminha adicional: como é que tudo isso começa? No início não existe nenhum
processo, portanto não é possível executar um fork .
1. Thread
2. Espaço de Endereçamento
• a memória utilizada pelo programa; isto inclui o código e grande parte dos dados
• arquivos abertos
• contador de programa
• registradores
• dados alocados na pilha (na maioria variáveis locais)
• endereços de retorno dos procedimentos ativos
Se olharmos o pcb :
• quando uma thread solicita uma leitura, ela fica bloqueada até que os dados
fiquem disponíveis
• um único processo com uma única thread não pode executar nada de útil
enquanto o disco está sendo acessado
• com threads múltiplas, uma thread pode continuar a executar enquanto a outra
espera pelo I/O
Threads compartilham:
• memória
• arquivos abertos
• variáveis globais
• pilhas
• contador de programa
• estado do processador
(Tanenbaum 2.4)
Estados de um Processo
• running
• blocked
• ready
• rever Fig. 2-2
Recursos
FIFO (First-In-First-Out)
Filas Múltiplas
• classses de prioridades
• objetivos:
o aumentar a eficiência
o tratar diferentes tipos de processos, cada qual com suas
necessidades
• problemas?
Escalonamento Garantido
Sumário
Utilização da Memória
Informação armazenada na memória pode ser classificada de várias
maneiras. Alguns exemplos:
Proteção:
• modificável
• leitura-apenas ("read-only")
• executável
Inicialização
Endereço ou Dado
Questões:
Segmentos
Ligadores (Linkers)
Funções de um ligador
Ligação: desafios
Ligador: funcionamento
Tem que dar vários passos; não é possível terminar sem ter lido todos arquivos.
• Passo 1
o ler toda informação da tabela de símbolos
o decidir como a memória será rearranjada
o ler toda informação de relocação
o descobrir tudo que for necessário nas bibliotecas
• Passo 2
o ler os segmentos e informação de relocação
o modificar os endereços
o escrever o novo módulo com símbolos, segmentos, e relocação
main ()
{
static float x, val;
extern float sin();
extern printf(), scanf();
Módulo matemático
float sin(x)
float x;
{
static float tmp1, tmp2, result;
// calcula função seno aqui
return (result);
}
Biblioteca C
Sumário
Passo 1:
Passo 2:
Monoprogramação
Até agora vimos como a memória é vista do ponto de vista do programa do
usuário. A partir de agora vamos ver como o S.O. vê (e gerencia) a
memória.
Todos os processos são ligados assumindo que o endereço inicial é 0. Como carregá-los
na memória? A solução mais simples é utilizar monoprogramação:
Processos no Unix
if (pid < 0) {
/* fork falhou, em geral por falta de memoria */
} else if (pid > 0) {
/* codigo do pai entra aqui */
} else {
/* codigo do filho entra aqui */
}
Signal