Programación Concurrente

Anuncio
Programación Concurrente
Ejemplos
Jesús Sanz Marcos
e-mail: [email protected]
Barcelona, Spain. 02/01/2001
Productores-Consumidores (Monitores)
typedef struct
{
queue q;
pthread_cond_t notfull,notempty;
pthread_mutex_t m;
} Buffer;
void Buffer_Init(Buffer * t)
{
pthread_mutex_init(&b->m,NULL);
pthread_cond_init(&b->notfull,NULL);
pthread_cond_init(&b->notempty,NULL);
}
void Buffer_Done(Buffer *t)
{
pthread_mutex_destroy(b->m);
pthread_cond_destroy(b->notfull);
pthread_cond_destroy(b->notempty);
}
void Buffer_Put(buffer *b, packet p)
{
pthread_mutex_lock(&b->m);
while (IsFullQueue(&b->q))
pthread_cond_wait(&b->notfull,&b->m);
PutQueue(&b->q, p);
pthread_mutex_signal(&b->notempty);
pthread_mutex_unlock(&b->m);
}
packet Buffer_Get(buffer *b)
{
packet p;
pthread_mutex_lock(&b->m);
while (IsEmptyQueue(&b->q))
pthread_cond_wait(&b->notempty,&b->m);
p = GetQueue(&b->q);
pthread_mutex_signal(&b->notfull);
pthread_mutex_unlock(&b->m);
return p;
}
Lectores/Escritores (Monitores)
typedef struct {
int readers;
int writing;
pthread_cond_t oktoread,oktowrite;
pthread_mutex_t m;
} Table;
void Table_Init(Table * t)
{
pthread_mutex_init(&t->m,NULL);
pthread_cond_init(&t->oktoread,NULL);
pthread_cond_init(&t->oktowrite,NULL);
readers = 0;
writting = FALSE;
}
void Table_Done(Table *t)
{
pthread_mutex_destroy(t->m);
pthread_cond_destroy(t->oktoread);
pthread_cond_destroy(t->oktowrite);
}
void Table_StartRead(Table *t)
{
pthread_mutex_lock(&t->m);
if (t->writting ||
!pthread_cond_empty(&t->oktowrite))
pthread_cond_wait(&t->oktoread, &t->m);
t->readers++;
pthread_mutex_unlock(&t->m);
}
void Tabla_EndRead(Table *t)
{
pthread_mutex_lock(&t->m);
t->readers--;
if (t->readers==0)
pthread_cond_signal(&t->oktowrite);
pthread_mutex_unlock(&t->m);
}
void Table_StartWrite(Table *t)
{
pthread_mutex_lock(&t->m);
if (t->readers>0 || t->writing)
pthread_cond_wait(&t->oktowrite,&t->m);
t->writing = TRUE;
pthread_mutex_unlock(&t->m);
}
void Table_EndWrite(Table *t)
{
pthread_mutex_lock(&t->m);
t->writing = FALSE;
if (pthread_cond_empty(&t->oktoread))
pthread_cond_signal(&t->oktowrite);
else
pthread_cond_broadcast(&t->oktoread);
pthread_mutex_unlock(&t->m);
}
Semáforos con Monitores
int sem_wait(sem_t *sem)
{
pthread_mutex_lock(&sem->m);
if (sem->n>0)
sem->n--;
else
pthread_cond_wait(&sem->anysignal,&sem->m);
pthread_mutex_unlock(&sem->m);
}
int sem_post(sem_t *sem)
{
pthread_mutex_lock(&sem->m);
if (pthread_cond_empty(&sem->anysignal))
sem->n++;
else
pthread_cond_signal(&sem->anysignal);
pthread_mutex_unlock(&sem->m);
}
Monitores con semáforos
typedef struct pthrad_mutex_t;
typedef struct{
int n;
sem_t cond;
} pthread_cond;
int pthread_mutex_init(pthread_mutex_t *m, )
{ return sem_init(m,0,1); }
int pthread_mutex_destroy(pthread_mutex_t *m)
{ return sem_destroy(m); }
int pthread_mutex_lock(pthread_mutex *m)
{ return sem_wait(m); }
int pthread_mutex_unlock(pthread_mutex *m)
{ return sem_post(m); }
int pthread_cond_init(pthread_mutex *c, )
{
c-> n = 0; /* número de procesos bloqueados bajo
la condición */
return sem_init(&c->cond,0,0);
}
int pthread_cond_destroy(pthread_cond *c)
{ return sem_destroy(&c->cond); }
int pthread_cond_wait(pthread_cont*c
,pthread_mutex *);
{
c->n++;
sem_post(m);
sem_wait(&c->cond);
sem_wait(m);
}
int pthread_cond_signal(pthread_cond *c)
{
if (c->n>0)
{
c->n--;
sem_post(&c->cond);
}
return –1;
}
int pthread_cond_signal(pthread_cond *c)
{
for(;c->n>0;c->n--) sem_post(&c->cond);
return –1;
}
Paso de Mensajes
int socketpair_wait(int *sv, int channel)
{
char c;
return read(sv[1-channel], &c, 1);
}
int socketpair_post(int *sv, int channel)
{
char c = ‘p’;
return write(sv[ch],&c,1);
}
int writen(int sd, void *buf, size_t len)
{
size_t nleft = len;
size_t nwritten;
const char *ptr = buf;
while (nleft>0)
{
if ((nwritten=write(sd,ptr,nleft))<=0)
return nwritten;
nleft -= nwritten;
ptr += nwritten;
}
return len;
}
int readn(int sd, void *buf, size_t len)
{
size_t nleft = len;
size_t nread;
const char *ptr = buf;
while (nleft>0)
{
if ((nread=read(sd,ptr,nleft))<0)
return nread;
nleft -= nread;
ptr += nread;
}
return len;
}
Productores-Consumidores (Mensajes)
(Productors)
socketpair_wait(ctl,0);
writen(data[0], &p, sizeof(p) );
socketpair_post(ctrl,0);
(Consumidors)
socketpair_wait(ctl,1);
readn(data[1], &p, sizeof(p));
socketpair_post(ctrl,1);
Wrapper de la función poll (Mensajes)
int waitsel(int timeout, int n, int fd[])
{
int i,n;
struct pollfd fds[n];
for (i=0;i<n;i++)
{
fds[i].fs = fd[i];
fds[i].events = POLLIN;
}
n = poll(fds,n,timeout);
switch(n)
{
case 0: /* timeout */ return –2;
case 1: /* error */ return –1;
default:
for (i=0;i<n && !(fds[i].revents&POLLIN);i++)
return fds[i].fd;
}
}
Lectores/Escritores (Mensajes)
(Lectores)
m->id = reader_id;
m->class = READER;
writen(data[0], &m, siezof(m) );
/* peticiones por cero */
readn(data[1], &ack, sizeof(ack));
/* esperando ACK */
/* leer tabla (...) */
writen(data[1], &m, siezof(m) );
/* liberamos la tabla */
(Lectores)
m->id = writer_id;
m->class = WRITER;
writen(data[0], &m, siezof(m) );
/* peticiones por cero */
readn(data[1], &ack, sizeof(ack));
/* esperando ACK */
/* escribir en tabla (...) */
writen(data[1], &m, siezof(m) );
/* liberamos la tabla */
Documentos relacionados
Descargar