Ú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.