Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.39 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/ipc.h>
  5. #include <sys/shm.h>
  6. #include <stdio.h>
  7. #include <sys/fcntl.h>
  8. #include <sys/wait.h>
  9. #include <semaphore.h>
  10. #include <pthread.h>
  11.  
  12. //define o número de processos filho a criar
  13. #define N 10
  14.  
  15. //define o número de threads a criar por processo filho
  16. #define M 10
  17.  
  18. //declaração do nosso semáforo mutex (para procesos)
  19. sem_t *mutex_proc;
  20.  
  21. //declaração/inicialização do nosso semáforo mutex (para threads)
  22. pthread_mutex_t mutex_thread = PTHREAD_MUTEX_INITIALIZER;
  23.  
  24. //id da memória partilhada a ser criada
  25. int shmid;
  26.  
  27. //endereço da memória partilhada (para um inteiro)
  28. int* mem;
  29.  
  30. //funções utilizadas
  31. void init(); //inicialização das variáveis necessárias
  32. void parent(); //código executado pelo processo principal, pai de todos os outros
  33. void child(); //código executado por cada processo filho
  34. void threadManipulation(); //criação de todas as threads, espera que estas terminem e junta-as no fim
  35. void* threadBehaviour(void* arg); //código executado por cada thread
  36. void printMem(); //print dos valores presentes na memória partilhada
  37. void terminate(); //término de todas as variáveis inicializadas em 'init()'
  38.  
  39. int main() {
  40.  
  41. int i;
  42.  
  43. //chamar a função para inicialização das variáveis necessárias
  44. init();
  45.  
  46. //cria N processos filho
  47. for (i = 0; i < N; i++) {
  48. if (fork() == 0) { //se sou o processo filho...:
  49. child(); //executo
  50. exit(0); //paro o processo
  51. }
  52. }
  53. //se sou o processo pai...:
  54. parent(); //executo
  55. return 0; //paro o processo principal
  56. }
  57.  
  58. void init() {
  59.  
  60. int i;
  61.  
  62. //inicialização do semáforo
  63. sem_unlink("MUTEX_PROC");
  64. mutex_proc = sem_open("MUTEX_PROC",O_CREAT|O_EXCL,0700,1); //o quarto argumento define o valor de inicialização do semáforo
  65.  
  66. //inicialização da memória partilhada (para armazenamento de M inteiros)
  67. shmid = shmget(IPC_PRIVATE, M*sizeof(int), IPC_CREAT|0700);
  68. mem = (int*)shmat(shmid, NULL, 0); //tem de se fazer 'cast' da expressão para um ponteiro do tipo desejado (int*);
  69. //os dois últimos argumento são assim por default;
  70.  
  71. //colocação de todos os interios da memória partilhada a 0
  72. for (i = 0; i < M; i++) {
  73. mem[i] = 0;
  74. }
  75. }
  76.  
  77. void parent() {
  78.  
  79. int i;
  80.  
  81. //esperar que N processos filho terminem
  82. for (i = 0; i < N; i++) {
  83. wait(NULL);
  84. }
  85.  
  86. //fazer print da memória partilhada
  87. printMem();
  88.  
  89. //chamar a função para 'limpar' o que foi criado
  90. terminate();
  91. }
  92.  
  93. void child() {
  94.  
  95. //preenchimento da memória partilhada
  96. sem_wait(mutex_proc); //esperar que o semáforo fique aberto (esperar que o valor seja 1) e decrementá-lo
  97. threadManipulation(); //chamar a função para funcionamento de threads
  98. sem_post(mutex_proc); //abrir o semáforo de novo (incrementá-lo)
  99. }
  100.  
  101. void threadManipulation() {
  102.  
  103. int i, j;
  104.  
  105. //criação de uma array com M threads
  106. pthread_t thread_array[M];
  107.  
  108. //criação de M threads e colocação destas num array
  109. for (i = 0; i < M; i++) {
  110. pthread_create(&thread_array[i], NULL, threadBehaviour, (void*)((long)i));
  111. }
  112.  
  113. //esperar que as threads acabem e juntá-las
  114. for (j = 0; j < M; j++) {
  115. pthread_join(thread_array[j], NULL);
  116. }
  117.  
  118. return;
  119. }
  120.  
  121. void* threadBehaviour(void* arg) {
  122.  
  123. //conversão do 'arg' para o tipo que queremos (neste caso recebemos 'i', do tipo 'long')
  124. long n = (long)arg;
  125.  
  126. //preenchimento da memória partilhada
  127. pthread_mutex_lock(&mutex_thread); //esperar que o semáforo fique aberto
  128. mem[n] += 1; //incrementar o valor no indice 'n', da memória partilhada
  129. pthread_mutex_unlock(&mutex_thread); //abrir o semáforo de novo
  130.  
  131. //terminação da thread
  132. pthread_exit(NULL);
  133. return NULL;
  134. }
  135.  
  136. void printMem() {
  137.  
  138. int i;
  139.  
  140. //fazer print das N posições da memória partilhada
  141. for (i = 0; i < N; i++) {
  142. printf("%d ", mem[i]); //não é necessário esperar pelo semáforo,
  143. //uma vez que todos os processos filho já terminaram
  144. }
  145. printf("\n");
  146. }
  147.  
  148. void terminate() {
  149.  
  150. //término do semáforo mutex_proc
  151. sem_close(mutex_proc);
  152. sem_unlink("MUTEX_PROC");
  153.  
  154. //término do semáforo mutex_thread
  155. pthread_mutex_destroy(&mutex_thread);
  156.  
  157. //término da memória partilhada
  158. shmctl(shmid, IPC_RMID, NULL);
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement