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 */ } }