#include #include #include #include #define OBS 3 void Alterador(void*); void *Observador(void*); typedef void (*cb_t) (void *info); typedef struct { cb_t cb; void *cbinfo; } desc; struct { desc observadores [OBS]; int obsregistrados; int valorobservado; pthread_mutex_t submutex; } dadossub = { {}, 0, 0, PTHREAD_MUTEX_INITIALIZER}; pthread_mutex_t obsmutex = PTHREAD_MUTEX_INITIALIZER; void main(argc, argv) int argc; char *argv[]; { int erro; int i; int *id; pthread_t tid[OBS]; for (i = 0; i < OBS; i++) { id = (int *) malloc(sizeof(int)); *id = i; erro = pthread_create(&tid[i], NULL, Observador, (void *) (id)); if(erro) { printf("erro na criacao do thread %d\n", i); exit(1); } } Alterador(NULL); } void Altera (int novo) { int i; pthread_mutex_lock(&dadossub.submutex); dadossub.valorobservado = novo; printf ("SUB: registrei novo valor %d - vou avisar observadores\n", dadossub.valorobservado); for (i=0; i< dadossub.obsregistrados; i++) dadossub.observadores[i].cb(dadossub.observadores[i].cbinfo); pthread_mutex_unlock(&dadossub.submutex); } void Alterador(void *i){ int v; for (v=1; v<10; v++) { sleep(3); Altera(v); } } void registraObservador (cb_t f, void *i) { pthread_mutex_lock(&dadossub.submutex); dadossub.observadores[dadossub.obsregistrados].cb = f; dadossub.observadores[dadossub.obsregistrados].cbinfo = i; dadossub.obsregistrados++; pthread_mutex_unlock(&dadossub.submutex); } int leValor() { int valor; pthread_mutex_lock(&dadossub.submutex); valor = dadossub.valorobservado; pthread_mutex_unlock(&dadossub.submutex); return valor; } void Avisa (void * conddele) { pthread_mutex_lock(&obsmutex); pthread_cond_signal((pthread_cond_t *)conddele); pthread_mutex_unlock(&obsmutex); } void EsperaAvisos(int meuid, pthread_cond_t *minhacond) { int valoratual; while(1) { valoratual = leValor(); printf("OBS %d: viu valor %d \n", meuid, valoratual); pthread_mutex_lock(&obsmutex); pthread_cond_wait(minhacond, &obsmutex); pthread_mutex_unlock(&obsmutex); } } void *Observador(void* id){ pthread_cond_t *minhacond; int meuid = *(int *) id; printf("OBS %d: iniciando\n", meuid); minhacond = (pthread_cond_t *) malloc(sizeof(pthread_cond_t)); if (pthread_cond_init(minhacond, NULL)) { printf("erro na inicializacao de condicao %d \n", meuid); exit(1); } registraObservador(Avisa, (void *) minhacond); EsperaAvisos(meuid, minhacond); }