3. feladat

Feladva okt. 12-18, 2009

Határidő nov. 7, 2009

Osztott memória - szinkronizálás nélkül

 Feltöltendő állomány(ok) neve: S03_nn_xxxxxxxxx(_aa).c ahol nn - feladat száma; xxxxxxxxx - felhasználó azonosítója a linux szerveren; (aa - az illető állomány funkcionalitásának valamilyen ismertető jegye több modul használata esetén).

 

  1. Hozzunk létre két folyamatot: az egyik ismételten ír (véletlenszerűen generált időközönként) egy osztott memória részben tárolt körkörös pufferbe, a másik pedig ismételten olvas (szintén véletlenszerűen generált időközönként). Futtassuk a két folyamatot úgy, hogy világossá váljon a két folyamat szinkronizálásának szükségessége ahhoz, hogy biztosítva legyen az, hogy az olvasó folyamat helyes adatokat olvasson. Helytelen adatoknak nevezzük az olyan kiolvasott adatok sorozatát, amely különbözik az előzőleg beírt adatsorozattól. Ennek érdekébe az író és az olvasó folyamat is írja ki az éppen beírt/kiolvasott adatot.

 

  1. Írjunk egy C programot, mely X-0 játékot játszik egy másikkal. A két folyamat közötti információcsere egy osztott memória területen keresztül történik. A programnak ellenőriznie kell, hogy csak két példányban fut-e.

 

  1. Létrehozunk egy osztott memória területet, melyet két "torpedózó" játékos használ. Az osztott-memória terület tartalmaz egy játékos-azonosítót, a célpont sor- és oszlopszámát, és egy 0 (ha az előző lövés talált) vagy 1 (ha az előző lövés nem talált) vagy -1 (ha az előző lövés teli találat volt) értéket. Egy játékos csak akkor lép be a játékba, ha nincs még két játékos, aki már játszik. A játékosnak megfelelő programban egy 12x12-es mátrixot generálunk, melyen 7 egymás utáni (vízszintes vagy függőleges) pozíciót megjelölünk. A következő célpont kijelölése vagy a billentyűzetről történik vagy egy intelligens algoritmus segítségével.

 

  1. Írjunk programot, mely létrehoz egy osztott-memória területet, egy 0 és 1 értékeket tartalmazó mátrixszal. Egy másik program n másodpercenként soronként végigjárja a mátrixot, és amennyiben valamelyik mátrixelem szomszédságában több, mint 5 b. 1-es érték van, akkor ez az elem értéke is 1 lesz, ha pedig több, mint 5 0-s szomszédja van, 0-vá válik ő is. Az a folyamat, amelyik létrehozta az osztott-memória területet, kiírja a mátrixot mindaddig, ameddig az már nem változik többé. (vigyázat! A mátrixot módosító folyamat külön tartsa nyilván a mátrix korábbi értékét, és annak alapján módosítsa az osztott memóriába írt mátrixelemeket.)

 

  1. Egy program létrehoz egy osztott-memória területet, egy 0 és 1 értékeket tartalmazó mátrixszal. Egy másik program n másodpercenként oszloponként végigjárja a mátrixot, és amennyiben valamelyik mátrixelem szomszédságában 5 db. 1-es érték van, akkor ez az elem értéke is 1 lesz, ha pedig 5db. 0-s szomszédja van, 0-vá válik ő is. Az a folyamat, amelyik létrehozta az osztott-memória területet, kiírja a mátrixot mindaddig, ameddig már nem változik többé. (vigyázat! A mátrixot módosító folyamat külön tartsa nyilván a mátrix korábbi értékét, és annak alapján módosítsa az osztott memóriába írt mátrixelemeket.)

 

 

  1. Írjunk C programot, mely (azonosító, jelzés) adatpárok sorozatát írja ismételten egy osztott-memória területre. Amint befejezte az írást, egy jelzést küld egy másik folyamatnak, mely olvashatja a sorozatot. A második folyamat minden egyes adatpár esetén elküldi a megadott jelzést az adott azonosítóval rendelkező folyamatnak.

 

  1. Írjunk folyamatot, mely létrehoz egy osztott-memória területet. Egy másik folyamat, valahányszor indul vagy befejeződik, mindig ír az osztott-memória területre; az indításkor egy sajátos adatot, befejezéskor pedig egy másik, a befejezésre jellemző adatot. Az első folyamat időnként végigjárja az osztott-memória területet és információt ír ki azokról a folyamatokról, amelyek kényszerű módon fejeződtek be (azok, amelyeknek nem sikerült a befejezésre jellemző információt írniuk, ugyanakkor már nem futnak. Ez utóbbi ellenőrzésére használhatunk  shell scriptet).

 

 


Tippek / gyakori hibák

  • Egyes feladatoknál (pl. 2, 3) fontos, hogy a két folyamat felváltva írjon az osztott memória területre. Más lehetőség híján ezt egyelőre a felhasználó oldhatja meg úgy, hogy futtatáskor előbb az egyik, majd a másik játékos ír be adatot.
  • Más esetben, ha növelni szeretnénk annak a valószínűségét, hogy egyik folyamat már elvégezte feladatát, mire egy másik lefut, (jobb híján) kísérletezhetünk késleltetés (sleep) bevezetésével vagy figyelhetjük egy osztott memória változó értékét (egyik sem ideális megoldás, még akkor sem, ha úgy tűniuk, hogy "működik").
  • ha szükséges, mégis végezhetünk szinkronizálást jelzések segítségével
  • az osztott memória területek (az üzenetsorokhoz, illetve szemaforokhoz hasonlóan) rendszer szintű erőforrások, és a számukra fenntartott hely korlátozott, ezért rendszeresen töröljük az általunk létrehozottakat.
    Ha a C programból nem sikerült törölni (shmctl) egy osztott memória részt, az alábbi shell parancsokat használhatjuk erre:
    > ipcs - információ a létező osztott memória részekről/ szemaforokról / üzenetsorokról
    > ipcrm - erőforrás törlése (lásd man)
  • Az osztott memóriát használó folyamatok külön indítható programok legyenek. A feladat jellegétől függően lehet, hogy elég egyetlen programot írnunk, amiből pl. kettőt indítunk, különböző paraméterekkel, viszont semmiképp ne szülő-gyerek folyamatot írjunk.