Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <stdio.h>
- #include <sys/fcntl.h>
- #include <sys/wait.h>
- #include <semaphore.h>
- #include <pthread.h>
- //define o número de processos filho a criar
- #define N 10
- //define o número de threads a criar por processo filho
- #define M 10
- //declaração do nosso semáforo mutex (para procesos)
- sem_t *mutex_proc;
- //declaração/inicialização do nosso semáforo mutex (para threads)
- pthread_mutex_t mutex_thread = PTHREAD_MUTEX_INITIALIZER;
- //id da memória partilhada a ser criada
- int shmid;
- //endereço da memória partilhada (para um inteiro)
- int* mem;
- //funções utilizadas
- void init(); //inicialização das variáveis necessárias
- void parent(); //código executado pelo processo principal, pai de todos os outros
- void child(); //código executado por cada processo filho
- void threadManipulation(); //criação de todas as threads, espera que estas terminem e junta-as no fim
- void* threadBehaviour(void* arg); //código executado por cada thread
- void printMem(); //print dos valores presentes na memória partilhada
- void terminate(); //término de todas as variáveis inicializadas em 'init()'
- int main() {
- int i;
- //chamar a função para inicialização das variáveis necessárias
- init();
- //cria N processos filho
- for (i = 0; i < N; i++) {
- if (fork() == 0) { //se sou o processo filho...:
- child(); //executo
- exit(0); //paro o processo
- }
- }
- //se sou o processo pai...:
- parent(); //executo
- return 0; //paro o processo principal
- }
- void init() {
- int i;
- //inicialização do semáforo
- sem_unlink("MUTEX_PROC");
- mutex_proc = sem_open("MUTEX_PROC",O_CREAT|O_EXCL,0700,1); //o quarto argumento define o valor de inicialização do semáforo
- //inicialização da memória partilhada (para armazenamento de M inteiros)
- shmid = shmget(IPC_PRIVATE, M*sizeof(int), IPC_CREAT|0700);
- mem = (int*)shmat(shmid, NULL, 0); //tem de se fazer 'cast' da expressão para um ponteiro do tipo desejado (int*);
- //os dois últimos argumento são assim por default;
- //colocação de todos os interios da memória partilhada a 0
- for (i = 0; i < M; i++) {
- mem[i] = 0;
- }
- }
- void parent() {
- int i;
- //esperar que N processos filho terminem
- for (i = 0; i < N; i++) {
- wait(NULL);
- }
- //fazer print da memória partilhada
- printMem();
- //chamar a função para 'limpar' o que foi criado
- terminate();
- }
- void child() {
- //preenchimento da memória partilhada
- sem_wait(mutex_proc); //esperar que o semáforo fique aberto (esperar que o valor seja 1) e decrementá-lo
- threadManipulation(); //chamar a função para funcionamento de threads
- sem_post(mutex_proc); //abrir o semáforo de novo (incrementá-lo)
- }
- void threadManipulation() {
- int i, j;
- //criação de uma array com M threads
- pthread_t thread_array[M];
- //criação de M threads e colocação destas num array
- for (i = 0; i < M; i++) {
- pthread_create(&thread_array[i], NULL, threadBehaviour, (void*)((long)i));
- }
- //esperar que as threads acabem e juntá-las
- for (j = 0; j < M; j++) {
- pthread_join(thread_array[j], NULL);
- }
- return;
- }
- void* threadBehaviour(void* arg) {
- //conversão do 'arg' para o tipo que queremos (neste caso recebemos 'i', do tipo 'long')
- long n = (long)arg;
- //preenchimento da memória partilhada
- pthread_mutex_lock(&mutex_thread); //esperar que o semáforo fique aberto
- mem[n] += 1; //incrementar o valor no indice 'n', da memória partilhada
- pthread_mutex_unlock(&mutex_thread); //abrir o semáforo de novo
- //terminação da thread
- pthread_exit(NULL);
- return NULL;
- }
- void printMem() {
- int i;
- //fazer print das N posições da memória partilhada
- for (i = 0; i < N; i++) {
- printf("%d ", mem[i]); //não é necessário esperar pelo semáforo,
- //uma vez que todos os processos filho já terminaram
- }
- printf("\n");
- }
- void terminate() {
- //término do semáforo mutex_proc
- sem_close(mutex_proc);
- sem_unlink("MUTEX_PROC");
- //término do semáforo mutex_thread
- pthread_mutex_destroy(&mutex_thread);
- //término da memória partilhada
- shmctl(shmid, IPC_RMID, NULL);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement