Advertisement
Kimossab

SO TP4

May 28th, 2015
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.46 KB | None | 0 0
  1. #include <sys/ipc.h>
  2. #include <sys/shm.h>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <stdlib.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <string.h>
  11. #include <signal.h>
  12. #include <time.h>
  13. #include "sem_funcoes.h"
  14.  
  15. #define CHAVE_SEM 15
  16. #define PERMISSOES 0600
  17.  
  18. int id;
  19.  
  20. void closesem(int sinalrecebido)
  21. {
  22.     sem_remover(id);
  23.     printf("\nSEMAFORO FECHADO\n");
  24. }
  25.  
  26. void childclose(int sin)
  27. {
  28.     while(waitpid(-1, NULL, WNOHANG) > 0);
  29. }
  30.  
  31. int aleatorio(int de, int ate)
  32. {
  33.     return de+(int)(((double)(ate-de+1))*rand()/(RAND_MAX+1.0));
  34. }
  35.  
  36. void main(int argv, char *argc[])
  37. {
  38.     if(argv != 3)
  39.     {
  40.         printf("Erro. Usagem : $tp4 <numero de processos> <número de iterações>\n");
  41.         return;
  42.     }
  43.  
  44.    
  45.     int pid=getpid();
  46.     int num_proc = atoi(argc[1]);
  47.     int num_it = atoi(argc[2]);
  48.     int i;
  49.     int n;
  50.     int fid;
  51.    
  52.     signal(SIGCHLD,childclose);
  53.     signal(SIGINT,closesem);
  54.  
  55.     id = sem_criar_n(CHAVE_SEM, 2, PERMISSOES);
  56.     sem_ini_var_n(id, 0, num_proc);
  57.     sem_ini_var_n(id, 1, 1);
  58.  
  59.     for(i=0; i<num_proc; i++)
  60.         if (fork()==0) break;
  61.    
  62.     fid=getpid();  
  63.    
  64.     for(i=0; i<num_it; i++)
  65.     {
  66.         if(fid != pid)
  67.         {
  68.             srand(fid+i*10);
  69.             printf("Filho %d a iniciar a sua tarefa (%dª iteração)...\n", fid, i+1);
  70.             sleep(aleatorio(1,5));
  71.             printf("... filho %d terminou a sua tarefa (%dª iteração).\n", fid, i+1);
  72.             sem_operacao_n(id, 0, -1);
  73.             sem_operacao_n(id, 1, 0);
  74.         }
  75.         else
  76.         {
  77.             sem_operacao_n(id, 0, 0);
  78.  
  79.             printf("\n%dª iteração concluida.\n",i+1);
  80.             if(i < num_it-1)
  81.                 printf(" Passando a seguinte...\n\n");
  82.            
  83.             sem_ini_var_n(id, 0, num_proc);
  84.             sem_operacao_n(id, 1, -1);
  85.             sem_ini_var_n(id, 1, 1);
  86.         }
  87.     }
  88.     if(fid != pid)
  89.         exit(0);
  90.     sem_remover(id);
  91. }
  92.  
  93. //sem_funcoes.h
  94. #include <sys/types.h>
  95. #include <sys/ipc.h>
  96. #include <sys/sem.h>
  97. #include <stdlib.h>
  98. #include <stdio.h>
  99. #define exit_on_error(s,m) if (s < 0) { perror(m); exit(1); }
  100. /* Modulo de funcoes de semaforos*/
  101. /* Este modulo nao pretende conter todas as "combinacoes" possiveis;
  102. apenas algumas das funcoes mais utilizadas nos exercicios estudados*/
  103. union semun
  104. { /* codigo copiado da manpage da semctl: */
  105.     int val;
  106.     /* value for SETVAL */
  107.     struct semid_ds *buf;
  108.     /* buffer for IPC_STAT, IPC_SET */
  109.     unsigned short *array;
  110.     /* array for GETALL, SETALL */
  111.     /* Linux specific part: */
  112.     struct seminfo *__buf;
  113.     /* buffer for IPC_INFO */
  114. };
  115. int sem_criar_n(int chave, int numero_de_semaforos, int permissoes);
  116. void sem_ini_var_n(int id, int indice_do_semaforo, int valor);
  117. int sem_criar(int chave, int permissoes, int valor);
  118. int sem_id(int chave);
  119. void sem_remover(int id);
  120. void sem_operacao_n(int id, int indice_do_semaforo, int operacao);
  121. void sem_operacao(int id, int operacao);
  122. int sem_valor_n(int id, int indice_do_semaforo);
  123. int sem_valor(int id);
  124. void sem_esperar(int id);
  125. void sem_assinalar(int id);
  126. void sem_wait40(int id);
  127.  
  128. //sem_funcoes.c
  129. #include "sem_funcoes.h"
  130. /* Modulo de funções para manipular semáforos/
  131. /* Este modulo nao pretende conter todas as "combinações" possíveis;
  132. apenas algumas das funções mais utilizadas nos exercícios estudados*/
  133. /* cria um conjunto de semáforos mas nao inicializa as respectivas
  134. variáveis de controlo */
  135. int sem_criar_n(int chave, int numero_de_semaforos, int permissoes)
  136. {int id;
  137. id=semget(chave, numero_de_semaforos, IPC_CREAT|IPC_EXCL|permissoes);
  138. exit_on_error(id,"Erro ao criar semaforo");
  139. return id;
  140. }
  141. /* (re)inicializa o valor da variavel de controlo do semaforo */
  142. void sem_ini_var_n(int id, int indice_do_semaforo, int valor)
  143. {int r;
  144. union semun su;
  145. su.val=valor;
  146. r=semctl(id, indice_do_semaforo, SETVAL, su);
  147. exit_on_error(r,"Erro ao atribuir valor ao semaforo");
  148. }
  149. /* cria um semaforo e inicializa a respectiva variavel de controlo */
  150. int sem_criar(int chave, int permissoes, int valor)
  151. {int id = sem_criar_n(chave, 1, permissoes);
  152. sem_ini_var_n(id, 0, valor);
  153. return id;
  154. }
  155. /* obtem id do semaforo */
  156. int sem_id(int chave)
  157. {int id;
  158. id=semget(chave, 0, 0);
  159. exit_on_error(id,"Erro ao obter id do semaforo");
  160. return id;
  161. }
  162. /* remove semaforo */
  163. void sem_remover(int id)
  164. {
  165. semctl(id, 0, IPC_RMID);
  166. }
  167. /* executa uma operacao sobre o semaforo n do conjunto */
  168. void sem_operacao_n(int id, int indice_do_semaforo, int operacao)
  169. {int r;
  170. struct sembuf sb;
  171. sb.sem_num = indice_do_semaforo; /* Indice do semaforo no conjunto */
  172. sb.sem_op = operacao;
  173. sb.sem_flg = 0; /* flags */
  174. r=semop(id, &sb, 1 );
  175. exit_on_error(r,"Erro ao realizar a operacao sobre o semaforo");
  176. }
  177. /* executa uma operacao sobre o semaforo 0(assumido)*/
  178. void sem_operacao(int id, int operacao)
  179. {
  180. sem_operacao_n(id, 0, operacao); /*Indice 0 assumido*/
  181. }
  182. /* devolve o valor da variavel de controlo do semaforo n do conjunto*/
  183. int sem_valor_n(int id, int indice_do_semaforo)
  184. {int r;
  185. r=semctl(id,indice_do_semaforo,GETVAL);
  186. exit_on_error(r,"Erro ao aceder ao semaforo");
  187. return r;
  188. }
  189. /* devolve o valor da variavel de controlo do semaforo 0 (assumido)*/
  190. int sem_valor(int id)
  191. {int r;
  192. r=sem_valor_n(id,0); /*0 assumido*/
  193. return r;
  194. }
  195. /* realiza a operação -1 ("esperar") sobre o semáforo 0 do conjunto*/
  196. void sem_esperar(int id)
  197. {
  198. sem_operacao(id, -1); /* esperar*/
  199. }
  200. /* realiza a operação +1 ("assinalar") sobre o semáforo 0 do conjunto*/
  201. void sem_assinalar(int id)
  202. {
  203. sem_operacao(id, 1); /* assinalar */
  204. }
  205. /* realiza a operação 0 ("wait-for-zero") sobre o semáforo 0 do conjunto*/
  206. void sem_wait40(int id) /* wait-for-zero*/
  207. {
  208. sem_operacao(id, 0);
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement