Vypracování - fg, bg


 

Úvod

Øízení úloh umožòuje zajistit, aby daný proces (spuštìný program) bìžel na popøedí nebo na pozadí. Tedy je tøeba mít nástroj k tomu, abychom mohli bìžící program pøesunout do pozadí a mohli pracovat na jiných vìcech. Tímto nástrojem bývá tzv. pøíkazový procesor. V souvislosti s øízením úloh definujeme dva pøíkazy - "bg" a "fg".


Rozbor úlohy :

Základní pojmy:

fg    - foreground  - pøíkaz pro pøepnutí již spuštìného procesu bìžícího na pozadí (popø. stopnutého procesu) do popøedí
bg   - background - pøíkaz pro spuštìní stopnutého procesu na pozadí (pøesune stopnutou úlohu na pozadí)
&    - spuštìní procesu (uvedeného pøed znakem &) na pozadí pøímo z pøíkazové øádky shellu
^Z   - (Ctrl-Z) pozastavení procesu bìžícího na popøedí

Možnosti pøepínání procesù:

popøedí --> pozadí 
Pokud bìží proces na popøedí, je nutné ho nejprve stopnout (pøevést do stavu STOPPED) pomocí ^Z a potom ho spustit na pozadí pomocí pøíkazu "bg". Tedy proces, který již bìží na popøedí, nelze dostat do pozadí jinak než pøes stopnutí pomocí ^Z.

pozadí --> popøedí 
Proces na pozadí se do popøedí dostane pomocí pøíkazu "fg", abychom však mohli zadat pøíkaz fg, tak shell musí být na popøedí (fg i bg jsou pøíkazy shellu).

spuštìní procesu na popøedí z shellu
Proces se spustí na popøedí po zadání jeho názvu do pøíkazového øádku shellu.

spuštìní procesu na pozadí z shellu
Proces se spustí na pozadí po zadání jeho názvu spoleènì se znakem "&"  do pøíkazového øádku shellu, na popøedí zùstává shell.


Stopnutí procesu

bìžícího na popøedí
Proces bìžící na popøedí lze stopnout pouze pomocí  ^Z

bìžícího na pozadí
Proces bìžící na pozadí nelze pøímo stopnout, musí se nejprve pøevést na popøedí. Výjimku tvoøí pøípad, když proces na pozadí požaduje ètení z terminálu - bude stopnut automaticky!


Pozn. - pøíkazy bg, fg lze spouštìt pouze z toho tty, ze kterého byly spuštìny procesy, na které chceme aplikovat pøíkazy bg, fg.
         - vypisovat na tty mohou i procesy bìžící na pozadí
         - vstup z tty mùze žádat pouze proces na popøedí (proces na pozadí je stopnut - stejnì jako by bylo stisknuto ^Z)



Úkoly:

1.
Spouštìní procesu z shellu

Tabulku procesù FS (fproc - soubor FS/COMMOM/FPROC.H) doplníme o položku isOnFg, která bude udávat, zda proces bìží na popøedí/pozadí.
Potom k danému terminálu (tty je identifikován pomocí položky fp_tty v fproc) je tøeba identifikovat procesy bìžící na pozadí (mají nastaveny isOnFg na FALSE) - fproc doplníme o položku numBg, která bude identifikovat èíslem proces bìžící na pozadí daného tty (dùležité pro to, abychom z procesù bìžících na pozadí, mohli vybrat pomocí fg/bg toho, který pùjde do popøedí/pozadí).  Èíslo identifikující proces bìžící na pozadí pro dané tty musí být jednoznaèné.

Dále musíme dodefinovat zprávy umožòující nastavit tyto promìnné v fproc (úpravy v COMMON/CALLNR.H - pøidání C_BG a C_FG, do SYSTASK/SYSTASK.C dodefinovat funkce do_fg, do_bg). Pøi volání je nutné nastavit ve zprávì správnì položku m_type z callnr.h

a) Spuštìní procesu z shellu normálnì na popøedí (bez znaku '&')
Øešení:
Shell èeká na skonèení procesu (pomocí pøíkazu wait, popø. waitpid), FS je zprávou informován o tom, že nový proces bìží na popøedí - je mu v FPROC nastavena položka isOnFg, u shellu je tato položka vynulována   

b) Spuštìní procesu z shellu na pozadí (pomocí &)
Øešení:
Po zadání pøíkazu v shellu se hledá znak '&', pøi jeho nalezení shell nebude èekat na dokonèení procesu (je tøeba obejí wait, waitpid).
Shell zùstává na popøedí, na FS se pošle zpráva, aby novému procesu nastavil položku isOnFg na FALSE.



2. Pøíkazy fg, bg
Øešení:
Pøíkazy fg, bg budou souèástí shellu (stejnì jako napø. v Linuxu).
Pokud shell zjistí, že uživatel zadal jeden z tìchto pøíkazù, pak se pošle na FS zpráva s parametrem, který bude urèovat, zda proces má být na popøedí nebo na pozadí. FS podle toho nastaví promìnnou inOnfg (TRUE jestli na popøedí nebo FALSE na pozadí). Pokud bude proces na popøedí, pak se musí rodiè dostat na pozadí, tedy pomocí metody getpid získáne rodièe a nastavíme pøíslušnou promìnnou. V pøípadì, že proces bude na pozadí, tak se vygeneruje jedineèné èíslo v rámci daného terminálu, které bude urèovat tento proces na pozadí.



3. Jak získáme major/minor èíslo øídicího terminálu ?
Øešení:
Major/minor èíslo je definováno ve struktuøe FPROC.H (soubor FS/COMMOM/FPROC.H) jako dev_t fp_tty.
K této promìnné se pøistupuje pouze ve dvou místech :
1) FS/SYSCALL/MISC.C ve funkci do_fork, která vytváøí nový proces a proto musí všechny položky struktury FPROC pøekopírovat do nové.
2) FS/SYSCALL/OPENC.C ve funkci do_open, která se snaží otevøít soubor. Pokud by šlo o otevøení speciálního znakového souboru, pak se otestuje zda tento proces už má pøiøazeno nìjaké zaøízení a pokud ne, tak mu pøiøadí toho nové èíslo.

Z tìchto poznatkù usuzuji, že major/minor èíslo se používá a proto ho budeme moci použít i pro naše úèely (to jest identifikace terminálu, ze kterého byl proces spuštìn).


4. Exit
Øešení:
V souboru FS/SYSCALL/MISC.C je funkce do_exit. V této funkci budeme øešit situaci ukonèení procesu, který je na popøedí. Pokud bude konèit proces, který je na popøedí (toto zjistíme podle promìnné isOnfg), tak musíme zajistit aby se jeho rodièovský proces dostal na popøedí. Toto vyøešíme tak, že pomocí funkce getpid() zjistíme rodièe procesu. Tomuto rodièovského procesu pak nastavíme promìnnou inOnfg na TRUE a tak se dostane na popøedí.
Pokud skonèí proces na pozadí, tak se nic nedìje.


5. Nadefinování stavu procesu STOPPED
Øešení:
Proces, kromì toho, že mùže bìžet na popøedí/pozadí, tak také mùže být pozastaven - nacházet se ve stavu STOPPED. V tomto stavu by proces nemìl být plánován schedullerem. Stav STOPPED je tøeba dodefinovat do položky p_flags v proc[]   (soubor KERNEL/PROC_PUB.H). Položka p_flags mimo jiné indikuje, že proces èeká na pøijetí zprávy, odeslání zprávy, atd. Proces se do stavu STOPPED mùže dostat po stisknutí ^Z (viz. dále), nebo v pøípadì, že požaduje vstup z terminálu a je na pozadí (isOnFg je False).
Dále je zapotøebí dodefinovat zprávy, které umi proc[].p_flags dostat do stavu STOPPED a scheduler upravit tak, aby proces v tomto stavu neplánoval.


6. ^Z (Ctrl - Z)
Øešení:
Proces bìžící na popøedí lze stopnout pomocí ^Z. V  souboru TTY/TTY.H bude tøeba dodefinovat - STOP_CHAR s hodnotou 0x1A (což odpovídá stisku Ctrl-Z). V pøípadì stisku ^Z bude zprávou proces bìžící na popøedí v pøíslušném terminálu uveden do stavu STOPPED, s tímto souvisí uvedení jeho rodièe na popøedí - nastavení isOnFg v fproc[]. V pøípadì, že proces bìžící na pozadí požaduje vstup z klávesnice (metoda do_read() ze souboru TTY/DO_READ.INC)- provede se totéž, jako by bylo stisknuto ^Z.



Zpet