(* P0 *) (* P1 *) wait(S); wait(T); wait(T); wait(S); ... ... signal(S); signal(T); signal(T); signal(S);
(* P *) (* C *) producir nextp sacar nextc de buffer poner nextp en buffer consumir nextc
(* P *) (* C *) producir nextp wait(lleno); poner nextp en buffer sacar nextc de buffer signal(lleno); consumir nextc
(* P *) (* C *) producir nextp wait(lleno); wait(vacio); sacar nextc de buffer poner nextp en buffer signal(vacio); signal(lleno); consumir nextc
(* P *) (* C *) producir nextp wait(lleno); wait(vacio); wait(mutex); wait(mutex); sacar nextc de buffer poner nextp en buffer signal(mutex); signal(mutex); signal(vacio); signal(lleno); consumir nextc¶ mutex tiene un valor inicial de 1.
wait(dde); ...escribir... signal(dde);
wait(dde). Pero no podemos usar lo mismo código como los
escritores. ¿Por qué? Porque entonces solamente un lector puede
leer a la vez.
wait(mutex);
readcount := readcount + 1;
if readcount = 1 then wait(dde)
signal(mutex);
...leer...
wait(mutex);
readcount := readcount - 1;
if readcount = 0 then signal(dde)
signal(mutex);
¶ Tenemos que controlar los accesos al readcount con un
semáforo mutex.
¶ ¿Es la solución justa? No. Los escritores pueden esperar sin límite.
¶ Problema: deadlock.
¶ Problema: inanición.
acquire(s)
if s.value = 1 then s.value = 0
else begin
poner el proceso en s.queue
bloquear
end
release(s)
if s.queue es vacio then s.value = 1
else begin
sacar un proceso P de s.queue
despertar P
end