TwojePC.pl © 2001 - 2024
|
|
A R C H I W A L N A W I A D O M O Ś Ć |
|
|
|
[SOFT] PHP, flock i zjawisko deadlock , bwana 14/06/03 08:59 Krotka pilka:
Jak zapewnic sobie sekcje krytyczne w PHP? Chodzi mi o sytuacje, kiedy 2 skrypty php probuja zablokowac na wylacznosc dwa pliki, ale robia to w roznej kolejnosci:
Skrypt1: Blokuje Plik1
Skrypt2: Blokuje Plik2
Skrypt1: Chce zablokowac Plik2, ale nie moze, bo czeka na zakonczenie Skryptu1 (w wlasciwie odblokowanie w nim Pliku1)
Skrypt2: Chce zablokowac Plik1 (ale nie moze, bo... wiadomo)
Takie sytuacje (czyli deadlock) mozna ominac, jesli na poczatku kazdy skrypt bedzie probowal zablokowac sobie od razu oba pliki, i w obu przypadkach bedzie to sie dzialo w tej samej kolejnosci (wtedy skrypt ktory zacznie pierwszy, zrobi wszystko od razu, a ten drugi bedzie czekal troche dluzej, ale za to oba maja szanse zakonczyc sie).
Zeby miec pewnosc, ze takie "zablokowanie z wyprzedzeniem" powiedzie sie, trzeba zapewnic sobie, ze obie instrukcje:
{
flock($plik1...
flock($plik2...
}
wykonaja sie tak jak w sekcji krytycznej, czyli, ze serwer wykona je "ciurkiem" bez wyskakiwania do wykonywania innego skryptu. Jak to uzyskac w PHP?
Podobnie potrzebne jest to chyba w sytuacji takiej:
if (flock($plik, LOCK_EX + LOCK_NB))
{
// ryzyko!
flock($plik, LOCK_EX);
}
W linii opisanej komentarzem "ryzyko!" moze dojsc do tego, ze inny watek na serwerze stanie sie aktywny, i wlasnie w tym momencie zablokuje ten sam plik na ktory wskazuje uchwyt $plik - czyli wartosc wyrazenia w if() zdezaktualizuje sie bez naszej wiedzy. Potrzebne jest wiec znowu cos w rodzaju sekcji krytycznej, ktora obejmie cale wyrazenie if().
Jak to rozwiazac?"you don't need your smile when I cut
your throat" - hmm , bor@s 14/06/03 10:08
rozproszone dawno miałem... ale może uda się ręcznie zaimplemenentować sekcje krytyczną. Były jakieś algorytmy (Dijsktry, piekarski). Wiele już nie pamiętam. Jakbym odświeżył sobie wiedzę, to może coś napiszę.- hmm2 , bor@s 14/06/03 10:20
a może można nawet prościej: pozakładać semafory
sem_acquire
sem_get
sem_release
sem_remove
warunkiem oczywiście jest to, że każdy proces odwołujący się do tych plików z nich korzysta.- no wlasnie nie da rady chyba , bwana 14/06/03 17:16
przynajmniej nie na Windowsie (a to wlasnie wchodzi w gre). Z dokumentacji PHP wynika, ze semafory mozna wprowadzic na SYSTEM V, o Windows ani slowa.
Sprobuje skorzystac z pamieci dzielonej, ale najpierw musze sie upewnic, czy sa niepodzielne operacje dostepu do pamieci dzielonej (czyli wlasnie otoczone sekcja krytyczna , czy tez - w windowsie - mutexem) - na 99% takie tez powinny byc, bo inaczej byloby to bez sensu."you don't need your smile when I cut
your throat" - ach ten Windows , bor@s 14/06/03 17:25
:) niby system zapewnia te mechanizmy, bo widziałem kiedyś odpowiednie polecenia systemowe WinAPI. Dziwne by było gdyby Apache z tego nie korzystał.- ano ach:) Windows ma i pamiec dzielona, i semafory i mutexy , bwana 14/06/03 17:47
sam serwer www (w moim przypadku to xitami) nie gra tu roli (chociaz na pewno je musi wykorzystywac;-D) tylko silnik php - to on musi zapewnic niepodzielnosc takich operacji jak lock i unlock, flock itp. (tych phpowych, nie systemowych). Tylko ze sam jezyk ich nie "upublicznia" dla kodera php w niektorych systemach."you don't need your smile when I cut
your throat"
- W ogole - po sieci snuje sie makabryczny przyklad blokowania - licznik odwiedzin , bwana 14/06/03 17:53
Jest w kilku miejscach, np. tutaj http://php.spinacz.pl/...41.html?id=41&npnum=5
(u dolu strony). Jest napisany tak, ze jesli np. 5 osob jednoczesnie wykona ten skrypt a potem (dzieki blokowaniu) juz kolejno zapisze do pliku zwiekszona wartosc licznika, to niestety, na koniec wartosc licznika bedzie wieksza o 1 a nie o 5 (w najgorszym przypadku).
Ponizej moj przykladowy licznik, ktory jest wolny od tego bledu (bardzo uproszczony ale tu nie sourceforge;-D):
if ($plik=fopen("licznik.txt", "r+"))
{
flock($plik, LOCK_EX);
$liczba=fgets($plik);
if (!$liczba)$liczba=1;
else $liczba++;
fseek($plik, 0);
fputs($plik, $liczba) ;
flock($plik, LOCK_UN);
fclose($plik);
print "Odwiedziny nr: $liczba";
}
Moze licznik to pierdola, ale bledny schemat postepowania przy oprogramowywaniu innych zadan moglby zdrowo namieszac."you don't need your smile when I cut
your throat" |
|
|
|
|
All rights reserved ® Copyright and Design 2001-2024, TwojePC.PL |
|
|
|
|