Sdílení paměti pomocí mapování souborů (3. díl) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



Delphi

Sdílení paměti pomocí mapování souborů (3. díl)

sdileni pameti

23. srpna 2002, 00.00 | V tomto dílu seriálu dokončíme serverovou část ukázkové aplikace a trochu při tom zpřesníme naše znalosti o implementaci mapování souborů ve Windows.

V tomto dílu dokončíme serverovou část naší ukázkové aplikace. Minule jsme "vyrobili" procedury reagující na události OnCreate a OnDestroy hlavního formuláře. Dnes se podíváme na samotné sdílení dat s klienty. To nastane při změně textu v komponentě Memo1 (typu TMemo). Budeme tedy obsluhovat její událost OnChange.

Pokud si dobře vzpomínáte na první díl, psal jsem o tom, že výsledkem namapování souboru je ukazatel na začátek jeho dat v paměti. Přiznám se, že jsem malinko lhal. Představte si třeba, že namapujete do paměti gigabajtový soubor. Pak byste mohli zapisovat a psát na libovolná místa celé gigabajtové oblasti paměti. V tu chvíli vyvstane několik problémů:

  1. Co se soubory většími než 2GB? Dva gigabajty jsou maximální velikost alokovatelné paměti ve Windows, když se tam soubor nevejde, co pak s tím?
  2. Jak efektivně cacheovat takový soubor? Pokud budete moct náhodně zapisovat kamkoliv do souboru, jakýkoliv obvyklý mechanismus selže a swapování se po dobu operací se souborem nezastaví...

Aby se systém Windows zbavil těchto problémů (hlavně prvního), byly zavedeny tzv. pohledy (views) do namapovaného souboru. Můžete si to představit jako "okénko" do dané paměti - viz obrázek:

Jak to vypadá v paměti při mapování souborů

Ve skutečnosti příslušná funkce file mappingu vrací ukazatel na začátek takového okénka a manipulovat můžete jen s jeho obsahem - nikoliv tedy s celým namapovaným souborem najednou. Podotýkám, že druhý problém z mého seznamu je tím řešen jen částečně, protože velikost okénka je možno nastavit až na 2GB.

Teď už se raději podívejme na kód procedury TMainForm.Memo1Change:

procedure TMainForm.Memo1Change(Sender: TObject);
var
  P: PChar;
begin
  if HMap <> 0 then
  begin
    P := MapViewOfFile(HMap, FILE_MAP_WRITE,
      0, 0, Length(Memo1.Text) + 1);
    StrCopy(P, PChar(Memo1.Text));
    UnmapViewOfFile(P);

    SendMessage(HWND_BROADCAST, HMessage, 0, 0);
  end;
end;

Celá procedura se provádí, jen pokud máme v pořádku přidělený handle file mappingu (viz minulý díl). Funkce MapViewOfFile nám poskytne výše zmiňovaný ukazatel na začátek "okénka". Parametry této funkce jsou celkem přirozené - handle mapování, způsob přístupu k datům (tentokrát chceme psát, v případě čtení bychom použili konstantu FILE_MAP_READ), vyšší a nižší část pozice v souboru, kam ukazatel směřuje (dohromady dávají 64bitové číslo) a nakonec délka okénka. Tu, jak je vidět, volíme rovnou délce textu v editoru plus jedna.

Standardní funkcí StrCopy překopírujeme data za řetězce Memo1.Text do oblasti, kam ukazuje ukazatel P. Tato funkce také za celý řetězec umístí znak #0, což je jednoduchý (navíc ve Windows a v C/C++ standardní) způsob, jak říct "tady je konec řetězce" - kvůli tomu jsme volili délku "okénka" o 1 větší než délka textu. Tohoto způsobu uložení textu výhodně využijeme při tvorbě klientské části aplikace.

Nakonec funkcí UnmapViewOfFile zavřeme "okénko" do namapovaného souboru a pošleme všem oknům (pomocí speciálního handle HWND_BRODCAST) zprávu o změně textu. Na možnou otázku, proč nepoužijeme funkce PostMessage odpovím jednoduše - synchronizace. Tato funkce totiž na rozdíl od SendMessage nečeká, až budou všechny zprávy doručeny, a vrátí ihned po odeslání zpráv řízení volajícímu. Pak by se mohlo snadno stát, že by proběhly třeba další změny textu a přitom by klienti ještě nezpracovali změny předchozí - a vzhledem k tomu, že všichni spolu se serverem přistupují do stejné paměti najednou, mohlo by dojít k problémům. Je to sice okrajový případ (mohl by nastat například při velkém vytížení procesoru), ale když existuje jednoduchý způsob, jak se mu vyhnout, není důvod ho nepoužít.

Příště

Pro dnešek je to vše, serverovou část máme tímto dílem dokončenou. To znamená, že příště se můžete podívat na část klientskou.

Celou ukázkovou aplikaci si můžete stáhnout i se zdrojovým kódem (Delphi 3 a vyšší).

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: