EXTERNÍ
DATOVÁ FRONTA
 
 

 
Prosím, dej nám prostředky, které by nás povzbudili k psaní lepších programů ...
DONALD E. KNUTH v CACM č. 12 1974, s. 672

Představím vám podrobně externí datovou frontu (tentokrát dokonce ani nepředpokládám vaši znalost tohoto mechanizmu v "klasickém" Rexxu). Představím vám ji jako prostředek pro komunikaci mezi programy, jako prostředek vstupu a výstupu, jako užitečnou datovou strukturu - frontu, zásobník, ...

Externí datová fronta (External Data Queue) je systémový objekt AS/400, obsahující posloupnost položek, podobných větám souborů. Po startu úlohy (job), v interaktivním prostředí po přihlášení pomocí povelu SIGN ON, se externí datová fronta vytvoří a je dostupná všem programům úlohy po celou dobu jejího trvání, v interaktivním prostředí tedy až do provední povelu SIGNOFF. Jeden program může položky do fronty uložit, druhý přečíst - fronta plní úlohu zařízení pro komunikaci mezi programy.

Užitečnou analogií pro pochopení mechanizmu fronty je představovat si ji jako hadici od vysavače (prohlédněte si následující obrázek) s vyznačeným začátkem a koncem. Jak vidíte, můžete ukládat pinpongové míčky (položky) z obou stran, ale vypadnout vám mohou jen z jejího začátku.

 

Příkaz queue přidá na konec fronty novou položku.

 

Příkaz push přidá na začátek fronty novou položku.

 

Příkaz parse pull přečte položku ze začátku fronty, je-li však fronta prázdná, pak příkaz parse pull bude číst ze souboru STDIN.

 

Volání vestavěné funkce QUEUED() vrací počet položek ve frontě.

 

CL povely ADDREXBUF (Add REXX Buffer) a RMVREXBUF (Remove REXX Buffer) je možné vydělit a uvolňovat uskupení položek ve frontě (buffers). Nebudu o těchto povelech hovořit podrobně, ale povel 'RMVREXBUF 0', který vymaže všechny položky ve frontě (volání funkce QUEUED() bude vracet 0), je užitečný.

Když potřebujete simulovat losování, použijete funkci RANDOM. Ale chci vám ukázat způsob, který mnohem věrněji napodobuje otáčení osudím nebo míchání karet atd., protože výsledek závisí i na době trvání této činnoti. Jon Bentley napsal:

Jak může počítač rozdávat karty v pokru? Když přiřadíme každé kartě v balíčku celé číslo mezi 1 až 52, pak rozdání můžeme provést náhodným výběrem pěti celých čísel z intervalu 1..52, například,

4  8  31  46  47

(To je důležité, aby se žádné číslo nevyskytovalo ve výběru dvakrát; držet v ruce více než jedno srdcové eso by mohlo ohrozit hráčovo zdraví) -

Napíšeme si program, který bude míchat a rozdávat karty. Začneme s představou balíčku karet - to budou čísla od 1 do 52. Uložíme je jako jeden řetězec znaků - posloupnost slov oddělených od sebe mezerami. Následující program MICHEJ umístí balíček na začátek fronty v případě, že je fronta prázdná. Na začátek fronty uloží položku obsahující momentální čas. A to je vše. Takže, kdo vlastně míchá? Čas.


/* MICHEJ */
Balicek = ""
if QUEUED() = 0 then do
  do J = 1 to 52; Balicek = Balicek J; end
  push Balicek
end
push TIME("S")

Pustíte-li po několika minutách, náhodně, dále uvedený program ROZDEJ, tak z externí datové fronty odebere položku s časem a balíček karet. Z časového záznamu a momentálního času určí číslo od 1 do počtu karet v balíčku - tj. vybere náhodně jednu kartu. Vybere ji doslova, protože ji zobrazí (příkazem say) a odstraní z balíčku (pomocí funkce DELWORD).


/* ROZDEJ */
parse pull T; parse pull Balicek
J = ABS(TIME("S") - T) // WORDS(Balicek) + 1
say "Rozdána karta" WORD(Balicek, J)
if WORDS(Balicek) > 1 then push DELWORD(Balicek, J, 1)

Střídavým spouštěním programů MICHEJ - ROZDEJ - MICHEJ - ... počítač míchá a rozdává karty. Po skončení programu MICHEJ můžete dělat cokoliv jen se neodhlašujte povelem SIGNOFF a neměňte obsah externí datové fronty.

Ale externí datová fronta není jen pro komunikaci mezi programy. Tak například, budete-li eliminovat rekurzi, můžete ji využít jako zásobník, budete-li programovat topologický sort, můžete ji využít jako frontu.

Když externí datovou frontu využíváte, musíte kontrolovat její obsah. Dokázali byste napsat program, který by to prováděl? Opravdu užitečný program by mohl zobrazit obsah fronty a podle přání uživatele by ji buď ponechal beze změny nebo by všechny v ní uložené položky vymazal. Zkuste si to nejprve sami. (Řešení této úlohy následuje)


/* XAMINE */
do QUEUED()
  parse pull Polozka; say Polozka; queue Polozka
end
do until Odpoved = "A" | Odpoved = "N"
  say "Vyjmout polozky z fronty? (A/N)"
  parse upper linein Odpoved
end
if Odpoved = "A" then 'RMVREXBUF 0'


 [Jak napsat a spustit program]

 [Standardní vstup a výstup]

 [Externí datová fronta]

 [SQL povely]


Kam dál ... hlavní str. english

od 1. ledna 2000, naposledy změněno 13. dubna 2018
Copyright © 2000-2018 Vladimír Zábrodský, RNDr.
 
mail