next up previous contents
Next: Kivételes események kezelésének Up: Rendszerhívások Previous: Egyébfájlokkal kapcsolatos

Fájlok konkurrens elérése

Ebben a részben arról lesz szó, hogy a UNIX milyen szolgáltatásokat nyújt párhuzamos folyamatok fájlhozzáférésének a szinkronizálására. A UNIX a fájlok konkurrens kezelésekor kialakult problémás helyzeteket a korábban már ismertetett rekord-lefoglalás lehetoségét biztosítja. A rekord-lefoglalás az fcntl() rendszerhívás segítségével implementálható a következokben leírtak szerint (az fcntl() használatához szükség van az <fcntl.h> fájl include-olására is).

A UNIX rekord-lefoglalása kétféle lehet: írási vagy olvasási célú. A ketto közötti lényeges különbség az, hogy egy rekordterületet (azaz a fájl egy bizonyos intervallumát) írás céljából egyszerre legfeljebb csak egy folyamat foglalhatja le, és csak akkor, ha azt a részt senki más nem foglalta még le sem írási sem pedig olvasási szándékkal); továbbá meg kell említeni, hogy olvasási célú rekordterület lefoglalást egyidejuleg több folyamat is kérheti akár ugyanarra a rekord-területre is. Fontos tudni, hogy a párhuzamos folyamatok kölcsönös kizárása az fcntl() rendszerhívásnál valósul meg, és nem a fájlmuveleteknél: vagyis ha valamelyik folyamat nem tartja be a rekord-lefoglalási szabályokat, akkor az operációs rendszer megengedi neki, hogy kedve szerinti módosításokat illetve olvasásokat végezzen a fájlon, de az eredmény korrektségét ilyenkor nem lehet garantálni.

Az fcntl() rendszerhívás a következoképpen használható:

  struct flock lock_data;
  int fd, cmd, rc;

  ...

  rc=fcntl(fd,cmd,&lock_data);

A rendszerhívás hatására az fd fájldeszkriptorral azonosított fájl lock_data argumentumban megadott része a cmd argumentumban megadott módon lefoglalásra kerül. A rendszerhívás írási célú rekord-lefoglalás esetén sikertelen lesz, ha a fájlra nincs írási engedélyünk.

A rekordlefoglalás módja (a cmd argumentum értéke alapján) háromféle lehet:

Most áttekintjük a lock_data argumentum egyes komponenseinek a szerepét (vagyis azt, hogy az flock struktúra egyes komponensei mit hogyan írhatnak le):

struct flock {
       short l_type;
       short l_whence;
       off_t l_start;
       off_t l_len;
       pid_t l_pid;
};

A rekordlefoglalás használatára lássuk a következo példát:

#include <fcntl.h>
#include <stdio.h>

main(int argc, char **argv)
{
  struct flock lock_data;
  int fd, cmd, rc, rf;

  fd=open("probafile",O_RDWR);
  rf=fork();
  lock_data.l_whence=SEEK_SET;
  lock_data.l_start=0;
  lock_data.l_len=10;
  if (rf==0) {
    lock_data.l_type=F_RDLCK;
    rc=fcntl(fd,F_SETLK,&lock_data); /* gyermek */
    fprintf(stderr,"Gyermek  tovabbfutott!\n");
    sleep(5);
    lock_data.l_type=F_UNLCK;
    rc=fcntl(fd,F_SETLK,&lock_data); /* gyermek */
  } else {
    sleep(1);
    fprintf(stderr,"Szulo: elkezd futni a lock elott ...\n");
    lock_data.l_type=F_WRLCK;
    rc=(-1);
    while (rc==(-1)) {
      rc=fcntl(fd,F_SETLK,&lock_data); /* szulo */
      if (rc==(-1)) fprintf(stderr,"Szulo:  SETLK sikertelen ... ujraprobalom\n");
      sleep(1);
    }
    fprintf(stderr,"Szulo lockolt es tovabbfutott!\n");
  }
  close(fd);
}

A program elindulása elott hozzunk létre egy probafile nevu fájlt, amire van írási jogunk (én ezt úgy tettem, hogy a gépem jelszófájlját átmásoltam erre a névre abba a directoryba, ahol a programot futtatni akartam).

A program elindulása után kettéágazik: szül egy gyermekfolyamatot. A gyermek lefoglalja olvasási céllal a probafile fájl elso 10 karakterét, és vár 5 másodpercig, mialatt a lefoglalást fenntartja, majd 5 másodperc után a lefoglalást megszunteti, majd lezárja a fájlt. A szülo vár 1 másodpercet, majd ciklusban másodpercenként egyszer megpróbálja lefoglalni a fájl elso 10 karakterét írási céllal.

A program futtatásakor a következoket írja ki a szabványos hibacsatornára:

Gyermek  tovabbfutott!
Szulo: elkezd futni a lock elott ...
Szulo:  SETLK sikertelen ... ujraprobalom
Szulo:  SETLK sikertelen ... ujraprobalom
Szulo:  SETLK sikertelen ... ujraprobalom
Szulo:  SETLK sikertelen ... ujraprobalom
Szulo lockolt es tovabbfutott!

Ez értheto, mert a szülo folyamat 1 másodpercet vár, majd utána próbálja meg lefoglalni 1 másodpercenként a fájlt, és ez csak azután sikerül, miután a gyermeke a fájlt már nem foglalja olvasási céllal.



next up previous contents
Next: Kivételes események kezelésének Up: Rendszerhívások Previous: Egyébfájlokkal kapcsolatos



Csizmazia Balazs
Tue Apr 2 00:06:27 MET DST 1996