Buscar

03-Processos-Part2

Prévia do material em texto

1 SO II 2-B 1 SO II 2-B 
2.4 Problemas clássicos de IPC 
 
2.4.1 O jantar dos filósofos 
 
Em 1965, Dijkstra propôs e resolveu um problema de sincronização 
que ele chamou de Jantar dos Filósofos. 
Desde então, toda vez que alguém inventa uma nova primitiva deve 
apresentar uma demonstração de como ela pode ser usada para 
resolver este problema. 
O sistema é bastante simples: 
 
 
5 filósofos estão sentados ao redor de uma mesa, cada um com um 
prato de macarrão a sua frente. Entre cada 2 filósofos existe um 
garfo. Os filósofos podem estar em um de dois estados possíveis: 
pensando ou comendo. Para comer o macarrão, o filósofo precisa de 
dois garfos. 
Quando um filósofo fica com foem, ele tenta obter dois garfos. Se 
conseguir, ele pode comer. Se um ou os dois garfos não estiverem 
disponíveis (estão com algum outro filósofo), é preciso esperar. 
Uma solução óbvia é esta: 
 
 
 
Infelizmente, esta solução não funciona. 
Suponha que todos os 5 tentem pegar o garfo esquerdo 
simultaneamente. Nenhum deles poderá pegar o garfo direito e 
temos um deadlock. 
 
Uma tentativa de melhorar esta solução é colocar um teste no 2
o
. 
take_fork. Se ele não estiver disponível, o 1
o
. garfo é solto. 
Isso também não funciona. 
2 SO II 2-B 2 SO II 2-B 
Suponha que todos peguem o garfo da esquerda. Testando o da 
direita, todos verificam que ele não está presente e soltam o 1
o
. em 
seguida, todos tentam novamente resultando num impasse. 
Esta situação é chamada de starvation. 
 
Uma outra possibilidade é que os processos esperem um período de 
tempo aleatório antes de tentar de novo. A chance de dois processos 
escolherem o mesmo período é bem menor. Há aplicações que 
funcionam dessa forma (p. ex.: Ethernet). 
Porém, algumas aplicações podem precisar de uma solução que 
funcione sempre (p. ex.: controle de usina nuclear!). 
 
Uma solução que não possui deadlocks nem starvation é proteger os 
5 comandos que seguem a chamada think() com um semáforo 
binário. Antes de tentar pegar o primeiro garfo, o processo chama 
um down sobre mutex. Depois de soltar os garfos, o processo chama 
um up. 
Esta solução tem um problema prático: apenas um processo pode 
comer por vez. Com 5 processos, pelo menos 2 poderiam comer por 
vez. 
 
Uma solução livre de deadlocks e que permite o máximo de 
paralelismo pode ser vista a seguir. 
 
 
2.4.2 Leitores e escritores 
 
Este problema modela o acesso a bancos de dados. 
Com múltiplos processos acessando um BD, é aceitável que vários 
deles possam acessar simultaneamente desde que sejam apenas de 
leitura. Porém, quando um processo acessa o BD para atualização, 
nenhum outro pode acessar simultaneamente, nem mesmo os de 
leitura. 
 
Esse problema apresenta duas possibilidades: 
 Suponha que alguns leitores estão acessando o BD e chega um 
processo de atualização; 
 Este último é bloqueado – enquanto houver processo de leitura, o 
que atualiza ficará esperando indefinidamente; 
 Caso cheguem mais processos de leitura, o que atualiza 
continuará esperando (virtualmente para sempre); 
 Essa situação indica que os processos de leitura têm prioridade 
sobre os de atualização. 
 
Mas pode-se dar prioridade para os processos de atualização: 
 Supondo que o processo de atualização bloqueie a entrada de 
novos processos de leitura; 
 Nesse caso, os processos de leitura atuais eventualmente 
terminarão, liberando o acesso ao processo de atualização. 
 
3 SO II 2-B 3 SO II 2-B 
 
 
 
 
 
2.4.3 O barbeiro dorminhoco 
 
Este problema apresenta a seguinte situação: 
 Há uma barbearia com um barbeiro, uma cadeira de barbeiro e N 
cadeiras de espera; 
 Se não há clientes, o barbeiro senta na cadeira de barbeiro e 
dorme; 
 Quando chega o primeiro cliente, ele acorda o barbeiro, ocupa a 
cadeira e tem o seu cabelo cortado; 
 Caso cheguem outros clientes, eles devem ocupar as cadeiras de 
espera; 
 Por fim, se chega um novo cliente e há alguém sendo atentido 
pelo barbeiro e todas as cadeiras de espera estão ocupadas, ele 
deve deixar o sistema; 
 Quando o barbeiro termina de atender o cliente atual, este sai da 
cadeira e vai embora; 
 Nesse caso, um dos clientes da espera é escolhido; 
 Caso não haja + nenhum, o barbeiro volta a dormir. 
 
Este modelo é semelhante a vários problemas onde se apresenta uma 
fila para acessar algum tipo de serviço. 
4 SO II 2-B 4 SO II 2-B 
 
 
 
 
 
5 SO II 2-B 5 SO II 2-B 
2.5 Escalonamento de Processos 
 
Scheduler: 
 Há situações em que mais de um processo têm condições de 
execução em um momento; 
 Deve-se decidir qual deles vai tomar posse do processador; 
 Quem toma essa decisão é o Scheduler (Escalonador). 
 
Num sistema batch, temos o algoritmos mais simples de 
escalonamento. 
 
 
 
 
 
 
 
 
 
 Um job é lido da unidade de fita; 
 O job é carregado na memória e executa até o fim; 
 Quando um job termina, o sistema carrega outro. 
 
Num sistema timesharing multi-usuário, o algoritmos é bem mais 
complexo: 
 
 Pode haver vários processos prontos; 
 Vários usuários esperam que suas tarefas sejam completadas; 
 Há processos rodando em background (ex.: mail). 
Objetivos de um algoritmo de escalonamento: 
1. Justiça: cada processo recebe um quantum adequado; 
2. Eficiência: a finalidade do escalonamento é manter a CPU 
ocupada ~100%; 
3. Tempo de resposta: deve ser baixo para os usuários interativos; 
4. Turnaround: o tempo que um processo batch fica no sistema 
deve ser o menor possível; 
5. Throughput: alto número de jobs processados por hora; 
 
Objetivos conflitantes: 
 Usuários interativos x batch; 
 Jobs devem ser rodados entre 0:00 h. e 6:00 h.; 
 A CPU é finita; 
 Se alguém é favorecido, outro é prejudicado; 
 Síndrome do “cobertor curto”; 
 
Elementos complicadores: 
 Processos são únicos; 
 Como as pessoas, cada um possui uma “personalidade” diferente 
dos demais; 
 Há processos que sempre estão esperando I/O (I/O bound), 
enquanto outros usam a CPU por horas (CPU bound); 
 O comportamento de um processo é imprevisível. 
 
Relógio = Auxiliar do processador no controle de tempo. 
 
Interrupção por tempo: 50 ou 60 Hz. O relógio interrompe o 
processador 50 ou 60 vezes por segundo. 
Tick: período entre uma interrupção por tempo e a seguinte. 
 
 
 
 
Unidade de 
Fita 
 
 
 
Computador 
Job 
6 SO II 2-B 6 SO II 2-B 
Preempção: suspensão temporária de um processo que poderia 
continuar executando. O processo deixa o processador e fica numa 
fila de processos “prontos para executar”. 
Um sistema preemptivo é o contrário de um sistema batch “rodar até 
o fim” (não preemptivo). 
 
Objetivos de todos os sistemas: 
 Justiça; 
 Política seguida por todos; 
 Balanceamento equilibrado. 
 
Para sistemas batch: 
 Maximizar o throughput (jobs por hora); 
 Minimizar o turnaround (tempo entre submissão e término); 
 Manter a CPU ocupada o máximo de tempo. 
 
Para sistemas interativos: 
 Minimizar o tempo de resposta; 
 Dar tratamento proporcional a todos os usuários. 
 
Para sistemas de tempo real: 
 Atender aos deadlines – evita a perda de dados; 
 Evitar a degradação de sistemas multimídia. 
 
2.5.2 Escalonamento em sistemas batch 
 
First-Come First-Serve (FCFS) 
 
O método mais simples. 
Os processos ocupam a CPU na ordem em que entram no sistema. 
Método da fita de jobs (ou leitora de cartões perfurados). 
Fácil de programar e de entender. 
Com multiprogramação, toda vez que o processo em execução 
bloqueia (p. ex. I/O), o próximo da fila é executado. Quando um 
processo bloqueado torna-se pronto, vai para o fim da fila. 
A desvantagem desse sistema é não reconhecer a diferença entre 
processos CPU bound e I/O bound. 
 
Menor job primeiro 
 
 A maioria dos algoritmos é projetada para sistemas interativos; 
 Este é um algoritmo projetado para jobs batch onde o tempo de 
execução é conhecido. 
 
Ex.: Considere uma companhiade seguros em que os jobs possuem 
certas quantidades de solicitações por parte dos clientes. 
 O tratamento de uma solicitação é conhecido, portanto o tempo 
de execução do job pode ser determinado. 
 
 4 jobs, A, B, C e D; tempo de execução de 8, 4, 4 e 4 minutos, 
respectivamente. 
 Rodando os jobs nesta ordem, obtemos turnarounds de 8, 12, 16 
e 20 minutos - média de 14 minutos. 
 Com menor job primeiro, obtemos 4, 8, 12 e 20 - média de 11 
minutos. 
O motivo é fácil de verificar. Ex.: 
 4 jobs com tempo de execução de a, b, c e d, respectivamente; 
 O job 1 termina no tempo a; 
 O job 2 termina no tempo a + b; 
7 SO II 2-B 7 SO II 2-B 
 O job 3 em a + b + c; 
 O job 4 em a + b + c + d; 
 A média é (4a + 3b + 2c + d)/4; 
 O job 1 contribui com 4 vezes o seu tempo para a média. 
 
Este algoritmo pode ser usado para sistemas interativos, 
considerando um job uma requisição. Basta conhecer os tempos de 
execução das requisições. 
 
 
 
Próximo menor tempo restante 
 
Uma variação do Menor Job Primeiro é este método, que dá 
preferência para o job que possui o menor tempo restante de 
execução. 
O tempo de execução deve ser conhecido antecipadamente. 
Novos jobs podem suspender o processo em execução caso seu 
tempo restante seja menor. 
 
Escalonamento em 3 níveis 
 
Até agora, tem-se assumido que a memória é suficiente para todos os 
processos prontos do sistema. 
Se a memória for insuficiente, é preciso manter alguns processos em 
disco. 
Implicações: o tempo para trazer um processo do disco para a 
memória e vice-versa é algumas ordens de magnitude maior do que 
uma troca de contexto. 
O escalonador escolhe quem roda e quem vai para disco ou quem 
fica na memória. 
Processos novos ainda passam por uma fila de admissão. 
 
Critérios: 
1. Quanto tempo faz desde o último swap? 
2. Quanta CPU o processo consumiu? 
3. Qual é o tamanho do processo (os pequenos não precisam passar 
por isso)? 
4. Qual é a prioridade? 
 
 
 
 
8 SO II 2-B 8 SO II 2-B 
2.5.3 Escalonamento em Sistemas Interativos 
 
 Escalonamento Round Robin 
 
 
 
 Cada processo recebe um quantum: período de tempo em que 
ele pode utilizar o processador; 
 No final do quantum, se o processo ainda estiver executando, ele 
sofre preempção e a CPU é entregue ao próximo processo; 
 Caso o processo corrente solicite um I/O e bloqueie, a CPU é 
entregue ao próximo processo. 
Ex.: 
Quantum de 20 ms, troca de contexto de 5 ms (25%) 
Quantum de 500 ms, troca de contexto de 5 ms (1%) 
No caso 1, 25% do tempo da CPU é perdido. 
No caso 2, apenas 1% do tempo da CPU é perdido. Entretanto, com 
10 usuários o 10
o
 poderia ter um tempo de resposta de 5 segundos. 
 
Escalonamento com Prioridades 
 
No método Round Robin, todos os processos são iguais. 
 
Na vida real, quase sempre estamos inseridos em hierarquias: 
 Reitoria, centro, departamento, professor, estudante. 
 
Funcionamento: 
 Cada processo recebe uma prioridade; 
 O processo “pronto” com maior prioridade é aquele que executa. 
 
 Para evitar que um processo execute indefinidamente, o 
escalonador pode reduzir sua prioridade a cada tick; 
 Quando a prioridade do processo atual ficar abaixo da prioridade 
de outro processo pronto, ocorre preempção. 
 Comando nice: um usuário pode reduzir a prioridade de seu 
processo caso ele não seja importante – “legal” para os outros 
usuários (ninguém usa!). 
 
Prioridade dinâmica: 
 Cada processo recebe uma prioridade que representa o inverso da 
fração utilizada de seu quantum; 
 Ex.: se ele utilizar 2 ms de um quantum de 100 ms, sua 
prioridade será 50; 
 Ex.: se usar 50 ms, sua prioridade será 2; 
 Ex.: se 100%, prioridade 1. 
 
Processo I/O bound: 
 Processa para solicitar novo I/O; 
 Este processo deve ter maior prioridade para que suas 
requisições de I/O sejam feitas em paralelo com a execução de 
outros processos; 
 Caso não tenha prioridade, este processo utilizará a memória do 
sistema por muito tempo, consumindo recursos. 
 
 
 
9 SO II 2-B 9 SO II 2-B 
Classes de prioridades: 
 
 
 
 Enquanto houver processos prontos na classe 4, os processos das 
classes abaixo nunca serão executados. 
 
Múltiplas filas 
 
Baseado em exemplo antigo: CTSS, 1962. 
 7094 só podia manter um processo por vez na memória; 
 Os gerentes desse sistema concluíram logo que era mais 
interessante dar um quantum grande aos processos do que dar 
quantuns pequenos e fazer mais operações de swap; 
 Divisão em classes: 
 Classe mais alta = 1 quantum; 
 Classe seguinte = 2 quantuns; 
 Etc. 
 
Ex.: a tarefa de um processo consiste de 100 quantuns. 
 Executa 1 quantum na classe mais alta; 
 Executa 2 quantuns e passa para a classe abaixo; 
 Executa 4, 8, 16 e 32 quantuns; 
 Dos últimos 64, executa apenas 37 e termina; 
 Tudo isso com apenas 6 trocas de contexto + a carga inicial do 
programa. 
 
Próximo Menor Processo 
 
O método de Menor Job Primeiro produz o menor tempo de resposta 
médio para sistemas batch. Se pudéssemos usar um método desse 
tipo para sistemas interativos, teríamos o menor tempo de resposta 
para requisições. 
O problema reside em determinar qual é o tempo necessário para 
processar uma requisição. 
Uma forma de determinar isso é estimar baseado nos tempos 
passados, mas usando pesos, de forma que as medidas + recentes 
sejam mais importantes. 
 
Considere o seguinte exemplo: 
 Uma requisição tem seu tempo estimado em T0; 
 Um novo atendimento determina que o tempo gasto foi T1; 
 Usando uma fórmula de peso a.T0 + (1 – a).T1, para um valor de 
a de ½ podemos obter uma série como segue: 
 
T0, T0/2 + T1/2, T0/4 + T1/4 + T2/2, T0/8 + T1/8 + T2/4 + T3/2 
A técnica de estimar valores em uma série com peso, em que os 
valores mais recentes são + importantes, é chamada de aging 
(envelhecimento). 
 
 
10 SO II 2-B 10 SO II 2-B 
Escalonamento garantido 
 
Abordagem: fazer promessas aos usuários sobre o desempenho do 
sistema - com n usuários, cada um tem garantido a utilização de 1/n 
do tempo de CPU. 
Para alcançar este objetivo, o sistema precisa saber quanta CPU cada 
job do usuário já consumiu desde o login e quanto tempo se passou 
desde o login de cada usuário. 
Com esses valores, pode-se computar a taxa de consumo de CPU por 
usuário. 
Em seguida, o sistema pode fazer a correção da utilização dando 
preferência ao usuário com menor taxa de consumo. 
 
Uma idéia parecida pode ser aplicada em sistemas de tempo real, 
comparando os deadlines que cada processo precisa atender. O 
sistema pode dar preferência ao job com deadline de mais risco de 
ser perdido. 
 
Escalonamento de loteria 
 
Waldspurger e Weihl, 1994: 
 Os processos recebem tickets de loteria para vários recursos, 
inclusive CPU; 
 O escalonador sorteia um ticket ao acaso; 
 O processo que possuir este ticket ganha acesso ao recurso; 
 Cada ticket vale uma certa quantidade do recurso; 
 Processos de mais importância podem receber tickets extras; 
 
Ex.: um período de tempo dividido em 100 tickets. 
Se um processo tiver 20 tickets, tem 20% do tempo. 
A consumação é aleatória. 
 A chance de um processo ser escolhido no sorteio é proporcional 
ao número de tickets que ele possui; 
 Processos cooperativos podem partilhar tickets; 
 
Ex.: um cliente faz uma requisição a um servidor e bloqueia. 
 Ele empresta seus tickets para aumentar a chance do 
servidor ser selecionado; 
 Quando o servidor responder, devolve os tickets ao 
cliente. 
 Método interessante para adequar necessidades de taxas 
diferentes. 
Ex.: vídeo - 10, 20 e 25 frames/segundo. 
 
Escalonamento de compartilhamento justo 
 
Suponha que dois usuários de um sistema tem a mesma prioridade. 
O usuário A executa 9 processos e o usuário B apenas 1. 
Sem outras informações, supondo que os processos sejam todos 
semelhantes, o usuário A vai obter 90% do uso da CPU, enquanto B 
vai ficar com os 10% restantes. 
 
Para evitaresta situação, alguns sistemas verificam a quem pertence 
um processo quando a CPU é alocada. 
 
Considere um usuário 1 com 4 processos: A, B, C e D; e um usuário 
2 com o processo E. 
Um sistema Round Robin que use este método poderia produzir a 
seguinte sequência de alocação: 
 
11 SO II 2-B 11 SO II 2-B 
A E B E C E D E A E B E C E D E ... 
 
Caso haja interesse em dar o dobro de CPU de B para A, a sequência 
seria: 
 
A B E C D E A B E C D E ... 
2.5.4 Escalonamento em Tempo Real 
 
Casos em que uma resposta atrasada é tão ruim quanto nenhuma. 
Exemplos: 
 Conversão dos dados de um CD em música; 
 Monitoramento de pacientes; 
 Piloto automático 
 Controle de um reator nuclear. 
 
Tipos: 
 Hard real time: deadlines rigorosos; 
 Soft real time: perder algum deadline é aceitável; 
 Eventos periódicos ou aperiódicos. 
 
Ex.: um sistema possui m eventos periódicos; o evento i ocorre no 
período Pi e necessita de Ci segundos de tratamento; a carga só pode 
ser manipulada se o sistema atender à regra: 
 
 m Ci 
 -- 1 
i=1 Pi 
 
Um sistema de tempo real que atende este critério é chamado de 
escalonável. 
 
Ex.: 3 eventos com períodos de 100, 200 e 500 mseg 
Tratamento em 50, 30 e 100 mseg. 
Escalonável: 0,5 + 0,15 + 0,2 < 1 
 
Algoritmos de tempo real: 
 Dinâmicos: decisões durante a execução 
 Estáticos: decisões antes da execução 
 
Algoritmos dinâmicos: 
1) Taxa monotônica: Liu e Layland, 1973, clássico 
Prioridade proporcional à freqüência. 
 
Ex.: um processo que roda a cada 20 mseg > PRI 50 
Outro roda a cada 100 mseg > PRI 10 
 
Faz preempção de qualquer processo para rodar o mais alto. 
Algoritmo ótimo! 
 
2) Primeiro deadline primeiro: processos que tratam eventos ficam 
na fila de prontos. 
A fila é classificada por deadline. 
 
3) Menor margem. 
Ex.: tratamento de 200 mseg, deadline de 250 mseg, margem de 50 
mseg 
 
 
12 SO II 2-B 12 SO II 2-B 
Necessidades de tempo real: 
 SO pequeno (microkernel); 
 Tempo de interrupção pequeno; 
 Troca de contexto rápida; 
 Interrupções desabilitadas por pouco tempo; 
 Manuseio de vários timers em mili ou microsegundos. 
2.5.5 Política x mecanismo 
 
 Em algumas situações, um processo pode ter vários filhos. 
 Ex.: um banco de dados, onde cada filho atende uma requisição. 
 O pai, no caso, deve ter uma boa idéia da importância de cada 
um de seus filhos (inclusive se algum deles é crítico). 
 Nenhum dos algoritmos vistos faz perguntas aos processos 
usuários para tomar decisões. Assim, dificilmente fará as 
melhores escolhas. 
 Solução: separar o mecanismo (que fica no kernel) da política (o 
processo de escolha). 
Ex.: no caso do BD, o pai pode definir a prioridade de seus filhos, 
mas o escalonador fará as escolhas quando for necessário. 
2.5.6 Escalonamento de threads 
 
Num sistema de multiplos processos, que admite múltiplas threads, 
há 2 níveis de paralelismo: processos e threads. 
Quando o sistema implementa threads no nível do usuário, o kernel 
não toma conhecimento de sua existência. Ele continua escalonando 
apenas processos. O escalonador interno de cada processo decide 
qual thread deve executar. 
Como não há interrupção por tempo para threads, a thread 
selecionada pode executar indefinidamente. Eventualmente ela usará 
todo o quantum do processo. Nesse caso, o kernel selecionará outro 
processo para execução. 
 
Quando esse processo retomar a CPU, aquela thread continuará sua 
execução até que eventualmente termine. 
Porém, seu comportamento anti-social não afetará outros processos. 
O escalonador do kernel dará a cada um o tempo que ele achar justo, 
independente do que acontece dentro daquele processo. 
 
 
 
Agora, considere que as threads são cooperativas. Nesse caso, a 
situação pode ser a da figura acima. 
 
Por outro lado, quando as threads são implementadas no kernel ele 
escolhe que thread vai executar em determinado momento, 
independente do processo a que pertence. É claro que, se houver 
interesse, o kernel pode considerar esse dado para tomar sua decisão. 
 
13 SO II 2-B 13 SO II 2-B 
A principal diferença entre threads no nível do usuário e no kernel é 
relativo ao desempenho: 
 Fazer uma troca de threads num sistema de threads no nível do 
usuário significa gastar apenas algumas instruções; 
 No nível do kernel, significa uma troca de contexto completa (se 
o processo for diferente), mudar o mapa de memória e invalidar 
o cache, o que é várias ordens de magnitude + lento; 
 Por outro lado, num sistema no nível do kernel o I/O de uma 
thread não bloqueia as demais. 
 
Como o kernel sabe que o custo para a troca de contexto é muito 
alto, ele pode usar essa informação e escolher uma thread do mesmo 
processo em vez de uma thread de um processo diferente (desde que 
seja possível e interessante). 
 
Uma vantagem para threads no nível do usuário é que o escalonador 
interno do processo pode escolher as threads pelo que elas fazem 
(ele sabe!). No nível do kernel, o máximo que é possível fazer é dar 
+ prioridade a uma delas, que será escolhida por causa disso. 
 
 
 
 
 
 
Sockets 
 
Chamadas para os protocolos orientados a conexão: 
 
Server 
 
 
 
 
 
 
 
 
 
 
 Cliente 
 
Bloqueia até estabelecer 
a conexão com o cliente 
 Estabelece conexão 
 
 
 
 requisição 
 
 
Processa requisição 
 
 resposta 
 
Chamadas para os protocolos sem conexão: 
Server 
 
 
socket() 
bind() 
listen() 
accept() 
read() 
socket() 
connect(
) 
write() 
write() 
read() 
socket() 
14 SO II 2-B 14 SO II 2-B 
 
 
 
 Cliente 
 
 
 
 
Bloqueia até receber 
do cliente 
 
 
 
 
Processa requisição 
 
 
 
 
 
sd = int socket (int family, int type, int protocol); 
Family: 
AF_UNIX protocolo interno Unix 
AF_INET protocolo Internet 
AF_NS protocolo Xerox NS 
AF_IMPLINK camada IMP link 
Type: 
SOCK_STREAM stream socket 
SOCK_DGRAM datagram socket 
SOCK_RAW raw socket 
SOCK_SEQPACKET sequenced packet socket 
SOCK_RDM reliably delivered message socket 
 
Protocol = 0 
 
Combinações válidas de family e type: 
 AF_UNIX AF_INET AF_NS 
SOCK_STREAM Sim TCP SPP 
SOCK_DGRAM Sim UDP IDP 
SOCK_RAW IP Sim 
SOCK_SEQPACKET SPP 
 
int bind (int sockfd, struct sockaddr *endereço, int tamanho); 
struct sockaddr { 
 u_short sa_family; /* família de endereços: AF_xxx */ 
 char sa_data[14]; /* até 14 bytes de endereço */ 
}; 
int connect(int sockfd, struct sockaddr * server, int tamanho); 
 
int listen(int sockfd, int backlog); 
 backlog = 5, em geral. 
 
int accept(int sockfd, struct sockaddr * peer, int * tamanho); 
 peer é o cliente. 
int sendto (int sockfd, char * buff, int nbytes, int flags, 
 struct sockaddr * to, int tamanho); 
 
int recvfrom (int sockfd, char * buff, int nbytes, int flags, 
 struct sockaddr * to, int tamanho); 
 
bind() 
recvfrom() 
sendto() 
socket() 
bind() 
sendto() 
recvfrom(
) 
15 SO II 2-B 15 SO II 2-B 
flags = 0 
 
bzero(char * dest, int nbytes);

Continue navegando