Академический Документы
Профессиональный Документы
Культура Документы
ao significado
do valor de retorno desta funo.
2)
Pretende-se implementar, usando a API POSIX, um servidor que permita consultar pginas
de texto
remotamente. As pginas sero visualizadas partir do programa cliente que implementa as
seguintes
funcionalidades: a) Envio do nome do ficheiro a visualizar; b) Impresso no ecr do
contedo do ficheiro.
O cdigo do cliente o seguinte:
int main(int argc, char *argv[]) {
char buf[BUFSIZE];
int s, ssize;
struct sockaddr_in name;
struct hostent* hostinfo;
name.sin_family = AF_INET;
hostinfo = gethostbyname (argv[1]);
name.sin_addr = *((struct in_addr *) hostinfo->h_addr);
name.sin_port = htons (4000);
while(1) {
printf("Nome do ficheiro: "); fflush(stdout);
fgets(buf, BUFSIZE, stdin);
formata_string(buf, &ssize);
s = socket (PF_INET, SOCK_STREAM, 0);
connect(s, (struct sockaddr *) &name, sizeof (struct sockaddr_in));
write(s, buf, ssize);//envia-se nome, incluindo o '\0'
FILE *fps = fdopen(s,"r");
copy_stream(fps,stdout);
fclose(fps);
}
}
void copy_stream(FILE *src, FILE *dest) {
int ch;
while((ch=fgetc(src))!=EOF)
fputc(ch, dest);
}
void formata_string(char *buf, int *ssize){
*ssize=strlen(buf);
if(buf[*ssize-1]=='\n') //vamos eliminar o '\n', caso exista
buf[*ssize-1]='\0'; //'\n' substitudo pelo novo '\0'
else //caso no exista, aumentamos ssize, para contar o '\0' original
2c) (1.5) Altere o servidor de forma a que este possa atender vrios pedidos de cada vez
(servidor multitarefa).
7. a) (2.5%) Indique uma vantagem das aplicaes multi-processo (i.e., com utilizao da
funo fork) face s
aplicaes multi-thread.
}
Indique uma possvel sucesso de mensagens impressas no ecr aps a execuo deste
programa,
assumindo que no existem interferncias de outros processos no sistema. Justifique
sucintamente.
Assuma que o identificador do processo inicial 2000 e que o(s) novo(s) processo(s)
toma(m) o(s)
valor(es) seguinte(s).
Resoluo
1) A funcao fork() permite que um programa possa criar um novo processo. O novo
processo tem uma
copia do codigo e dos dados do programa original e continua a execucao a partir da
funcao fork(). O
valor de retorno da funcao fork() e essencial neste processo pois permite que o
programa verifique se
ainda esta no processo original (neste caso o valor de retorno do fork() e um valor
maior do zero, o pid
do novo processo) ou no novo processo (neste caso o valor de retorno do fork() e
zero).
que o processo receber o sinal de um dos processos filho (indicando assim a sua
terminao), a
funo sigchld_handler ser automaticamente executada, evitando assim que o processo
filho se torne
um zombie.
casos, o processo inicial ter que aguardar (atravs da funo waitpid()*) que o
processo filho criado no
ciclo anterior termine antes de poder criar o novo processo para execuo da funo
finish_work().
Desta forma, possvel ter a funo begin_work() de um novo ciclo a ser executado
concorrentemente
com a funo finish_work() do ciclo anterior.
*Nota: havia uma gralha no enunciado do exame, tendo aparecido wait em vez de
waitpid. No afecta a
resposta.
7a) O facto de haver um erro que leve terminao de um dado processo no causa a
terminao de toda
aplicao. Isto pode ser especialmente til na implementao de servidores. No caso
das aplicaes multithread,
uma vez que todas as threads pertencem ao mesmo processo, um erro numa delas causa a
terminao do
processo e, por consequncia, de todas as threads.
8: Quando qualquer um dos seus processos filho muda de estado, i.e., quando terminam,
quando so parados
ou quando so continuados (isto , quando sai do estado parado). Nota:
possvel configurar a disposio
do sinal de forma a s receber o SIGCHLD devido a terminaes de processos filho
(SA_NOCLDSTOP).
2000: 9 19
2001: 9 18
2000: 8 17
Aps a criao do novo processo (fork()), o processo inicial entrar no ciclo while
(linha 25), ir decrementar o
valor do semforo sem1 (que se encontra a 1) e faz a primeira impresso. De seguida,
inicia uma nova iterao
do ciclo, encontrando sem1 a zero, o que o far aguardar na chamada funo
sem_wait (linha 27).
Entretanto, o novo processo, que se encontrava bloqueado na linha 16 (sem_wait com
sem2 a 0),
desbloqueado pela instruo da linha 31 (executada pelo processo inicial), atualiza
a sua cpia da varivel i
(de 20 para 19), decrementa o valor guardado na memria partilhada (linha 17), causa
a segunda impresso
apresentada acima, incrementa o valor do semforo sem1 e termina (linha 22). O
incremento de sem1
desbloqueia o processo inicial que, desta forma, executa uma nova iterao do ciclo
while, com a
correspondente impresso dos valores de i e de b, sendo que esta ltima varivel
reflete a alterao feita no
processo filho, uma vez que estava armazenada em memria partilhada por ambos os
processos.
11)
2000: 1
2001: 0
2001: 1
O novo processo fica bloqueado na funo sem_wait (valor inicial do semforo a 0) at que o processo
inicial faa o sem_post. A
pausa de 2 segundos d oportunidade ao processo inicial de executar primeiro o seu printf e terminar.
Passados cerca de 2
segundos, o processo filho executa o printf da linha 11, incrementa o valor de i (que havia sido herdado
a 0, valor na altura do
fork) na linha 15, faz o printf da linha 17 e termina.