/****************************************************************************** * FILE: experiment-x2.c * DESCRIPTION: * Demontrating consumer producer with threads which are synchronized * One mutex-variable is used to support thread synchronisation * * LAST REVISED: 25/08/03 Florian Weizenegger ******************************************************************************/ #include #include /* for gettimeofday() */ #include /* for gettimeofday() */ #include #include #include #include #include /* for semget(), semop(), semctl() */ #define NUM_THREADS 45 #define SIZEOFBUFFER 8000 #define NO_OF_ITERATIONS 10000 /* Para uso dos semafaros */ #define NUMERO_DE_SEM SIZEOFBUFFER #define CHAVE_DE_SEM 0x1234 #define PERMISSAO_SEM 0666 struct sembuf sem_ocupadas[1]; struct sembuf sem_livres[1]; pthread_t consumers[NUM_THREADS]; pthread_t producers[NUM_THREADS]; pthread_mutex_t mutex_p, mutex_c; int buffer[SIZEOFBUFFER]; int i1=0, i2=0, id; void myadd(int toAdd) { i1 = (i1+1) % SIZEOFBUFFER; buffer[i1] = toAdd; } void myremove() { buffer [i2]; i2 = (i2+1) % SIZEOFBUFFER; } //Producer adds NO_OF_ITERATIONS times the value 10 //to the buffer void *produce(void *threadid) { int i = 0; int sum = 0; int ret = 0; printf("Producer #%d started...\n", threadid); while (i < NO_OF_ITERATIONS) { if( semop( id, sem_livres, 1 ) == -1 ) { fprintf(stderr,"chamada semop() falhou, impossivel fechar o semaforo!"); exit(1); } pthread_mutex_lock (&mutex_p); myadd(10); i++; sum += 10; if( semop( id, sem_ocupadas, 1 ) == -1 ) { fprintf(stderr,"chamada semop() falhou, impossivel fechar o semaforo!"); exit(1); } pthread_mutex_unlock (&mutex_p); } printf("Producer #%d sum : %d\n", threadid, sum); pthread_exit(NULL); } //Consumer removes void *consume(void *threadid) { int i = 0; int sum = 0; int ret = 0; printf("Consumer #%d started...\n", threadid); while (i < NO_OF_ITERATIONS) { if( semop( id, sem_ocupadas, 1 ) == -1 ) { fprintf(stderr,"chamada semop() falhou, impossivel fechar o semaforo!"); exit(1); } pthread_mutex_lock (&mutex_c); myremove(); i++; sum += ret; if( semop( id, sem_livres, 1 ) == -1 ) { fprintf(stderr,"chamada semop() falhou, impossivel fechar o semaforo!"); exit(1); } pthread_mutex_unlock (&mutex_c); } printf("Consumer #%d sum : %d\n", threadid, sum); pthread_exit(NULL); } int main(int argc, char *argv[]) { int tc, tp, status, i, rc; float delta; struct timeval start_time; struct timeval stop_time; gettimeofday( &start_time, NULL ); //init mutex pthread_mutex_init(&mutex_p, NULL); pthread_mutex_init(&mutex_c, NULL); /* * Destrancar semapharo */ sem_ocupadas[0].sem_op = -1; sem_ocupadas[0].sem_num = 0; /* numero do semapharo */ sem_ocupadas[0].sem_flg = 0; sem_livres[0].sem_op = 1; sem_livres[0].sem_num = 0; /* numero do semapharo */ sem_livres[0].sem_flg = 0; /* * Criacao do semapharo */ if( (id = semget(CHAVE_DE_SEM, 1, IPC_CREAT |0666 )) == -1 ) { perror("\n Erro na requisicao de criacao do semapharo - semget \n"); fprintf(stderr,"Erro na requisicao de criacao do semapharo - semget"); exit(1); } if( semop(id, sem_livres, 1) == -1) { fprintf(stderr,""); perror("\n Erro ao usar o semapharo na chamada semop\n"); exit(1); } for (i=0;i %d", i, buffer[i]); delta = (float)(stop_time.tv_sec - start_time.tv_sec); delta += (stop_time.tv_usec - start_time.tv_usec)/(float)1000000; printf("\nTotal time : %.10f sec\n\n", delta); pthread_exit(NULL); if( semctl( id, 0, IPC_RMID, 0) != 0 ) { fprintf(stderr,"Impossivel remover o semaforo!\n"); exit(1); } }