Você está na página 1de 58

O SISTEMA UNIX

Histrico
Final da dcada de 60: o sistema operacional MULTICS (MULTiplexed Information andComputing Service foi projetado para ser um sistemaoperacional padro, pelos melhores pesquisadores da poca (MIT, GE, Bell Labs). Enorme sucesso acadmico. Enorme fracasso comercial.. Era um software muito pesado para hardwares com pouca capacidade computacional. UNICS (UNIplexed Information and Computing Service): sistema projetado por um pesquisador da Bell Labs, que abandonou o projeto no meio (Ken Thompson). Funcionou primeiramente em um PDP7. Devido ao seu sucesso, seu cdigo foi portado para um PDP-11, reescrito em linguagem de alto nvel(B). Ritchie concebe uma nova linguagem, derivada do B: a linguagem C. O sistema UNIX reescrito em C por Ritchie e Thompson. A Bell Labs d o sistema Unix s universidades com o cdigo fonte (1974).

O SISTEMA UNIX - HISTRICO

UNIX verso 6 (1976): primeiro padro do Unix no meio universitrio, contou com contribuies de vrias universidades. Prxima verso: UNIX verso 7 (1978). Como o sistema operacional era escrito em uma linguagem de alto nvel, era relativamente simples port-lo para diferentes arquiteturas. No primeiro trabalho de migrao entre arquiteturas, foi projetado um compilador C porttil (Johnson) que poderia, devidamente customizado, gerar cdigo para vrias arquiteturas diferentes. UNIX system III (1982): lanado comercialmente em 1984 pela AT&T. Fracasso comercial. UNIX system V(1983): verso melhorada do system III. Sucesso de mercado. UNIX BSD: Desenvolvido a partir do Unix verso 6 pela University of California, em Berkeley. A verso 4BSD incorpora: paginao, sistema de arquivos rpido, comunicao em rede com o protocolo TCP/IP. final dos anos 80: duas verses comerciais incompatveis do UNIX, UNIX 4.3BSD e UNIX System V release III. Unix-likes: Ultrix (DEC), Xenix (Microsoft)

O SISTEMA UNIX - HISTRICO

Tentativas de padronizao: System V Interface Definition (AT&T): definio de chamadas ao sistema e formato de arquivo. S foi utilizado no System V. POSIX (Portable Operating System) (Comit de Padronizao IEEE): pegou as caractersticas comuns aos sistemas System V e BSD e props padronizaes de interfaces de: chamadas de sistema, shell, correspondncia, acesso a arquivos, etc. OSF (consrcio Open Software Foundation): tentativa da IBM, DEC e HP de produzir um Unix que possua todas as caractersticas vigentes. IEEE + X11 + Motif + DCE, etc. UI (consrcio Unix International): resposta da AT&T -> AIX (da IBM).

O SISTEMA UNIX - OBJETIVOS


O Unix um sistema multi-usurio e multi-tarefa, simples, poderoso e flexvel. Simplicidade: Tentando evitar um dos principais fatores que causaram o fracasso do MULTICS, os algoritmos do Unix foram selecionados por sua simplicidade, e no por sua velocidade ou sofisticao. Flexibilidade: No foi feito um projeto detalhado do Unix antes de sua implementao, apesar de terem existido alguns princpios de projeto. Assim, foram projetados um pequeno nmero de elementos bsicos que poderiam se combinar de diversas maneiras, resultando em surpreendente flexibilidade. Portabilidade: Na implementao do Unix, foi tomado um grande cuidado em manter as estruturas independentes do hardware, na medida do possvel. Essa caracterstica, aliada utilizao da linguagem C para a confeco do cdigo fonte, geraram cdigo de portabilidade relativamente simples. O Unix um sistema feito por programadores para programadores. O usurio inexperiente pode dispor de uma interface simples porm maior cuidado foi tomado em oferecer ao programador experiente uma interface concisa e poderosa.

Controle de usurios no UNIX


Cada usurio deve possuir uma conta(login) no Unix para ter acesso ao sistema. Cada conta possui uma senha(password) associada. O par login,password deve constar em um arquivo de senhas (/etc/passwd). O arquivo de senhas no escondido e todos os usurios podem l-lo. A password contida neste arquivo est criptografada. Cada usurio identificado por um nmero inteiro (uid). Contedo do arquivo /etc/passwd:
username:password:uid:gid:coment:home_dir:shell Contem uma linha por usurio.

Superusurio:
usurio com uid = 0 (root). Poderes do superusurio: ler e escrever em todos os arquivos do sistema executar chamadas de sistema protegidas

Alguns utilitrios Unix necessitam de permisso de superusurio para executar. Neste caso, o usurio normal adquire temporariamente os direitos do superusurio. Esta necessidade criou a diferenciao entre usurio efetivo e usurio real.
real: uid utilizado para identificar o usurio efetivo: uid temporrio durante a execuo do comando. uid efetivo = uid do dono do arquivo executvel

Gerncia de Processos no Unix


Os processos no Unix so processos tradicionais (heavyweight). Cada processo possui recursos alocados a ele (ambiente) e registradores (linha de execuo). Um processo opera sobre um nico conjunto de registradores. Os termos heavyweight e lightweight descrevem o custo de uma operao de troca de contexto. Processos heavyweight = grande overhead na troca de contexto. O Unix um sistema operacional multiprogramado. Muitos processos ativos em um dado instante. Muitos processos de um mesmo usurio ativos em um dado instante. Os processos so organizados em uma rvore de processos.

init

getty

getty

... cmd1

shell cmd2 cmdn

Todo processo tem um nmero nico que o identifica (pid process id). Todo processo tem um pai (ppid - parent pid). Todo processso um descendente do processo init.

Gerncia de Processos Unix Tabela de Processos:


Guarda as informaes referentes aos processos. acessada pelo pid. As informaes relacionadas ao processo so visualizadas atravs do comando ps (shell). Algumas informaes contidas:
Flags de estado: descrevem o estado de execuo do processo. UID: grupo do usurio que startou o processo pid: identificador nico do processo ppid: pid do pai do processo CP: fator de utilizao de CPU PRI: prioridade do processo NI: parmetro para o escalonador SZ:tamanho do segmento de dados + pilha RSS: Memria real utilizada pelo processo WCHAN: evento pelo qual o processo est esperando STAT: status de execuo do processo TT: terminal associado ao processo TIME: tempo de CPU (user+system) COMMAND: arquivo executvel que gerou o processo

Gerncia de Processos Unix Criao de processos: Entidades componentes do processo: pilha bss dados
Cdigo
conjunto de registradores flags diversos descritores abertos

O contexto de um processo est descrito na tabela de processos A criao de processos no Unix envolve a cpia da maioria dos campos contidos na tabela de processo (registradores, flags de estado, etc) e a cpia dos segmentos de cdigo, dados e pilha do processo pai. pilha bss dados
Cdigo
entrada na tabela de processos PROCESSO PAI

pilha bss dados


Cdigo
entrada na tabela de processos PROCESSO FILHO

Ao final da criao, os processos pai e filho executam o mesmo arquivo executvel.

Gerncia de Processos Unix - Criao de Processos Como o PC (program counter) tambm foi copiado de processo-pai para processo-filho, o processo-filho comea a sua execuo na instruo imediatamente posterior instruo que causou a sua criao. Primitiva de criao de processos: fork
Sintaxe: int fork()
parmetros nome da primitiva retorno

Descrio: O novo processo uma cpia exata do processo pai, com as seguintes excees: o pid de cada processo nico; o ppid de cada processo diferente; o processo filho possui uma cpia dos descritores abertos do pai; todos os semforos so zerados; os parmetros de escalonamento so zerados no filho; locks no so herdados; sinais pendentes so descartados no filho Retorno: No caso de sucesso, retorna 0 para o filho e o pid do processo filho para o pai. Caso contrrio, retorna -1.

Gerncia de Processos Unix - Criao de Processos

Exemplo:
if ((pid = fork()) < 0) { printf(erro no fork\n); exit (1); } if (pid == 0) printf (sou o processo filho\n); else printf (sou o processo pai\n);

Obs: Normalmente, quando ns criamos um novo processo, desejamos executar um novo programa. Nos demais sistemas operacionais, o nome do arquivo executvel dado no momento da criao do processo. No Unix, precisamos fazer em dois passos. Primeiro, devemos usar o fork para gerar um processo filho que a rplica do processo pai. Depois, devemos executar a primitiva que faz o processo executar um novo programa (execve)

Gerncia de Processos Unix - Criao de Processos


Primitiva de carga de arquivo executvel: exec Sintaxe:
int execve(char *path, char *argv[], char *envp[]); int execl(char *path, char *argv[0], char *argv[1],..., (char *) 0);

Descrio: Transforma o processo que chamou esta primitiva em um novo processo. O novo arquivo executvel fornecido em path. A lista de parmetros fornecida em argv. Argv[0] deve ser o nome do programa (sem path). A lista de variveis de ambiente fornecida em envp. Estas duas listas devem ser terminadas por NULL. O novo processo mantem o pid, o ppid, os parmetros do escalonador, o real uid, os descritores de arquivos abertos So alterados: a imagem do processo na memria, o conjunto de registradores e o uid efetivo. Retorno: S retorna no caso de erro (-1). No caso de sucesso no pode retornar, pois a imagem original do processo foi perdida.

Gerncia de Processos Unix Exemplo:


if ((pid == fork()) < 0) { printf(erro no fork\n); exit(1); } if (pid == 0) /* processo filho */ execve(prfilho, NULL, NULL); printf(continuo o codigo do pai\n);

Algumas primitivas teis:


int getppid();int getiud();int getpid(); int geteuid();

Trmino de processos:
Sempre que um processo filho termina a sua execuo, o processo pai deve ser avisado. Quando um processo morre, seus filhos passam a ser filhos do processo init. Quando um processo morre e o pai no est esperando o aviso de sua morte, o processo morrendo fica em um estado <zombie> ou <defunct> at que o pai seja avisado.
init init

10

10

15

12

15

Gerncia de Processos Unix - Trmino de Processos


O trmino de processos implementado atravs das primitivas wait e exit. Primitiva que termina um processo: _exit Sintaxe: void _exit(int status); Descrio: todos os descritores de arquivos abertos so fechados. Se o processo pai estiver executando um wait, ele notificado do trmino do processo filho e tem acesso ao status. Se o pai no estiver esperando, o status salvo at que o pai execute um wait. Retorno: Nunca retorna, j que causa o trmino do programa Obs: A maioria dos programas C, chama a rotina exit(), que limpa as bibliotecas standard antes de terminar o programa Primitiva de espera de trmino de um processo: wait Sintaxe: int wait (int *status); Descrio: bloqueia o processo pai at que um de seus filhos termine ou seja parado para trace. Se exite algum processo quej morreu mas no foi esperado ainda, o retorno imediato. Retorno:
-1: o processo no tem filhos se o primeiro byte = 0177: filho parado se o primeiro byte != 0177 e > 0: filho terminou por causa de um sinal seno filho terminou por um exit.

Gerncia de Processos Unix - Estados dos Processos No Unix, de maneira similar aos outros sistemas operacionais, um processo pode estar pronto para rodar (ready) ou bloqueado (blocked). O processo pode estar bloqueado por vrias razes, dentre elas:
esperando que a pgina corrente seja carregada (P); esperando I/O (D); parado por um utilitrio de debug (T); dormindo por poucos segundos (S); dormindo por muitos segundos (I).

Os processos prontos para rodar competem pelo uso da CPU, da a necessidade de um algoritmo de escalonamento de processos. Escalonamento de processos no Unix: o algoritmo utilizado o escalonamento com prioridades dinmicas. Processos com a mesma prioridade so regidos pela poltica round-robin. O algoritmo proposto favorece a execuo de processos I/O bound (critrio = tempo de resposta).
usurio 2 2 usurio 1 1 usurio 0 0 -1 espera filho -2 sada em term -3 I/O em disco

modo usurio preemptvel

prioridade cresce

modo kernel no preemptvel

Gerncia de Processos Unix - Escalonamento de Processos


Clculo dinmico da prioridade: A cada clock tick, o contador de utilizao do processador do processo em execuo incrementado na tabela de processos (quantun = x clock_ticks). Periodicamente, a prioridade de cada processo recalculada:
pri = base + utilizao do processador - aging base normalmente zero, mas o processo pode pedir para rodar em prioridade mais baixa. Nesse caso, base tem um valor positivo Para impedir starvation: o algoritmo do Unix usa a tcnica de aging (as prioridades dos processos que esperam CPU h muito tempo so decrementadas periodicamente).

Primitiva que reduz a prioridade de um processo: nice Sintaxe: int nice(incr) Descrio: o fator base substitudo por incr. Os processos usurio s podem aumentar o nice e consequentemente reduzir a prioridade do processo. S superusurio pode fornecer valores negativos

Gerncia de Processos Unix - Comunicao entre Processos Os processos Unix, ao longo de sua execuo, podem necessitar trocar dados e controles com outros processos. O sistema operacional Unix permite que os processos se comuniquem de diversas maneiras:
Pipes; Filas de mensagens; Memria compartilhada; Semforos; Sinais.

Pipes
Na linguagem de comando (shell), os pipes so utilizados com freqncia. Exemplo: ls -l * |grep May. Neste caso, a sada do comando ls -l * passada como entrada do prximo comando grep May. Na programao Unix, ns utilizamos exatamente o mesmo conceito. Os pipes so buffers protegidos em memria, acessados segundo a poltica FIFO
pipe FIFO p1 p2

Gerncia de Processos Unix - Pipes

Primitiva de criao de pipes: Sintaxe: int pipe(int fd[2]); Descrio: cria o mecanismo pipe, que composto de dois descritores de arquivos (fd[0] e fd[1]) para leitura e escrita, respectivamente. Retorno: 0 no caso de sucesso e -1 no caso de erro

Manipulao de pipes: Escrita: Primitiva: int write(int fd, char *buf,


int nbyte)

Descrio: escreve nbyte do buffer apontado por buf no descritor de arquivo fd. Retorno: Se OK, retorna o nmero de bytes escritos com sucesso em fd. Se no, retorna -1.

Gerncia de Processos Unix - Pipes

Leitura: Primitiva: int read(int fd, char *buf,


int nbyte)

Descrio: l nbyte do arquivo fd para o buffer apontado por buf. Retorno: Se OK, retorna o nmero de bytes lidos com sucesso de fd. Se no, retorna -1.

Mecanismo genrico: cria o pipe (primitiva pipe); cria o processo (primitiva fork). A primitiva fork vai duplicar os descritores de arquivos, assim, o pipe fica disponvel para o processo pai e o processo filho; um processo l e o outro escreve no pipe;

Gerncia de Processos Unix - Exemplo de utilizao de pipes


Exemplo:

main() { int

pid, /* pid do processo filho */ fd[2], /* descritores do pipe */ estado; /* estado do processo filho */ char mensagem[30]; /* cria o pipe */ if (pipe(fd) < 0) { printf(erro na criacao do pipe\n); exit(1); } /* cria o processo */ if ((pid = fork()) < 0) { printf(erro na criacao do processo\n); exit(1); } /* codigo do filho */ if (pid == 0) { if (read(fd[0], mensagem, 30) < 0) printf(erro na leitura\n); else printf(valor lido = %s\n, mensagem); exit(0); } /* codigo do pai */ strcpy(mensagem, teste do envio no pipe); if (write(fd[1], mensagem, sizeof(mensagem)) < 0) printf(erro na escrita\n); wait(&estado); exit(0);

Gerncia de Processos Unix - Filas de Mensagens

As filas de mensagens so mecanismos de comunicao protegidos. Podem estar em memria ou em disco. S os processos autorizados tm acesso fila. As filas de mensagens so permanentes, ou seja, elas no so destrudas quando o processo que as criou morre. Necessitam de uma remoo explcita. Passos para a utilizao de filas:
Criar a fila Obter o identificador da fila Ler ou escrever na fila Remover a fila (ou no)
fila de mensagens m1 m2 m3

p1

p2

pn

Gerncia de Processos Unix - Filas de Mensagens Programao via fila de mensagens:


Primitiva de criao e obteno de filas: msgget Includes necessrios:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

Primitiva de criao e obteno de filas: msgget Criao de filas: Sintaxe:


int msgget(key_t key, int IPC_CREAT | msgflg);

Descrio: o processo que chama esta primitiva cria uma fila com a chave key e as permissoes de acesso em msgflg. O parmetro IPC_CREAT determina a criao de filas. O uid e gid da fila so o uid e o gid efetivos do usurio dono do processo. Retorno: Sucesso: identificador da fila (msqid). Este identificador ser utilizado em todas as operaes sobre a fila. Erro: -1. Exemplo:
if (idfila = msgget(0x1233, IPC_CREAT | 0x1FF) < 0) { printf(erro na criacao da fila\n); exit(1); }

Gerncia de Processos Unix - Filas de Mensagens

Obteno de identificador de fila: Sintaxe:


int msgget(key_t key, int msgflg);

Descrio: o processo que chama esta primitiva obtem o identificador da fila criada com a chave key . As permissoes de acesso so especificadas em msgflg. Retorno: Sucesso: identificador da fila (msqid). Este identificador ser utilizado em todas as operaes sobre a fila. Erro: -1. (erros de permisso de acesso, fila no existe). Exemplo:

if (idfila = msgget(0x1233, 0x124) < 0) { printf(erro na obtencao da fila\n); exit(1); }

Gerncia de Processos Unix - Filas de Mensagens


Envio de mensagem: Sintaxe:
int msgsnd(int msqid, struct msgbuf *msgp, int msgsize, int msgflg);

Descrio: o processo que chama esta primitiva envia a mensagem contida em msgp de tamanho msgsize para a fila msqid com os flags msgflg.
msqid o identificador obtido com msgget. msgp aponta para a estrutura da mensagem que a seguinte: long mtype; char mtext[1]; Pode ser enviada uma mensagem de tamanho qualquer, contanto que o primeiro campo seja long e descreva o tipo da mensagem. msgsize o tamanho da mensagem em bytes. msgflg determina o tipo do envio: IPC_NOWAIT: o processo no espera que a mensagem seja colocada na fila e retorna imediatamente 0 : o processo fica bloqueado at que a mensagem possa ser colocada na fila, ou at que a fila seja removida ou at o envio de um sinal que deve ser tratado.

Retorno: Sucesso: 0 Erro: -1.

Gerncia de Processos Unix - Filas de Mensagens


Recepo de mensagem: Sintaxe:
int msgrcv(int msqid, struct msgbuf *msgp, int msgsize, long msgtyp, int msgflg);

Descrio: o processo chama esta primitiva para receber


uma mensagem do tipo msgtyp de tamanho msgsize da fila msqid com os flags msgflg. A mensagem recebida deve ser colocada no buffer apontado por msgbuf. msqid o identificador obtido com msgget. msgp aponta para a estrutura da mensagem a se recebida que a seguinte: long mtype; char mtext[1]; Pode ser enviada uma mensagem de tamanho qualquer, contanto que o primeiro campo seja long e descreva o tipo da mensagem. msgsize o tamanho da mensagem em bytes. msgtyp o tipo da mensagem (primeiro campo da mensagem). msgp -> mtype deve ser igual a msgtyp. msgflg == IPC_NOWAIT : se no houver mensagem, o processo retorna. msgflg == 0 : se no houver mensagem, o processo fica bloqueado at que chegue uma mensagem, ou a fila seja removida ou seja recebido um sinal tratvel.

Retorno:
Sucesso: nmero de bytes enviados (sem contar o tipo) Erro: -1.

Gerncia de Processos Unix - Filas de Mensagens

Remoo de fila de mensagem: Sintaxe:


int msgctl(int msqid, IPC_RMID, struct msqid_ds *buf);

Descrio: o processo que chama esta primitiva remove a fila de mensagem msqid. A remoo da fila s pode ser feita pelo usurio que a criou ou pelo superusurio. Retorno: Sucesso: 0 Erro: -1.

Gerncia de Processos Unix - Exemplo de Filas de Mensagens


#include<errno.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> main() { int pid, idfila, fd[2], estado; struct mensagem { long pid; char msg[30]; }; struct mensagem mensagem_env, mensagem_rec; /* cria */ if ((idfila = msgget(0x1223, IPC_CREAT|0x1ff)) < 0) { printf("erro na criacao da fila\n"); exit(1); } pid = fork(); if (pid == 0) { mensagem_env.pid = getpid(); strcpy(mensagem_env.msg, "teste de mensagem"); msgsnd(idfila, &mensagem_env, sizeof(mensagem_env), 0); exit (0); } msgrcv(idfila, &mensagem_rec, sizeof(mensagem_rec), 0, 0); printf("mensagem recebida = %d %s\n", mensagem_rec.pid, mensagem_rec.msg); wait (&estado); exit(0); }

Gerncia de Processos Unix - Memria Compartilhada


Os processos no Unix podem compartilhar explicitamente um segmento de memria protegido pelo kernel. Os passos envolvidos so os seguintes: Criao do segmento de memria compartilhada:
segmem

P1

Depois da criao, os processos podem dar um attach no segmento compartilhado. O attach bem sucedido retorna um ponteiro para o incio da rea compartilhada.
imagem P1 imagem P2

Gerncia de Processos Unix - Memria Compartilhada


Aps o attach, o segmento de memria compartilhada pode ser acessado via o ponteiro retornado, com operaes normais de read e write. O segmento de memria compartilhado no destrudo quando o processo que o criou morre. Ele necessita de uma remoo explcita. Includes necessrios:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h>

Primitiva de criao e obteno de memria compartilhada: shmget Criao de memria: Sintaxe:


int shmget(key_t key, int size, int IPC_CREAT | shmflg);

Descrio: o processo que chama esta primitiva cria um segmento de memria compartilhada de tamanho size com a chave key e as permisses de acesso em shmflg. O parmetro IPC_CREAT determina a criao de segmentos de memria. O uid e gid da memria so o uid e o gid efetivos do usurio dono do processo.

Gerncia de Processos Unix - Memria Compartilhada


Retorno: Sucesso: identificador da memria compatilhada. Este identificador ser utilizado para o attach Erro: -1. Obteno de memria: Sintaxe:
int shmget(key_t key, int size, int shmflg);

Descrio: o processo que chama esta primitiva obtem o segmento de memria compartilhada de tamanho size com a chave key e as permisses de acesso em shmflg. Retorno: Sucesso: identificador da memria compatilhada. Este identificador ser utilizado para o attach Erro: -1.

Gerncia de Processos Unix - Memria Compartilhada


Mapeamento de memria:shmat Sintaxe:
char *shmat(int shmid, char *shmaddr, int shmflg);

Descrio: o processo que chama esta primitiva mapeia o segmento de memria compartilhada shmid no endereo shmaddr de seu espao de endereamento.
parmetros: shmid: descritor de memria compartilhada obtido no shmget. shmaddr: endereo no qual o segmento de memria ser mapeado. Se shmaddr for 0, o endereo de mapeamento selecionado pelo sistema. shmflg: determina o modo de acesso memria compartilhada (read_only ou read/write).

Retorno: Sucesso: endereo do segmento de memria compartilhada Erro: -1.

Gerncia de Processos Unix - Memria Compartilhada


Unmapping de memria:shmdt Sintaxe:
int shmdt(int shmid);

Descrio: o processo que chama esta primitiva desfaz o mapeamento do segmento de memria compartilhada shmid. A partir do shmdt, o processo no tem mais acesso ao segmento. Deve fazer um novo attach para acess-lo de novo. Retorno: Sucesso: 0 Erro: -1. Remoo de memria:shmctl Sintaxe:
int shmctl(int shmid, IPC_RMID, struct shmid_ds *buf);

Descrio: o processo que chama esta primitiva remove o segmento de memria compartilhada shmid. A partir deste momento, nenhum processo possui mais acesso a este segmento. S o dono ou o superusurio podem remover segmentos. Retorno: Sucesso: 0 Erro: -1.

Gerncia de Processos Unix - Memria Compartilhada - Exemplo


#include<sys/types.h> #include<sys/ipc.h> #include<sys/shm.h> main() { int pid, idshm, estado; struct shmid_ds buf; int *pshm; /* cria memoria*/ if ((idshm = shmget(0x1223, sizeof(int), IPC_CREAT|0x1ff)) < 0) { printf("erro na criacao da fila\n"); exit(1); } /* cria processo filho */ pid = fork(); if (pid == 0) { /* codigo do filho */ pshm = (int *) shmat(idshm, (char *)0, 0); if (pshm == (int *)-1) { printf("erro no attach\n"); exit(1); } printf("vou escrever\n"); *pshm = 334; exit(0);

/* codigo do pai */ pshm = (int *) shmat(idshm, (char *)0, 0); if (*pshm == -1) { printf("erro no attach\n"); exit(1); } sleep(1); printf("pai - numero lido = %d\n", *pshm); wait(&estado); exit (0); }

Gerncia de Processos Unix - Semforos

Os semforos so utilizados para delimitar uma seo crtica, onde somente um processo executar de cada vez. So uma maneira de estabelecer uma certa ordem na execuo dos processos. Os semforos no Unix foram implementados de maneira extremamente flexvel e, por esta razo, as primitivas resultantes so de grande complexidade. Os semforos so estruturas de dados sobre as quais so executadas operaes indivisveis. Passos para a utilizao de semforos: Criao de um conjunto de semforos, que ser identificado por semid. Obteno do identificador do semforo, verificados todos os problemas de permisso de acesso Execuo de operaes sobre os semforos. Estas operaes so na verdade um conjunto de operaes definidas pelo programador que sero executadas de maneira indivisvel. Remoo do identificador do semforo. Os semforos so tambm permanentes, ou seja, necessitam de uma remoo explcita.

Gerncia de Processos Unix - Semforos


Includes necessrios:
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h>

Primitiva de criao e obteno de um conjunto de semforos: semget Criao de semforos: Sintaxe:


int semget(key_t key, int nsems, int IPC_CREAT | semflg);

Descrio: o processo que chama esta primitiva cria um conjunto de nsems com a chave key e as permisses de acesso em shmflg. O parmetro IPC_CREAT determina a criao de segmentos de memria. O uid e gid da memria so o uid e o gid efetivos do usurio dono do processo. Obteno de semforos: Sintaxe:
int semget(key_t key, int nsems, int shmflg);

Descrio: o processo que chama esta primitiva obtem o conjunto de nsems semforos com a chave key e as permisses de acesso em shmflg. Retorno: Sucesso: identificador do conjunto de semforos. Erro: -1.

Gerncia de Processos Unix - Semforos


Operaes sobre os semforos: Sintaxe:
int semop(int semid, struct sembuf *sops, int nsops);

Descrio: esta primitiva executa indivizivelmente um conjunto de operaes sobre um conjunto de semforos identificados por semid. So executadas nsops operaes sobre os semforos. As operaes esto descritas na estrutura sembuf, que contem os seguintes campos:
short sem_num /* numero do semforo */ short sem_op /* tipo da operao */ short sem_flg /*flags */ se sem_op < 0: se o valor do semforo for maior ou igual ao valor absoluto de sem_op, sem_val = sem_val - |sem_op|. Caso contrrio, se sem_flg for diferente de IPC_NOWAIT, o processo fica bloqueado. se semop = 0: se o valor do semforo for 0, retorna; seno fica bloqueado, se sem_flg for diferente de IPC_NOWAIT. se semop > 0: o valor de semop somado ao valor do semforo.

Retorno: Sucesso: 0 Erro: -1.

Gerncia de Processos Unix - Semforos


Remoo de um conjunto de semforos:semctl Sintaxe:
int semctl(int shmid, int semnum, int IPC_RMID, union semun { val; struct semid_ds *buf; ushort *array; }arg; shmid_ds *buf);

Descrio: o processo que chama esta primitiva remove o conunto de semforos identificado por semid. S o dono ou o superusurio podem remover semforos. Retorno: Sucesso: 0 Erro: -1.

Gerncia de Processos Unix - Semforos Exemplo


#include<errno.h> #include<sys/types.h> #include<sys/ipc.h> #include<sys/sem.h> struct sembuf operacao[2]; int idsem; int p_sem() { operacao[0].sem_num = 0; operacao[0].sem_op = 0; operacao[0].sem_flg = 0; operacao[1].sem_num = 0; operacao[1].sem_op = 1; operacao[1].sem_flg = 0; if ( semop(idsem, operacao, 2) < 0) printf("erro no p=%d\n", errno); } int v_sem() { operacao[0].sem_num = 0; operacao[0].sem_op = -1; operacao[0].sem_flg = 0; if ( semop(idsem, operacao, 2) < 0) printf("erro no p=%d\n", errno); }

Gerncia de Processos Unix - Semforos Exemplo

main() { int pid, estado; int *psem; /* cria semaforo*/ if ((idsem = semget(0x1223, 1, IPC_CREAT|0x1ff)) < 0) { printf("erro na criacao do semaforo\n"); exit(1); } /* cria processo filho */ pid = fork(); if (pid == 0) { /* codigo do filho */ p_sem(); printf("filho - obtive o semaforo\n"); v_sem(); printf("filho - liberei o semaforo\n"); exit(0); } /* codigo do pai */ p_sem(); printf("pai - obtive o semaforo\n"); v_sem(); printf("pai - liberei o semaforo\n"); wait(&estado); exit (0); }

Gerncia de Processos Unix - Tratamento de Sinais


Os sinais so interrupes que chegam assincronamente aos processos. No momento de recepo de um sinal tratvel, a execuo do programa desviada para a rotina de tratamento de sinais. Ao final da rotina de tratamento de sinal, o programa volta instruo imediatamente posterior quela que estava sendo executada quando o sinal foi recebido.

rotina de tratamento

recepo de sinal

a=1; b=2; c=20; d=c+b; e=a+b;

Gerncia de Processos Unix - Tratamento de Sinais


Sinais do Unix: SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGABRT SIGEMT SIGFPE SIGKILL ignored) SIGBUS SIGSYS SIGPIPE to read it SIGALRM SIGTERM SIGURG SIGSTOP ignored) SIGTSTP SIGCONT SIGCHLD SIGTTIN terminal SIGTTOU terminal SIGIO 1 2 3 4 5 6 7 hangup interrupt quit illegal instruction trace trap abort (generated by abort(3) routine) emulator trap

8 arithmetic exception 9 kill (cannot be caught, blocked, or 10 bus error 12 bad argument to system call 13 write on a pipe or other socket with no one 14 15 16 17 18 19 20 21 alarm clock software termination signal urgent condition present on socket stop (cannot be caught, blocked, or stop signal generated from keyboard continue after stop child status has changed background read attempted from control

SIGSEGV 11 segmentation violation

22 background write attempted to control 23 I/O is possible on a descriptor

Gerncia de Processos Unix - Tratamento de Sinais

SIGIO 23 I/O is possible on a descriptor SIGXCPU 24 cpu time limit exceeded SIGXFSZ 25 file size limit exceeded SIGVTALRM 26 virtual time alarm SIGPROF 27 profiling timer alarm SIGWINCH 28 window changed SIGLOST 29 resource lost SIGUSR1 30 user-defined signal 1 SIGUSR2 31 user-defined signal 2

A maioria destes sinais possui tratamento default dado pelo sistema. A maioria dos sinais causa o trmino do processo que o recebe, se a ao default for mantida. Com exceo dos sinais sigkill e sigstop, todos os outros sinais podem receber um tratamento diferente do default. Os sinais SIGUSR1 e SIGUSR2 no possuem ao prdefinida e so usados para enviar interrupes entre processos de usurio.

Gerncia de Processos Unix - Tratamento de Sinais

Primitiva de especificao da rotina de tratamento de sinais: sigvec Como a chamada sigvec muito complexa, foi definida uma funo C mais simples e porttil: signal Rotina signal: Sintaxe:
#include <signal.h> void (*signal(sig, func))() void (*func)();

Descrio: A rotina signal determina que a funo func ser executada quando o sinal sig for recebido. A funo func pode ser SIG_DFL, SIG_IGN ou uma funo qualquer fornecida pelo usurio. Retorno: Sucesso: retorna a ao tomada anteriormente Erro : -1

 Ateno: Se o sinal for recebido quando uma operao de I/O estiver sendo executada (arquivos, pipes, filas, semforos), a operao no executada at o final e retorna o erro EINTR.

Gerncia de Processos Unix - Tratamento de Sinais

Primitiva de envio de sinais: kill Sintaxe:


#include <signal.h> int kill (pid_t pid, int sig);

Descrio: O processo que executa o kill envia o sinal sig ao processo de pid pid. Se sig for igual a 0, o kill testa somente a existncia do processo de pid pid. Se pid for -1 e o processo for de usurio, o sinal enviado a todos os processos com uide do usurio. No caso de superusurio, o sinal enviado a todos os processos do sistema. O processo pode mandar sinal para ele prprio Retorno: 0: sucesso -1: erro

Gerncia de Processos Unix - Tratamento de Sinais - Exemplo


Exemplo 1: recepo e envio de sinais
#include <signal.h> void funcao_sigusr1() { printf("recebi sigusr1\n"); } void funcao_sigusr2() { printf("recebi sigusr2\n"); } main() { signal(SIGUSR1, funcao_sigusr1); signal(SIGUSR2, funcao_sigusr2); kill(getpid(), SIGUSR1); kill(getpid(), SIGUSR2); }

Exemplo 2: tratamento de excees


#include <signal.h> void funcao_sigsegv() { printf("recebi segment fault. Vou morrer!!!\n"); exit(1); } main() { char *p; signal(SIGSEGV, funcao_sigsegv); /* vou forcar um segment fault */ printf("%s", *p); }

Gerncia de Processos Unix - Funes Relacionadas ao Tratamento de Sinais


Funo: alarm Sintaxe: unsigned int alarm(unsigned int seconds) Descrio: envia o sinal SIGALARM ao processo que o chamou depois de seconds segundos. alarm(0) cancela os alarms pendentes. Retorno: tempo que faltava para o alarm anterior. Funo: pause Sintaxe: int pause( ) Descrio: pra o processo at que um sinal seja recebido. Retorno: Sucesso: no retorna. Erro: -1. Sintaxe: int sleep( unsigned seconds) Descrio: suspende a execuo do processo por no mnimo seconds segundos. Retorno: Sucesso: 0. Se o sleep retornar por recepo de sinal, retorna o nmero de segundos que o processo deixou de dormir.

Gerncia de Memria Unix


Nas verses mais modernas do Unix, utilizado o mecanismo de paginao por demanda para a gerncia da memria. Para rodar, um processo necessita unicamente que sua tabela de pginas esteja em memria. A tabela de pginas do Unix uma tabela invertida, por isso tambm chamada mapa de memria.

Tipos de tabela de pgina:


forward-mapped: faz o mapeamento direto endereo virtual -> endereo real invertida: faz o mapeamento inverso (real -> virtual). Como ns temos somente o endereo virtual, temos que aplicar uma funo de hash, que nos retorna um conjunto de endereos reais possveis. O endereo que corresponde ao mapeamento obtido por comparao neste conjunto. Uma entrada na tabela de pginas possui: ndice da prxima entrada, ndice da entrada anterior, nmero do bloco no disco, nmero do disco, prximo endereo de hash, ndice na tabela de processos, base dos segmentos de cdigo, dados e pilha,nmero da pgina dentro do segmento, bits de controle, etc.

Gerncia de Memria Unix

Imagem da memria:
page frame n ... page frame 1 page frame 0 page table

kernel

Imagem do processo:

pilh a

bs s dado

break

Cdigo s

Gerncia de Memria Unix - Implementao


A gerncia de memria no Unix implementada basicamente por trs processos: o gerente de page fault, o swapper e o paginador (substituidor de pginas). O gerente de page faults contactado toda vez que uma exceo do tipo page fault ocorre. Ele o responsvel por encontrar uma entrada livre na tabela de pginas e carregar a pgina que gerou o page fault em memria. O tratamento de page fault uma operao demorada (da ordem do milisegundo). Para melhorar o desempenho do tratamento do page fault, utilizado o processo paginador que roda em background. O swapper responsvel por colocar e retirar processos da memria. Processo paginador: executa periodicamente (a cada 250ms) e verifica o estado da ocupao da memria. Se houverem muito poucas page frames livres, o paginador tira algumas pginas da memria, liberando assim os page frames (algoritmo de substituio). Assim, diminui a probabilidade de execuo do algoritmo de substituio no momento do tratamento do page fault. Esquema de funcionamento: varivel min: sempre que a utilizao da memria cai abaixo de min, o paginador roda. varivel max: o paginador roda at que existam max molduras livres

Gerncia de Memria Unix - Implementao

Algoritmo de substituio de pginas: global: escolhe a pgina independente do processo que a possui o algoritmo utilizado o algoritmo do relgio com duas passagens. Primeira passagem: zera o bit de utilizao. Segunda passagem: as pginas que ainda tiverem o seu bit de utilizao zerado so movidas para a lista de espao livre, mantendo o seu contedo. Quando h um page fault, uma das pginas da lista de espao livre escolhida. Se uma das pginas contidas na lista de espao livre for referenciada, ela sai da lista de espao livre. Se o sistema notar que o paginador est constantemente liberando pginas, o swapper contactado para remover processos da memria.

Gerncia de Memria Unix - Implementao


Processo swapper: Responsvel pelas operaes de swap in e swap out swap out: se existir processo ocioso por mais de 20 segundos, remove da memria. Se no houver, examina os 4 maiores processos. O que estiver h mais tempo na memria removido. Repete a operao at que o limite seja atingido. swap in: calcula a prioridade dinmica dos processos swapped out. Os processos que foram removidos h mais tempo so carregados em memria (swap in). O algoritmo usado evita o movimento de processos muito grandes. Chamadas de sistema: Rotina: brk Include necessrio: #include<sys/types.h> Sintaxe: int brk (caddr_t addr) ou caddr_t sbrk(int incr) Descrio: As duas rotinas setam o endereo mais baixo do segmento de dados. Com brk, o prprio programador deve especificar o novo endereo. Com sbrk, o programador especifica o nmero de bytes adicionais que ele quer para o seu segmento.

Gerncia de Arquivos Unix Sistema de Arquivos Unix tradicional


nomes de arquivos: 14 caracteres Estrutura do sistema de arquivo no disco:

boot super i-nodos bloco

blocos de dados

Bloco de boot: no usado pelo sistema de arquivos Super-bloco (bloco 1): contem informaes sobre o sistema de arquivos: nmero de i-nodos, nmero de blocos, ponteiro para a lista de blocos livres. i-nodos: cada i-nodo descreve um arquivo (64 bytes). Contem informaes gerais (dono, proteo) e a localizao do arquivo no disco. diretrio: conjunto de entrada de 16 bytes (nome do arquivo + nmero do i-nodo)

Gerncia de Arquivos Unix - Sistema de Arquivos Tradicional


Tabela de descritores de arquivo (por processo) Tabela de descrio de arquivos abertos posio &i-nodo posio &i-nodo

modo #ligaes uid / gid tamanho tempos de acesso 256 256 256 & 10 primeiros blocos indireto simples indireto duplo indireto triplo

A primitiva de leitura de um arquivo necessita de um descritor de arquivo. Com este descritor, acessa-se a tabela de descritores e desta tabela acessa-se a tabela de descries. L temos o ponteiro para o i-nodo. No i-nodo, compara-se a posio corrente do arquivo com os endereos dos 10 primeiros blocos (acesso direto). Se a posio corrente no cair l, o acesso deve ser

indireto de um, dois ou trs nveis.

Gerncia de Arquivos Unix - Sistema de Arquivos Rpido (Berkeley)


Nome do arquivo: 255 caracteres O disco dividido em grupos de cilindros, cada qual com o seu superbloco, i-nodos e blocos de dados. Objetivo -> reduzir o tempo de seek. Dois tamanhos de bloco: blocos grandes e blocos pequenos. Os arquivos grandes usam um pequeno conjunto de blocos grandes.

transferncia eficiente de arquivos grandes

eficincia no armazenamento de arquivos pequenos (pouca perda de espao em disco) e de arquivos grandes (diretrio)

A maioria dos sistemas Unix modernos usa esse sistema de arquivo

Entrada/Sada no Unix
Os dispositivos de E/S no Unix so tratados como arquivos => arquivos especiais. Cada dispositivo de E/S possui um driver de dispositivo, localizado no diretrio /dev, que dependente do hardware. Dois tipos de arquivos especiais: bloco e caracter. Arquivo especial de bloco (e.g. disco): com o bjetivo de aumentar o desempenho, usa uma cache entre o sistema de arquivos e o driver. A cada 30 segundos (tempo configurvel), escreve os blocos modificados no driver. O bloco modificado pode ser escrito antes no caso de cache full.
usurio sistema de arquivo buffer cache

drivers

disco

Entrada/Sada no Unix

Arquivos especiais de caracter (e.g. terminal): Os arquivos a caracter manipulam a estrutura de dados chamada lista-C. Cada elemento desta lista um pequeno bloco de at 64 caracteres, um contador e um ponteiro para o prximo. Os dados digitados no terminal so filtrados de acordo com disciplinas de linha. So produzidos assim o conjunto de caracteres processado, que ser entregue ao processo.

/dev/tty (6)

(1) (5) lista-C

disciplinas de linha (3) driver (2) (4)

Primitivas Unix de Manipulao de arquivo


Criao de arquivos: creat (obsoleta) Criao e abertura de arquivos: open Includes necessrios: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> Sintaxe: int open( char *path, int flags, [mode_t mode]) Descrio: A primitiva cria o arquivo de nome path, se este no existir, se for especificado O_CREAT em flags. O arquivo criado ter as permisses de acesso descritas em mode. O arquivo criado imediatamente aberto. A operao de abertura de arquivo adiciona uma entrada na tabela de arquivos do processo. O modo de abertura do arquivo est descrito em flags e pode ser:
O_RDONLY, O_WRONLY, O_RDWR, O_NDELAY e O_NONBLOCK (usado para pipes e linhas de comunicao), O_SYNC( a escrita s retorna quando o registro tiver sido escrito no disco), O_APPEND, O_EXCL (usado em conjunto com O_CREAT, para retornar erro se o arquivo j existir)

Retorno:
Sucesso: descritor do arquivo aberto Erro: -1

Exemplo:
fd = open(arquivo, O_RDWR | O_CREAT | O_EXCL, 0x666);

Primitivas Unix de Manipulao de arquivo


Fechamento de arquivos: close Sintaxe: int close (int fd) Descrio: A primitiva close deleta o descritor de arquivos fd da tabela de arquivos do processo. Retorno:
Sucesso: 0 Erro: -1

Leitura e escrita de arquivos: sintaxe descrita na parte do curso referente a pipes. Mudana de diretrio corrente: chdir Includes necessrios: #include <sys/stat.h> Sintaxe: int chdir (char *path) Descrio: A primitiva chdir muda o diretrio corrente para path. Retorno:
Sucesso: 0 Erro: -1

Mudana de modo: chmod Sintaxe: int chmod (char *path, int mode) Descrio: A primitiva chmod muda modo do arquivo path para mode. Retorno:
Sucesso: 0 Erro: -1

Primitivas Unix de Controle de I/O


Nos sistemas Unix tradicionais, o controle de I/O para os arquivos especiais feito por uma nica chamada ao sistema(ioctl). Assim, usamos a mesma chamada para, por exemplo, alterar a blocagem de transferncia de dados entre disco e memria e para alterar a velocidade de um terminal. O padro POSIX aboliu esta chamada e criou um conjunto enorme de outras, especficas a cada funo. Rotina: ioctl Sintaxe:
int ioctl (int fd, int request, caddr_t arg)

Descrio:
A primitiva ioctl executa a funo request no arquivo especial descrito por fd. Se forem necessrios parmetros adicionais, eles devem ser fornecidos em arg. A funo request dependente do hardware e descrita no manual do dispositivo.

Retorno:
Sucesso: != -1 Erro: -1

Exemplo de chamadas POSIX:


Setar atributos de um terninal: int tcsetattr(fd, opt, &termio); Setar a velocidade de entrada: int ofsetospeed (&termio, int speed);

A maioria dos usurios Unix continua a usar ioctl

Você também pode gostar