Adriano

Adriano Brasileiro Silva - Laboratorio de CES-33

Esta pagina foi criada com o proposito de realizar as atividades de laboratorio da materia de CES-33 do curso de Computacao do ITA, ano de 2009

Pratica 1

Foi pedido que implementassemos o problema dos produtores e consumidores aplicando pipes para a troca de mensagens. O problema ja e resolvido simplesmente por ser utilizados os pipes, que garantem a exclusao mutua. Assim, para implementar o problema, criei o seguinte codigo:

Produtor:

#include <stdio.h>
#include <fcntl.h> 
#include <string.h>
 
main ()
{ 
  int fd, messageLen, i;
  char message [100];
  sprintf (message, "%d", getpid());
  messageLen = strlen (message) + 1;
  do
  {
    fd = open ("aPipe", O_WRONLY);
    if (fd == -1) sleep (1);
  } while (fd == -1); 
  for (i = 1; i <= 3; i++)
  {
    write (fd, message, messageLen);
    sleep (3);
  }
  close (fd);
}

Consumidor:

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
 
main ()
{
  int fd;
  char str[100];
  mkfifo ("aPipe", 0660);
  fd = open ("aPipe", O_RDONLY);
  while (readLine (fd, str))
  printf ("%d leu de %s\n", getpid(), str); 
  close (fd);
} 
 
readLine (int fd,char *str)
{
  int n;
  do
  {
    n = read (fd, str, 1);
  } while (n > 0 && *str++ != 0);
 return (n > 0);
}

Onde cada produtor produz tres mensagens e os consumidores as leem. Assim, executando os alguns produtores e consumidores, obtemos o seguinte resultado:

lab1.png

Nota-se que o consumidor le as mensagens produzidas pelos tres outros produtores

Pratica 2

Nesta pratica foi pedido que implementassemos o problema do jantar dos filosofos utilizando threads. O codigo criado foi o seguinte:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
 
#define N        5
#define LEFT        (i+N-1)%N
#define RIGHT        (i+1)%N
#define THINKING    0
#define HUNGRY        1
#define EATING        2
 
#define TRUE        1
 
typedef sem_t semaphore;
int state[N];
semaphore mutex;
semaphore s[N];
 
void think(int i)
{
  printf("Filosofo %d esta pensando\n", i);
}
 
void eat(int i)
{
  printf("Filosofo %d esta comendo\n", i);
}
 
void test(int i)
{
  if (state[i] == HUNGRY && state[LEFT] != EATING && state[RIGHT]    != EATING)
  {
    state[i] = EATING;
    sem_post(&s[i]);    
  }
}
 
void take_forks(int i)
{
  sem_wait(&mutex);
  state[i] = HUNGRY;
  test(i);
  sem_post(&mutex);
  sem_wait(&s[i]);
}
 
void put_forks(int i)
{
  sem_wait(&mutex);
  state[i] = THINKING;
  test(LEFT);
  test(RIGHT);
  sem_post(&mutex);
}
 
void* philosopher(void *i)
{
  int f = *(int*) i;
  while(TRUE)
  {
    think(f);
    take_forks(f);
    eat(f);
    put_forks(f);    
  }
}
 
main()
{
  pthread_t thread[N];
  sem_init(&mutex, 0, 1);
  int i;
  for(i=0; i<N; i++)
  {
    sem_init(&s[i], 0, 0);
    pthread_create(&thread[i], NULL, philosopher, &i);
  }
  void* out;
  for(i=0; i<N; i++)
    pthread_join(thread[i], &out);
}

Onde a funcao main cria as tantas threads quantos sao os filosofos. Os semaforos garantem a exclusao mutua. Executando-se o arquivo, tem-se o resultado:

lab2.png

Note que assim que um filosofo termina de comer, o processamento dele ja permite que ele coma novamente, de modo que ele come varias vezes seguidas. No entanto, todos os filosofos em algum momento conseguem comer, sem ocorrerem deadlocks.

Pratica 3

Nesta pratica, foi pedido que implementassemos o problema da barbearia, da mesma forma que na pratica anterior, de modo que o resultado e analogo:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
 
#define CHAIRS 5
#define CLIENTES 100
#define TRUE 1
 
typedef sem_t semaphore;
 
semaphore customers;
semaphore barbers;
semaphore mutex;
int waiting = 0;
 
void cut_hair(void)
{
  int i;
  printf("Barbero esta cortando cabelo\n");
  for(i=0; i<10000000; i++);
}
 
void get_haircut(void)
{
  printf("Cliente tem o cabelo cortado\n");
}
 
void* barber(void* i)
{
  while(TRUE)
  {
    sem_wait(&customers);
    sem_wait(&mutex);
    waiting = waiting - 1;
    sem_post(&barbers);
    sem_post(&mutex);
    cut_hair();
  }
}
 
void* customer(void* i)
{
  sem_wait(&mutex);
  if(waiting<CHAIRS)
  {
    waiting = waiting + 1;
    sem_post(&customers);
    sem_post(&mutex);
    sem_wait(&barbers);
    get_haircut();
  }
  else
  {
    sem_post(&mutex);
    printf("Cliente desistiu\n");
  }
}
 
main()
{
  pthread_t barbeiro, clientes[CLIENTES];
 
  sem_init(&mutex, 0, 1);
  sem_init(&barbers, 0, 0);
  sem_init(&customers, 0, 0);
 
  pthread_create(&barbeiro, NULL, barber, NULL);
  int i;
  for(i=0; i<CLIENTES; i++)
    pthread_create(&clientes[i], NULL, customer, NULL);
 
  void* out;
  pthread_join(barbeiro, &out);
  for(i=0; i<CLIENTES; i++)
    pthread_join(clientes[i], &out);
}

Coloquei um numero alto de clientes para que se pudessem observar desistencias. Para tanto, tambem foi necessario atrasar o barbeiro quando ele cortasse o cabelo de alguem. Executando o codigo, temos o seguinte resultado:

lab3.png

Pratica 4

A ultima pratica do bimestre consistiu em implementar o problema dos escritores e leitores utilizando semaforos e mutexes. No fim das contas seguiu o mesmo procedimento das praticas anteriores.

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
 
#define TRUE 1
 
typedef sem_t semaphore;
semaphore mutex;
semaphore db;
int rc = 0;
int database;
 
int think_up_data()
{
  return rand();
}
 
void write_data_base(int f)
{
  database = f;
}
 
int read_data_base()
{
  return database;
}
 
void use_data_read(int f)
{
  printf("Foi lido %d\n", f);
}
 
void* reader(void* i)
{
  int f;
  while(TRUE)
  {
    sem_wait(&mutex);
    rc = rc + 1;
    if (rc == 1) sem_wait(&db);
    sem_post(&mutex);
    f = read_data_base();
    sem_wait(&mutex);
    rc = rc - 1;
    if (rc == 0) sem_post(&db);
    sem_post(&mutex);
    use_data_read(f);
  }        
}
 
void* writer(void* i) {
  int f;
  while(TRUE)
  {
    f = think_up_data();
    sem_wait(&db);
    write_data_base(f);
    sem_post(&db);    
  }
}
 
main()
{
  pthread_t escritor, leitor;
 
  sem_init(&mutex, 0, 1);
  sem_init(&db, 0, 1);
 
  pthread_create(&escritor, NULL, writer, NULL);
  pthread_create(&leitor, NULL, reader, NULL);
 
  void* out;
  pthread_join(escritor, &out);
  pthread_join(leitor, &out);
}

Onde na funcao main sao criados um leitor e um escritor em threads diferentes. O escritor gera um numero aleatorio e o escreve no database. O leitor por sua vez le o valor do database e o imprime. Note que cada acesso ao database esta protegido por semaforos, para garantir a exclusao mutua na regiao critica. O codigo em andamento e o seguinte:

lab4.png

Este codigo sofre do mesmo problema para mostrar resultados que o segundo laboratorio, mas, com o codigo em andamento, e possivel notar o progresso do leitor.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License