.    

Zamykání souborů v C a v PHP

xChaos 12. března 2006 [9467 znaků] [editováno 6. června 2011] [HowKnow]
★★★ [ + ] 3 [3x] [ - ] [kvalitní[x]]
Zobrazení 11544 ← RSS 11 Facebook 8 Twitter 10 Google 95
Komentářů 3

Pokud chcete z webových skriptů, které mohou běžet ve více kopiích současně zapisovat do nějakého společného souboru (například počítadla přístupů), tak je potřeba se trochu zamyslet nad otázkou zamykání souborů v OS #unix. #programming #linux
Varování: tento článek asi nic neřekne lidem, kteří nic netuší o programování webových aplikací v jazyce PHP. Na druhou stranu - i když tady cituji jistou chybnou implementaci čehosi v jazyce C, tak znalost Céčka není myslím bezpodmínečně nutná. Ale i neprogramátory by možná mohlo zaujmout, že se tady pokouším rozepsat, jaké věci se třeba občas honí hlavou lidem, kteří používají a modifikují programy s otevřeným zdrojovým kódem. Samozřejmě, že většinou se to takhle nerozebírá a nedebatuje se o tom. Jde o to, že samotná práce s programovacími jazyky podle mě v lidské psychice aktivuje určité typy asociací a svérázné "analytické paranoii", které jsou výrazně odlišné od myšlenkových procesů vyvolaných jinými typy lidských i čistě symbolických jazyků - a "programátorské myšlení" pokládám za poněkud zneuznanou (nikoliv ve smyslu finančním - tam jsou dnes programátoři spíše nadhodnocení - ale třeba ve smyslu akademickém...) alternativu klasického "matematického myšlení".

Nemám na mysli schopnost stát se cvičenou opicí, která vynikne v množství namemorovaných HTML tagů, klíčových slov v CSS, nebo koneckonců i shellových příkazů v unixu. Nechci říkat, že nejde o úctyhodnou schopnost - schopnost namemorovat se telefoní seznam je také uctyhodná, a existují lidé, kteří jsou toho schopni. U toho memorování významu různých umělých konstruktů jde dejme tomu o určité odcizení se běžnému lidskému mluvenému i psanému jazyku, a o osvojení si určitě umělé, post-lidské slovní zásoby. Někdy může být zajímavá i schopnost pracovat se symbolickým zápisem např. různých grafických objektů - tam jde v podstatě o obdobu divadelní nebo filmové scénaristiky. Já mám ale na mysli ještě něco jiného - mluvím tady o specificky programátorské paranoie, a o jejích kořenech.

Před lety jsem tady pravda rozjel seriál (1,2,3) o svém programovacím jazyku C<<1, který běžně používám pro psaní některých svých projektů... ale ten zatím nemá implementováno zrovna závratné množství užitečné funkčnosti oproti čistému C... každopádně, jestli někdy na TečceCZ bude vycházet učebnice C, tak to bude rovnou pojaté jako učebnice C<<1 - včetně seznamu Debianích balíků, které bude třeba instalovat pro kompilaci příkladů, apod. Čisté C je dnes opravdu vhodné jen pro zájemce o spolupráci na vývoji linuxového kernelu - a to je cesta, kterou se asi nikdy netroufnu vydat. Ale do toho teď zabředat nechci.

Tématem tohoto článku je zamykání souborů v Unixu. Zamykání sobourů je důležité, pokud do nějakého souboru na disku má zapisovat více programů současně. Je to obecně způsob uvažování, kterého byli programátoři odchovaní 8bitovými hračkovými počítači a DOSem většinou ušetřeni - ale je to zároveň naprostý základ jakéhokoliv multitaskingu. A web je o multitaskingu. Nejjednodušší myslitelnou aplikací zamykání souborů je implementace primitivního počítadla přístupů, vloženého přímo do vašich webových stránek - které ale přitom nebude závislé na externím uložiští dat (např. na SQL databázi.. ony ty externí databáze mě vůbec nějak přijdou jako cesta do pekel, ale to jen můj subjektivní pocit, který nemá cenu řešit). Tedy samozřejmě - filesystém je také úložiště dat. Někdo má rád soubory, a někdo má rád SQL. Důvodem pro nezávislost na SQL může být například to, že někteří webhosteři (například já :-) poskytují svým zákazníkům na serverech SQL databáze jen za (mírný) příplatek. A proč platit několik stovek ročně za funkčnost, kterou někdy lze implementovat pomocí pár řádků v PHP, že ano...

Před časem jsem řešil problematiku zamykání souborů v Céčku. I vás třeba může napadnout vytvořit si jako zámek speciální soubor. To je samo o sobě zbytečné - zamykání bylo v unixech navržené tak, aby šlo zamknout přímo soubor, do kterého zapisujete. Ale to není všechno. Špatně jsem toho zjevně pochopil víc... posuďte sami:


#include <stdio.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <unistd.h>

{
 int f=open(fname,O_RDONLY);
 if(f<0)
 {
  f=open(fname,O_WRONLY|O_CREAT,S_IWRITE|S_IREAD);
  if(f<0)
   return -1;
 }
 while(flock(f,LOCK_EX)==-1)
  sleep(1);
 ...
}
Zejména smyčka while(flock(f,LOCK_EX)==-1) je zjevně nesmyslná.

Služba zamykání souboru je totiž zejména v unixových systémech implementována jako blokující volání jádra - tedy v rámci tohoto volání se čeká, dokud soubor není zamčen. Více detailů viz man flock. Snažit se volat funkci flock() ve smyčce tedy neznamená zkoušet každou sekundu, zda se nám již soubor podařilo zamknout - znamená to regulérně se donekonečna zacyklit, pokud zamčení souboru z nějakého důvodu není možné provést. Což se nepochybně občas dělo - a náš server si nepochybně oddechl ve chvíli, kdy jsem na tuhle chybu přišel a starý program pro počítání návštěv začal vyřazovat.

Protože zveřejnit tady korektní implementaci v Céčku by asi nebylo v dnešní éře masového rozšíření PHP pro moc lidí zajímavé, a já neplánuju dělat tady z toho učebnici Céčka, tak zveřejním korektní příklad zamykání souboru rovnou v PHP.

Zde tedy uvádím jako příklad jednoduché počítadlo návštěv v PHP. Vypadá to opravdu triviálně - ale musím se přiznat, že už asi stárnu, a kvalitu kódu neměřím podle počtu vygenerovaných řádek. Zajímají mě spíš jakási "programátorská haiku" (nebo případně i kóany :-). Jde o to, že napsat kód, který bude něco dělat, je v tomhle případě tak triviální, že i mě samotného překvapilo, že několik prvních pokusů bylo chybných a vedlo k občasnému vyresetování counteru. Poprvé protože jsem flock() nepoužil (myslel jsem, že to PHP dělá samo za mě - nedělá, není pro blbé), podruhé vynulování počítadla zase způsobilo chybné použítí flock() - a to už mě překvapilo natolik, že jsem si řekl, že to je téma na celý článek. Nejsem už zvyklý psát kód, ve kterém by byly chyby - a kdybych to netestoval na firemním portálu s někola tisíci návštěv denně, tak bych si toho třeba všiml až za několik let. Podle mě je to poučné pro všechny bastlíře a lepiče, co zuřivě slepují z dostupných knihoven cokoliv se jim podaří, a neuvědomují si, že jejich výtvory často nezkolabují jenom čirou náhodou a díky nízké návštěvnosti a tím i pravděpodobnosti nějaké kolize...

Podmínkou zprovoznění tohoto primitivního počítadla je existence podadresáře data/ v adresáři, kde je PHP skript uložen, jeho vlastnictví stejným uživatelem, kterému patří PHP skript (předpokládá se užití safe mode), a práva zapisu pro uživatele, pod kterým běží Apache (v Debianu se tento uživatel jmenuje www-data). Funkce flock() volající příslušnou službu unixového jádra se v jayzích C i v PHP jeví definovaná stejně, takže tento příklad může myslím pomoci i Céčkařům:


<?
/* xChaos PHP fragment collection - begin  */
/* the simplest correctly working sql-free hit counter, 20060309 */

$counter=0;
$f=fopen('data/counter','r+');
if($f)
{
 if(flock($f, LOCK_EX))
 {
  $counter=intval(fgets($f,10))+1;
  rewind($f);
 }
}
else
{
 $f=fopen('data/counter','w');
 if($f) flock($f, LOCK_EX);
}

printf("%09d",intval($counter));

if($f)
{
 fputs($f,strval($counter));
 fclose($f);
}
/* xChaos PHP fragment collection - end */
?>

Samotné počítadlo přístupů je samozřejmě aplikace na nic - ale podstatné je, že zamykat by se asi měly všechny soubory, do kterých může přes webové rozhraní a PHP potenciálně zapisovat v jednu chvíli víc než jeden uživatel.

Osobně masové rozšíření PHP nepokládám za příliš šťastné - zejména v případě aplikací, které mají používat tisíce lidí denně současně. Nicméně i když by spolupráci spustitelných programů s Apachem mohlo jít pojmout nějak inteligentněji (nějaká šílenost typu fastcgi), tak je třeba přiznat, že u většiny skriptů je jejich interpretace PHP modulem v Apachi méně náročná, než by bylo odpovídající forkování procesu a spouštění binárního CGI skriptu... a výkon CPU je dnes často to jediné, čeho mají počítače dostatek.

Problém je, že pokud obrovské zvýšení komplexity nějakého systému vede pouze k vyřešení problému jehož složitost je lineární, tak se uživatelům obvykle vyplatí spíše příslušné lineární zvyšení výpočetního výkonu (např. zvýšení počtu CPU).

Na druhou stranu - dva procesoru sežerou 2x tolik elektřiny - a přitom většinu času budou stejně idlovat (česky flákat se). Takže ekologické aspekty související s programováním serverových aplikací lze řešit na dvou frontách: na jedné straně se výrobci snaží za chodu podtaktovávat dnešní předimenzovaná CPU, pokud nejsou pod zátěží, na druhé straně by se o optimalizaci mohli snažit také třeba programátoři webových serverů - kdyby dali uživatelům do rukou mocnější nástroj, než je PHP... no, ale to už s problematikou blokujícího systémového volání pro zamykání soborů v Unixu souvisí jenom vzdáleně... :-)

No, příště se v rubrice Howknow pokusím pro změnu rozepsat o receptech na méně známá DIY bezmasá jídla...


Sloupcová sazba: pokud je okno prohlížeče dostatečně velké (na monitoru s dostatečným rozlišením), zobrazí se článek ve více sloupcích (w3.org). Testováno v browserech Firefox, Opera a Chrome. Není implementováno v Internet Exploreru. Tato feature může způsobovat problémy ve starších verzích prohlížečů s jádrem Webkit (Google Chrome, Safari, Konqueror). Pokud nevidíte článek celý, zkuste zmenšit okno prohlížeče nebo použít verzi pro tisk. [zpět na začátek sloupcové sazby]
Pokud se vám článek líbil, zkuste autora podpořit [zobrazit možnosti]
Sdílet v síti [Identi.ca - musíte být předem přihlášeni] [Twitter] [Facebook] [Jagg.cz]
Formátovat pro tisk [bez komentářů] [s komentáři]
Krátká forma URL (adresy) [http://teckacz.cz/381]
Všechny články [od autora xChaos] [v rubrice HowKnow] [nejnovější]

Hodnocení článku čtenáři [ + ] 3 [3x] [ - ]
Tip: Pro moderaci článků (kladné nebo záporné hodnocení) je nutné použít browser, který podporuje javascript a cookies.
Komentáře čtenářů [napsat vlastní]
Skrýt hodnocené nebo méně


[] Vitex 14. března 2006 ← komentářů 43 ☯☯ 17 [43x]
[ + ] 0 [0x] [ - ] ← pro ohodnocení komentáře se není nutné nikde registrovat
→ [/-/9546] ← na komentář můžete odpovědět nebo ho sdílet
Mě se poslední dobou PHP líbí i na věci, jenž byly donedávna doménou BASHe a PERLu - tzn. systémové scripty. Filozofie jazyka hluboce čerpá a inspiruje se vším, co bylo dříve a v rámci možností se snaží brát si ze svých předchůdců to nejlepší.

[] Tomáš_Mráz 14. března 2006 ← komentářů 304 64 [240x]
[ + ] 0 [0x] [ - ] ← pro ohodnocení komentáře se není nutné nikde registrovat
→ [/-/9553] ← na komentář můžete odpovědět nebo ho sdílet
Hmm mně taky připadá PHP, jako když pejsek s kočičkou vařili dort.
(Samý dobrý věci, ale když se toho hodně sní, tak vám bude 14 dní špatně.)

[] xChaos 14. března 2006 ← komentářů 5520 0 [3050x]
[ + ] 0 [0x] [ - ] ← pro ohodnocení komentáře se není nutné nikde registrovat
→ [/-/9555] ← na komentář můžete odpovědět nebo ho sdílet
Já nejsem žádnej purista, já proti PHP nemám ani tak estetický výhrady (koneckonců je to skoro stejný jako C), jako spíš výhrady co se týče výkonu (je to interpretované), a toho, že obecně to používají lidi, co neuměj programovat ve víceúlohovém prostředí (minimum je používat to zamykání souborů).
 

Počet zobrazených komentářů: 3 [celkový čas potřebný k prohledání databáze a vytvoření stránky: 0.55 sekund]

Pozor, vložením komentáře souhlasíte s pravidly hry TečkyCZ! [zobrazit pravidla] →
Ochrana proti spambotům - tři-krát-tři je ... ? (napište číslicí - nemělo by byt potřeba při zapnutém JavaScriptu)
Sociální síť (přihlaste se předem, 1. řádek<=96 znaků=status, zbytek=odkaz)
Offtopic resolver (týká se odpověď původního tématu, nebo patří jinam?)
Přezdívka (povinně) - nepoužívejte speciální znaky, mezery=podtržítka
E-mail (volitelně) - nebude zobrazen, zobrazí se ikonka z [www.gravatar.com]

Nelze použít HTML [zobrazit mikrosyntax] →

Nápověda: ve vlastním zájmu uvádějte u komentářů pouze funkční a dostupnou e-mailovou adresu. Přezdívku, která je jednou spojená s konkrétní e-mailovou adresou, už nyní nelze bez zásahu administrátora serveru spojit s jinou adresou. Uvedením neplatné e-mailové adresy si v budoucnu znemožníte upload ikonky i možnost použít některé další chystané neanonymní funkce vázané na uvedení platné e-mailové adresy.


TečkaCZ [Nejnovější články] [Nejnovější komentáře] [Zeď vzkazů] [Zeď odkazů] [Začátek článku]

    TečkaCZ
  •  
  • Komentáře →
  • Nástěnky →
  • Debaty →
  • Články →
  • Ročníky →
  • Rubriky →
  • RSS kanály →
  • Vzhled →
  • Ostatní →
  •  
[] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] []
  •  
.

[Arachne Labs]

[SPOJE.NET]

[Právě dnes | Tech | Ostatní]

Yacy P2P web search jabber.arachne.cz
tiskové zprávy a otevřené dopisy přebíráme z nejrůznějších informačních kanálů (i bez výslovného souhlasu autorů)
licenční práva k použitým obrázkům a grafickým motivům nejsou definována (přebírejte pouze texty bez obrázků)
texty článků i komentáře bez uvedení copyrightu jsou chráněny GNU Free Documentation License
založeno na Quzo engine, (G)1999-2002 David Čermák, (G)2002-2012 Michael Polák
Quzo engine vyvíjejí Arachne Labs, webhosting sponzorují SPOJE.NET
seznam aktuálních článků je dostupný i ve formátu RSS (XML)
můžete také sledovat Twitter feed TečkyCZ.
test XHTML a CSS2 validity