Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <string.h>
- #include <signal.h>
- #include <time.h>
- #include "sem_funcoes.h"
- #define CHAVE_SEM 15
- #define PERMISSOES 0600
- int id;
- void closesem(int sinalrecebido)
- {
- sem_remover(id);
- printf("\nSEMAFORO FECHADO\n");
- }
- void childclose(int sin)
- {
- while(waitpid(-1, NULL, WNOHANG) > 0);
- }
- int aleatorio(int de, int ate)
- {
- return de+(int)(((double)(ate-de+1))*rand()/(RAND_MAX+1.0));
- }
- void main(int argv, char *argc[])
- {
- if(argv != 3)
- {
- printf("Erro. Usagem : $tp4 <numero de processos> <número de iterações>\n");
- return;
- }
- int pid=getpid();
- int num_proc = atoi(argc[1]);
- int num_it = atoi(argc[2]);
- int i;
- int n;
- int fid;
- signal(SIGCHLD,childclose);
- signal(SIGINT,closesem);
- id = sem_criar_n(CHAVE_SEM, 2, PERMISSOES);
- sem_ini_var_n(id, 0, num_proc);
- sem_ini_var_n(id, 1, 1);
- for(i=0; i<num_proc; i++)
- if (fork()==0) break;
- fid=getpid();
- for(i=0; i<num_it; i++)
- {
- if(fid != pid)
- {
- srand(fid+i*10);
- printf("Filho %d a iniciar a sua tarefa (%dª iteração)...\n", fid, i+1);
- sleep(aleatorio(1,5));
- printf("... filho %d terminou a sua tarefa (%dª iteração).\n", fid, i+1);
- sem_operacao_n(id, 0, -1);
- sem_operacao_n(id, 1, 0);
- }
- else
- {
- sem_operacao_n(id, 0, 0);
- printf("\n%dª iteração concluida.\n",i+1);
- if(i < num_it-1)
- printf(" Passando a seguinte...\n\n");
- sem_ini_var_n(id, 0, num_proc);
- sem_operacao_n(id, 1, -1);
- sem_ini_var_n(id, 1, 1);
- }
- }
- if(fid != pid)
- exit(0);
- sem_remover(id);
- }
- //sem_funcoes.h
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/sem.h>
- #include <stdlib.h>
- #include <stdio.h>
- #define exit_on_error(s,m) if (s < 0) { perror(m); exit(1); }
- /* Modulo de funcoes de semaforos*/
- /* Este modulo nao pretende conter todas as "combinacoes" possiveis;
- apenas algumas das funcoes mais utilizadas nos exercicios estudados*/
- union semun
- { /* codigo copiado da manpage da semctl: */
- int val;
- /* value for SETVAL */
- struct semid_ds *buf;
- /* buffer for IPC_STAT, IPC_SET */
- unsigned short *array;
- /* array for GETALL, SETALL */
- /* Linux specific part: */
- struct seminfo *__buf;
- /* buffer for IPC_INFO */
- };
- int sem_criar_n(int chave, int numero_de_semaforos, int permissoes);
- void sem_ini_var_n(int id, int indice_do_semaforo, int valor);
- int sem_criar(int chave, int permissoes, int valor);
- int sem_id(int chave);
- void sem_remover(int id);
- void sem_operacao_n(int id, int indice_do_semaforo, int operacao);
- void sem_operacao(int id, int operacao);
- int sem_valor_n(int id, int indice_do_semaforo);
- int sem_valor(int id);
- void sem_esperar(int id);
- void sem_assinalar(int id);
- void sem_wait40(int id);
- //sem_funcoes.c
- #include "sem_funcoes.h"
- /* Modulo de funções para manipular semáforos/
- /* Este modulo nao pretende conter todas as "combinações" possíveis;
- apenas algumas das funções mais utilizadas nos exercícios estudados*/
- /* cria um conjunto de semáforos mas nao inicializa as respectivas
- variáveis de controlo */
- int sem_criar_n(int chave, int numero_de_semaforos, int permissoes)
- {int id;
- id=semget(chave, numero_de_semaforos, IPC_CREAT|IPC_EXCL|permissoes);
- exit_on_error(id,"Erro ao criar semaforo");
- return id;
- }
- /* (re)inicializa o valor da variavel de controlo do semaforo */
- void sem_ini_var_n(int id, int indice_do_semaforo, int valor)
- {int r;
- union semun su;
- su.val=valor;
- r=semctl(id, indice_do_semaforo, SETVAL, su);
- exit_on_error(r,"Erro ao atribuir valor ao semaforo");
- }
- /* cria um semaforo e inicializa a respectiva variavel de controlo */
- int sem_criar(int chave, int permissoes, int valor)
- {int id = sem_criar_n(chave, 1, permissoes);
- sem_ini_var_n(id, 0, valor);
- return id;
- }
- /* obtem id do semaforo */
- int sem_id(int chave)
- {int id;
- id=semget(chave, 0, 0);
- exit_on_error(id,"Erro ao obter id do semaforo");
- return id;
- }
- /* remove semaforo */
- void sem_remover(int id)
- {
- semctl(id, 0, IPC_RMID);
- }
- /* executa uma operacao sobre o semaforo n do conjunto */
- void sem_operacao_n(int id, int indice_do_semaforo, int operacao)
- {int r;
- struct sembuf sb;
- sb.sem_num = indice_do_semaforo; /* Indice do semaforo no conjunto */
- sb.sem_op = operacao;
- sb.sem_flg = 0; /* flags */
- r=semop(id, &sb, 1 );
- exit_on_error(r,"Erro ao realizar a operacao sobre o semaforo");
- }
- /* executa uma operacao sobre o semaforo 0(assumido)*/
- void sem_operacao(int id, int operacao)
- {
- sem_operacao_n(id, 0, operacao); /*Indice 0 assumido*/
- }
- /* devolve o valor da variavel de controlo do semaforo n do conjunto*/
- int sem_valor_n(int id, int indice_do_semaforo)
- {int r;
- r=semctl(id,indice_do_semaforo,GETVAL);
- exit_on_error(r,"Erro ao aceder ao semaforo");
- return r;
- }
- /* devolve o valor da variavel de controlo do semaforo 0 (assumido)*/
- int sem_valor(int id)
- {int r;
- r=sem_valor_n(id,0); /*0 assumido*/
- return r;
- }
- /* realiza a operação -1 ("esperar") sobre o semáforo 0 do conjunto*/
- void sem_esperar(int id)
- {
- sem_operacao(id, -1); /* esperar*/
- }
- /* realiza a operação +1 ("assinalar") sobre o semáforo 0 do conjunto*/
- void sem_assinalar(int id)
- {
- sem_operacao(id, 1); /* assinalar */
- }
- /* realiza a operação 0 ("wait-for-zero") sobre o semáforo 0 do conjunto*/
- void sem_wait40(int id) /* wait-for-zero*/
- {
- sem_operacao(id, 0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement