Chapter 5 - Concurrency: Mutual Exclusion and Synchronization

Sincronização entre Processos: Mecanismo de Semáforos

 

Semáforo é um mecanismo de comunicação entre processos composto das operações wait(...) e signal(...). Via de regra, define-se um semáforo para cada recurso compartilhado. Operações em semáforos se processam através da chamda de sistema semop(...). Esta chamada requer 03 parâmetros: o identificador do semáforo (obtido via semget(...)); um array de estruturas sembuf; e o número de estruturas no array. Cada estrutura efetua uma operação no semáfor de índice estipulado na estrutura.

 
struct sembuf  {
  short sem_num;      /* indice do semaforo */
  short sem_op;       /* operacao requisitada */
  short sem_flag;     /* controle da operacao */
}
 

O segundo campo da estrutura sembuf opera no respectivo semáforo de acordo com a seguinte lógica. Sem "sem_op" for: a. se for negativo, bloqueie, senão some "sem_op" ao valor do semáforo e retorne; b. se positivo, some "sem_op" ao valor do semáforo e retorne; c. se nulo, retorne se o valor do semáforo for nulo; bloqueie, caso contrário. De posse destas primitivas, implemente as operações signal(...) ("sem_op" + 1) e wait(...) ("sem_op" - 1).

Com as operações signal(...) e wait(...) implementadas, resolva o problema dos filósofos jantando. Simule cada filósofo como um processo. Implemente 02 soluções: Fig. 6.12 e Fig. 6.15 do Livro Texto - William STALLINGS. Obs.: A 2º solução poderá utilizar a biblioteca de "threads", mas a 1º não. O código abaixo ilustra o uso de semáforo para acesso a uma região crítica (no caso, o vídeo).

 
#include <"stdio.h">
#include <"sys/types.h">
#include <"sys/ipc.h">
#include <"sys/sem.h">

int DefSem( key_t key )         /* Cria um Semáforo */
{
  int semid;
  union semun arg;

  semid = semget( key, 1, 0777 | IPC_CREATE );
  arg.val = 1;
  semctl( semid, 0, SETVAL, arg );
  return( semid );
}

int GetSem( key_t key )        /* Acessa Semáforo */
{
  int semid;
  semid = semget( key, 1, 0777 );
  return( semid );
}

void wait( int semid )         /* Define Operação Wait(...) */
{
  struct sembuf psem[2];
  psem[0].sem_num = 0;
  psem[0].sem_op = -1;
  psem[0].sem_flg = SEM_UNDO;

  semop( semid, psem, 1 );
}

void signal( int semid )         /* Define Operação Signal(...) */
{
  struct sembuf vsem[2];
  vsem[0].sem_num = 0;
  vsem[0].sem_op = 1;
  vsem[0].sem_flg = SEM_UNDO;

  semop( semid, vsem, 1 );
}

int main( int argc, char* argv[] )          /* Main Program */
{
  char* poema[16];
  int i, semid;

  semid = GetSem( 13 );
  if( semid < 0 )  {
    printf("Semáforo não criado !");
    exit( 0 );
  }

  poema[0] = "As armas e os baroes assinalados";
  poema[1] = "Que da ocidental praia Lusitana";
  poema[2] = "Por mares nunca dantes navegados";
  poema[3] = "Passaram ainda alem de Tapobrana";
  poema[4] = "E, em perigos e guerras esforcados";
  poema[5] = "Mais do que prometia a forca humana";
  poema[6] = "Por gente remota edificaram";
  poema[1] = "Novo reino, que tanto sulimaram";

  while( 1 )  {
    wait( semid );      /* entrada na região crítica */
    for( i = 0; i < 8; i++ )  {
      printf("\n%s", poemapi] );
      sleep( 1 );
    }
    printf("\n\n");
    signal( semid );    /* saída da região crítica */
  }
}
 

 


Luís Fernando Faina
Last modified: Fri Jun 4 10:12:48 2004