Enviado em 15/05/2019 - 20:09h
Olá, fiz a resolução do enunciado abaixo e está funcionando perfeitamente, porém não sei se fiz o uso correto dos semáforos (nunca usei isso antes). Gostaria de saber se é assim que se utiliza ou se o que fiz não passa de uma gambiarra das mais medonhas.#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <errno.h> #include <unistd.h> #include <semaphore.h> #define NUM_THREADS 3 int cont1 = 0; int cont2 = 0; sem_t t1; struct WorkUnit { int temp; }; void *tratador1 (void *param) { int valor; sem_getvalue (&t1, &valor); if(valor == 0){ cont1++; if(cont1 == 10){ printf("Tratador 1 utilizado \n\n"); cont1 = 0; } sem_post(&t1); } pthread_exit(NULL); } void *tratador2 (void *param) { int valor2; sem_getvalue (&t1, &valor2); if(valor2 == 2){ cont2++; if(cont2 == 10){ printf("Tratador 2 utilizado \n\n"); cont2 = 0; } sem_wait(&t1); } pthread_exit(NULL); } void *observador (void *param) { struct WorkUnit *wu = param; int temp = wu->temp; printf("Valor recebido \n\n"); if(temp <= 40) { // condicao para decrementar o semaforo sem_wait(&t1); }else if(temp >= 50) { // condicao para incrementar o semaforo sem_post(&t1); } pthread_exit(NULL); } int main (){ int terror; int n; int t; void *(*functions[NUM_THREADS])(void *) = {tratador2, tratador1, observador}; int valor[0]; pthread_t tids [NUM_THREADS]; sem_init (&t1, 0, 1); //iniciando o semaforo while (1) { printf("Digite o valor: "); scanf("%d", valor); for (n=0; n<NUM_THREADS; n++) { terror = pthread_create(&tids[n],NULL, functions[n], valor); if (terror) { errno = terror; perror("Falha na criação da thread"); exit(EXIT_FAILURE); } } for (t = 0; t < NUM_THREADS; t++) { terror = pthread_join(tids[t], NULL); if (terror) { errno = terror; perror("Erro no Join!"); exit(EXIT_FAILURE); } } } pthread_exit(NULL); }
Enviado em 16/05/2019 - 09:32h
Concordo com sua suspeita, pois o código não me parece muito alinhado com o enunciado.Enviado em 16/05/2019 - 16:08h
Enviado em 19/05/2019 - 00:14h
Bem, eu posso ter entendido tudo errado, mas acho sinceramente que não.sem_t temp1_wr, temp1_rd, temp2_wr, temp2_rd; int temp_t1, temp_t2; void *tratador1(void *){ static unsigned count; // Sinaliza ao observador que ele pode gravar o dado observado. sem_post(&temp1_wr); // Loop infinito, como pede o enunciado. while(1){ // Aguarda haver dado pronto para consumo. sem_wait(&temp1_rd); // Região crítica: Consome dado em temp_t1. Durante este tempo, não pode haver acesso simultâneo a temp1. /* ... */ // Fim da região crítica. Sinaliza ao observador que pode gravar novo dado observado. sem_post(&temp1_wr); // Aqui você pode fazer o que quiser, desde que não dependa do valor compartilhado de temp1. if(++count==10){ // Imprime mensagem. count=0; } } // Como o loop acima é infinito, nunca se vai chegar aqui... return NULL; } void *tratador2(void *){ // Equivalente a tratador1(), mas trocando ‘temp1…’ por ‘temp2…’. // (Ou talvez se possa ter um tratador só, chamado duas vezes, mas com argumentos diferentes. // Acima eu ignorei o argumento da função, mas ele poderia ter sido usado com um ponteiro que // incluísse os dois semáforos.) } void *observador(void *){ while(1){ int temp=obtem_temperatura(); if(temp<=40){ sem_wait(&temp1_wr); temp1=temp; sem_post(&temp1_rd); } else if(temp>50){ sem_wait(&temp2_wr); temp2=temp; sem_post(&temp2_rd); } } return NULL; } int main(void){ sem_init(&temp1_wr, 0, 0); sem_init(&temp1_rd, 0, 0); sem_init(&temp2_wr, 0, 0); sem_init(&temp2_rd, 0, 0); // Cria as três threads apenas uma vez. }
Criar entrada (menuentry) ISO no Grub
Como gerar qualquer emoji ou símbolo unicode a partir do seu teclado
Instalar o VIM 9.1 no Debian 12
Como saber o range de um IP público?
Muitas dificuldades ao instalar distro Linux em Notebook Sony Vaio PCG-6131L (VPCEA24FM)
Slackpkg+ (Slackpkg Plus) está de volta!
Como dividir duas janelas igualmente e lado-a-lado na sua tela
Como redefinir o diretório Home? (4)
Problemas com adaptadores wifi no Zorin (1)
Ocomon 6.0.1 - Problemas ao editar configurações estendidas (7)