Logo Passei Direto
Buscar
Material
páginas com resultados encontrados.
páginas com resultados encontrados.
left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

left-side-bubbles-backgroundright-side-bubbles-background

Crie sua conta grátis para liberar esse material. 🤩

Já tem uma conta?

Ao continuar, você aceita os Termos de Uso e Política de Privacidade

Prévia do material em texto

Computação Concorrente (MAB117) – Prova Suplementar
Prof. Silvana Rossetto – 21 de julho de 2015
1DCC/IM/UFRJ
Questão 1 (2,0 pts) A série abaixo pode ser usada para estimar o valor de π. A função
Serial pi implementa o cálculo dessa série de forma sequencial. (a) Implemente uma
versão concorrente para essa função para dividir a tarefa de estimar o valor de π entre N
threads. Todas as threads deverão executar a mesma função.
π = 4 ∗ [1− 1/3 + 1/5− 1/7 + 1/9− ...]
double Serial_pi(long long n) {
double sum = 0.0; long long i; double factor = 1.0;
for (i = 0; i 0) { wait(); }
17: } catch (InterruptedException e) {}
18: //realiza a escrita de ’str’
19: notify(); //libera outro escritor (caso exista escritor bloqueado)
20: } }
Resp.: (a) Sim, pois os escritores só ficarão bloqueados na variável de condição
quando houver leitores lendo, como o último leitor desbloqueia todos os escritores blo-
queados não há necessidade do notify() na saı́da do método Escrita().
(b) Sim, desde que o notify() da linha 19 seja mantido. Nesse caso, se vários es-
critores ficarem bloqueados na variável de condição porque há leitores lendo, quando o
último leitor sair, ele irá desbloquear apenas um escritor, mas cada escritor irá neces-
sariamente desbloquear outro escritor quando terminar a escrita, garantindo que todos
os escritores bloqueados sejam em algum momento desbloqueados. Isso é possı́vel pois
apenas escritores ficarão bloqueados na fila da variável de condição.
(c)
class LE {
private int leit, escr, escresp;
LE() {
this.leit = 0; //numero de leitores lendo
this.escr = 0; //numero de escritores escrevendo (0 ou 1)
this.escresp = 0; //numero de escritores esperando
}
// Entrada para leitores
public synchronized void EntraLeitor (int id) {
try {
while (this.escr > 0 || this.escresp > 0) {
wait(); //bloqueia se houver escritores esperando ou escrevendo
}
this.leit++;
} catch (InterruptedException e) { }
}
// Saida para leitores
public synchronized void SaiLeitor (int id) {
this.leit--;
if (this.leit == 0)
notifyAll(); //libera os escritores
//(a fila da variavel de condicao pode ter leitores e escritores)
}
// Entrada para escritores
public synchronized void EntraEscritor (int id) {
try {
this.escresp++; //sinaliza que quer escrever
while ((this.leit > 0) || (this.escr > 0)) {
wait(); //bloqueia se houver leitores lendo ou outro escritor escrevendo
}
this.escresp--;
this.escr++;
} catch (InterruptedException e) { }
}
// Saida para escritores
public synchronized void SaiEscritor (int id) {
this.escr--;
notifyAll(); //libera os leitores e outros escritores
}
}
Questão 3 (5,0 pts) Você foi contratado para desenvolver uma aplicação para a Justiça
Federal que, dado o número do CPF de uma pessoa, consulte todos os processos relaciona-
dos a essa pessoa em um banco de dados e gere um arquivo texto com esse levantamento.
Como a busca no banco de dados é muito demorada, já foi definido que a aplicação
deverá ser concorrente, i.e., executar com várias threads para aumentar sua eficiência,
diminuindo o tempo total para processar várias buscas consecutivas. A thread princi-
pal (main) deverá inicialmente criar um número de threads auxiliares igual ao dobro do
número de processadores da máquina. As threads auxiliares deverão realizar a tarefa
principal de, dado um número de CPF, consultar o banco de dados e gerar o arquivo de
saı́da. A thread principal (main), após criar as threads auxiliares, deverá ficar esperando
a entrada de um novo CPF pelo teclado, ou o valor -1 indicando que a aplicação deve
ser encerrada. A cada novo CPF informado, a thread principal deverá acionar uma thread
auxiliar para processá-lo, e logo em seguida voltar a esperar nova entrada do usuário. As
threads auxiliares devem ficar aguardando uma nova tarefa (CPF para consultar), realizar
a tarefa e voltar a aguardar nova tarefa, até que a thread principal avise que a aplicação
deve terminar e não há mais consultas pendentes para realizar (nesse caso a thread auxili-
ar deve finalizar sua execução). Após o usuário solicitar o encerramento da aplicação, as
consultas pendentes devem ser realizadas/finalizadas e novas consultas não serão mais re-
cebidas. A thread principal deve aguardar todas as threads auxiliares terminarem e então
finalizar a aplicação.
Considere que já existe uma função implementada que dado um CPF ela faz a
busca dos processos e gera o arquivo de saı́da. A assinatura dessa função é: void
consultaProcessos(long int cpf).
A função sysconf( SC NPROCESSORS ONLN) pode ser usada para identificar o número
de processadores da máquina.
(a) Usando a linguagem C, implemente uma solução para a aplicação definida
acima (código da thread principal e das threads auxiliares) usando de forma eficiente a
capacidade de processamento da máquina.
(b) Avalie a sua implementação quanto à corretude (atende aos requisitos do prob-
lema, não possui erros de concorrência, como possibilidade de condições de corrida in-
desejáveis, e não pode causar deadlock ou livelock) e à eficiência (usa da melhor forma
possı́vel a capacidade de processamento da máquina). Apresente argumentos objetivos
que justifiquem a sua avaliação.
Resp.: (a)
/*Variaveis globais */
pthread_mutex_t em; //lock par exclusao mutua
pthread_cond_t cond; //variavel de condicao para sincronizacao logica
int NTHREADS = sysconf(_SC_NPROCESSORS_ONLN) * 2;
long int cpf[NTHREADS]; //buffer para guardar CPFs esperando por atendimento
int in=0, out=0, cont=0; //variaveis de controle do buffer
int terminar=0; //variavel para registrar se a aplicacao deve terminar (0:nao, 1:sim)
//insere um novo cliente (CPF) no buffer para ser atendido por uma thread
//funcao executada pela thread main
int insere(long int cliente) {
pthread_mutex_lock(&em);
if(cont==NTHREADS) { //se nao ha espaco no buffer, recusa a solicitacao
pthread_mutex_unlock(&em);
return 0;
}
//insere o novo cliente e atualiza as variaveis de estado do buffer
cpf[in]=cliente;
in=(in+1)%NTHREADS;
cont++;
pthread_mutex_unlock(&em);
return 1;
}
//retira um cliente do buffer para atende-lo
//funcao executada pelas threads auxiliares
//(elas soh executam essa funcao se ja houver uma solicitacao armazenada)
long int retira() {
long int cliente;
cliente=cpf[out];
cpf[out]=0; //slot vazio
out=(out+1)%NTHREADS;
cont--;
return cliente;
}
//funcao principal das threads auxiliares
void *Trabalhador (void *t) {
int my_id = *(int*)t;
long int local_cpf;
while(1) { //permanece ativa ate que o sinal de terminar seja lançado
pthread_mutex_lock(&em);
while((cont==0) && (!terminar)) {
pthread_cond_wait(&cond, &em);
}
if(cont>0) { //ha solicitacao para tratar, pega uma delas e processa
local_cpf=retira();
pthread_mutex_unlock(&em);
fazInteracao(local_cpf); //interacao com o cliente remoto, fora da secao critica
} else { //terminar==1, a thread deve encerrar
pthread_mutex_unlock(&em);
break;
}
}
pthread_exit(NULL);
}
//funcao principal
int main(int argc, char *argv[]) {
int i,res;
long int req;
pthread_t threads[NTHREADS];
int id[NTHREADS];
//inicializa o lock e a variavel de condicao
pthread_mutex_init(&em, NULL);
pthread_cond_init(&cond, NULL);
//cria as threads auxiliares
for(i=0;i

Mais conteúdos dessa disciplina