-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadersAndWriters.c
93 lines (67 loc) · 1.78 KB
/
readersAndWriters.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
$ gcc readersAndWriters.c -o readersAndWriters.out -lpthread
*/
#define _REENTRANT
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define MAX_THREADS 128
#define p(s) {printf s;fflush(stdout);sleep(1);}
/* por defecto 20 threads */
int numthreads = 20;
/* rutinas de los threads */
void *lector(void *);
void *escritor(void *);
/* vector de rutinas de lectores y escritores (ratio lect/escr = 2) */
void *(*rutina[3])(void *)={escritor,lector,lector};
pthread_t tid[MAX_THREADS]; /* array de IDs thread (identificadores) */
/* semaforos */
sem_t x,escr;
/* variables globales */
int contador; /* para llevar el orden de llegada de las peticiones */
int cont_lect;
int main(int argc, char *argv[])
{
int i,n=0;
if (argc>1) n=atoi(argv[1]);
if ((n>0) && (n<=MAX_THREADS)) numthreads=n;
contador=0;
cont_lect=0;
sem_init(&x, 0, 1);
sem_init(&escr, 0, 1);
/* crear aleatoriamente lectores y escritores */
for (i=0;i<numthreads;i++)
pthread_create(&tid[i], NULL, rutina[rand()%3], (void *)i);
/* esperar a que terminen todos */
for (i=0;i<numthreads;i++)
pthread_join(tid[i],NULL);
p(("Acabaron todos los threads ...\n"));
exit(0);
}
void * lector(void *arg)
{
int n=(int)arg; /* cardinal */
p(("L%d quiere leer.\n",n));
sem_wait(&x);
cont_lect++;
if (cont_lect==1) sem_wait(&escr);
sem_post(&x);
p(("L%d LEE !!!\n",n));
sleep(rand()%3);
p(("L%d termina de leer.\n",n));
sem_wait(&x);
cont_lect--;
if (cont_lect==0) sem_post(&escr);
sem_post(&x);
}
void * escritor(void *arg)
{
int n=(int)arg; /* cardinal */
p(("E%d quiere escribir.\n",n));
sem_wait(&escr);
p(("E%d ESCRIBE !!!\n",n));
sleep(rand()%3);
p(("E%d termina de escribir.\n",n));
sem_post(&escr);
}