Autor | Zpráva | ||
---|---|---|---|
klus. Profil * |
#1 · Zasláno: 5. 8. 2011, 18:52:13
Ahoj. Zajímám se o problematiku zápisu do stejného textového souboru. Vytvářím logování do souboru, ale bojím se, že kdyby 2 procesy měly otevřený stejný soubor, budou si navzájem přepisovat data. Teoretické řešení nabízí funkce flock, ale ta podle ohlasů také nebude dokonalá. Pokud budu chtít otevřít (fopen) zamknutý soubor - co se stane? Selže otevření nebo selže až případné čtení / zápis? A pokud bude soubor už zamčený, jak se chovat? Čekat ve smyčce dokud se neuvolní zámek?
|
||
Majkl578 Profil |
#2 · Zasláno: 5. 8. 2011, 19:20:15 · Upravil/a: Majkl578
Můžeš se atomickými operacemi v Nette (třídou Nette\Utils\SafeStream), případně ji rovnou použít, neměla by mít žádné závislosti na zbytku Nette. Použití je snadné, je vidět v dokumentaci. Sama
flock využívá. Jediné co musíš sám udělat je manuální registrace:
Nette\Utils\SafeStream::register(); safe:// používat.
|
||
klus. Profil * |
#3 · Zasláno: 5. 8. 2011, 22:44:25
Prostudoval jsem tu třídu a tímto způsobem do souborů standardně zapisuji, jen si neregistruji vlastní stream. Když použiju fopen('nejakyprotokol://stream.str') a poté znovu fopen('nejakyprotokol://stream.str') - odstartuje nový stream resp. v případě SafeStream pokus o nové otevření souboru nebo se to připojí k již existujícímu streamu - jen abych pochopil jak streamy v php fungují - z manuálů moc moudrý nejsem.
|
||
Majkl578 Profil |
#4 · Zasláno: 5. 8. 2011, 23:13:01
klus.:
„a poté znovu“ Přemýšlím, proč bys tohle úmyslně dělal. Cílem je přece otevřít soubor, přečíst/zapsat bezpečně data a pak soubor uvolnit. Ve chvíli, kdy je soubor aktuálně otevřen, ostatní připojení čekají až do odemčení (jakoby zamrznou). V tvém vlastním zájmu přeci není blokovat spojení, ale jen přečíst/zapsat a hned zas uvolnit. Otevírat 1 soubor 2× v jednom scriptu přes safe stream způsobí zamrznutí, protože 2. otevření bude čekat do uzavření prvního. Jak to funguje ve více vláknech si můžeš zkusit jednoduše sám. Otevři script obsahující následující kód ve více oknech prohlížeče (s prodlevou pár vteřin): require '/www/.../Nette/Utils/SafeStream.php'; Nette\Utils\SafeStream::register(); $a = fopen('safe:///tmp/test', 'w+'); sleep(5); fclose($a); |
||
Davex Profil |
#5 · Zasláno: 5. 8. 2011, 23:42:40
klus.:
Pro účely logování bys mohl využít toho, že je zápis do souboru otevřeného v módu append ( fopen('soubor', 'a') nebo file_put_contents('soubor', $data, FILE_APPEND) ) atomický (minimálně na Linuxu) a není nutné používat flock() . Pokud ho nebudeš paralelně otevírat v jiném módu, tak by s tím neměl být problém.
|
||
klus. Profil * |
#6 · Zasláno: 5. 8. 2011, 23:44:46
Ano, to je vlastnost flocku. Toto také čeká v případě použití zámku jedním procesem:
while(true) { $fp = fopen("/tmp/lock.txt", "w+"); echo "oteviram\n"; if (flock($fp, LOCK_EX)) { // do an exclusive lock echo "otevreno\n"; sleep(5); ftruncate($fp, 0); // truncate file fwrite($fp, "Write something here\n"); flock($fp, LOCK_UN); // release the lock } else { echo "selhalo\n"; echo "Couldn't get the lock!"; } fclose($fp); echo "zavreno\n\n"; sleep(1); Mě by zajímalo, zda pokud mám otevřený stream a otevřu ho znovu (třeba v jiném php procesu), zda se připojí na již otevřený stream nebo zda vytvoří nový a fopen vrátí handler nového streamu - v takovém případě nemá přístup k souboru přes stream jiný význam než ušetření pár řádek kódu. Jenom mě zajímají vlastnosti streamu v php. |
||
Časová prodleva: 13 let
|
0