15. Конкуренция: взаимно изключване и синхронизация
Задачата на писатели/читатели.
 
5.7 Задачата на писатели/читатели.
    Данни (файл, блок от паметта) се използват от няколко процеса. Някои от процесите само четат тези данни - читатили, а други само променят данните - писатели. Следните условия трябва да се спазват:
   1. Произволен брой читатели могат да четат едновременно данните;
   2. Само един писател може да пише данни;
   3. Ако писател пише, никой читател не може да чете.
    Ако всеки процес може и да пише и да чете, общото решение за ВИ работи.
    Ако един процес може или само да чете, или само да пише - общото решение е неприемливо, а съществуват и по-ефективни решения.

** Предимство на читателите.
/* program readers_and_writers */
int readcount;
semaphore x = 1, wsem = 1;

void reader()
{ while (true)
  {
   wait(x);
   readcount++;
   if (readcount==1) wait(wsem);
   signal(x);
   READUNIT();
   wait(x);
   readcount--;
   if (readcount==0) signal(wsem);
   signal(x);
  }
}
void writer()
{
 while (true)
 {
  wait(wsem);
  WRITEUNIT();
  signal(wsem);
 }
}
 
 

 

void main()
{ readcount = 0;
  parbegin(reader, writer);
}

** Предимство на писателите.
/* program readers_and_writers */
int readcount, writecount;
semaphore x = 1, y = 1, z = 1, wsem = 1, rsem = 1;
 

void reader()
{ while (true)
  {
   wait(z);
   wait(rsem);
   wait(x);
   readcount++;
   if (readcount==1) wait(wsem);
   signal(x);
   signal(rsem);
   signal(z);
   READUNIT();   /* {КС} */
   wait(x);
   readcount--;
   if (readcount==0) signal(wsem);
   signal(x);
  }
}
void writer()
{
 while (true)
 {
  wait(y);
  writecount++;
  if (writecount==1) wait(rsem);
  signal(y);
  wait(wsem);
  WRITEUNIT();  /* КС */
  signal(wsem);
  wait(y);
  writecount--;
  if (writecount==0) signal(rsem);
  signal(y);
 }
}
void main()
{
 readcount = writecount = 0;
 parbegin (reader, writer);
}
    Общо предназначение на семафорите:
- x - коректната работа с обща глобална променлива readcount;
- y - коректната работа с обща глобална променлива writecount;
- z - осигурява предимство на писателите;
- rsem - свободно за четене (няма писател в КС);
- wsem - свободно за писане (няма читатели в КС).
    Двойката семафори z и rsem осигуряват най-много един читател на опашка за семафора rsem, което позволява преминаването на първият писател през този семафор. Така се дава предимството на писателите.
 
Състояния на системата: Състояния на семафорите wsem, rsem и z:
Само читатели в системата - wsem - 1
- няма опашки
Само писатели в системата - rsem - 1
- опашка от писатели на wsem
Много читатели четат, идва писател - wsem е затворен (от първия читател); rsem е отворен;
- писателят минава и затваря rsem;
- писателят чака на wsem;
- следващият идващ читател затваря z и чака на rsem;
- всички други идващи читатели чакат на z;
- последният читател, завършил четенето, отваря wsem;
Последен писател пише, чакат читатели - wsem е затворен (от пишещия писател);
- опашките са както в предишния случай;
- писателят свършва и отваря wsem;
- писателят отваря rsem;
- читателят, чакащ на rsem минава, отваря z и чете;