Ocenite etot tekst:





    Podsistema  upravleniya  vvodom-vyvodom  pozvolyaet processam podderzhivat'
svyaz' s periferijnymi ustrojstvami, takimi kak nakopiteli na magnitnyh  dis-
kah  i lentah, terminaly, printery i seti, s odnoj storony, i s modulyami yad-
ra, kotorye upravlyayut ustrojstvami i imenuyutsya drajverami ustrojstv, s  dru-
goj.  Mezhdu drajverami ustrojstv i tipami ustrojstv obychno sushchestvuet odnoz-
nachnoe sootvetstvie: v sisteme mozhet byt' odin diskovyj drajver dlya upravle-
niya vsemi diskovodami, odin terminal'nyj drajver dlya upravleniya vsemi termi-
nalami i odin lentochnyj drajver dlya upravleniya vsemi lentochnymi  nakopitelya-
mi. Esli v sisteme imeyutsya odnotipnye ustrojstva, poluchennye ot raznyh izgo-
tovitelej - naprimer, dve marki lentochnyh nakopitelej, - v etom sluchae mozhno
traktovat' odnotipnye ustrojstva kak ustrojstva dvuh razlichnyh tipov i imet'
dlya  nih  dva otdel'nyh drajvera, poskol'ku takim ustrojstvam dlya vypolneniya
odnih i teh zhe operacij mogut potrebovat'sya  raznye  posledovatel'nosti  ko-
mand.  Odin  drajver upravlyaet mnozhestvom fizicheskih ustrojstv dannogo tipa.
Naprimer, odin terminal'nyj drajver mozhet upravlyat' vsemi terminalami, podk-
lyuchennymi k sisteme. Drajver razlichaet ustrojstva, kotorymi  upravlyaet:  vy-
hodnye  dannye, prednaznachennye dlya odnogo terminala, ne dolzhny byt' poslany
na drugoj.
    Sistema podderzhivaet "programmnye ustrojstva", s kazhdym  iz  kotoryh  ne
svyazano  ni  odno konkretnoe fizicheskoe ustrojstvo. Naprimer, kak ustrojstvo
traktuetsya fizicheskaya pamyat', chtoby pozvolit' processu obrashchat'sya k nej izv-
ne, pust' dazhe pamyat' ne yavlyaetsya periferijnym ustrojstvom. Komanda ps obra-
shchaetsya k informacionnym strukturam yadra v fizicheskoj pamyati, chtoby  soobshchit'
statistiku  processov. Eshche odin primer: drajvery mogut vesti trassirovku za-
pisej v udobnom dlya otladki vide, a  drajver  trassirovki  daet  vozmozhnost'
pol'zovatelyam chitat' eti zapisi. Nakonec, profil' yadra, rassmotrennyj v gla-
ve 8, vypolnen kak drajver: process zapisyvaet adresa programm yadra, obnaru-
zhennyh v tablice identifikatorov yadra, i chitaet rezul'taty profilirovaniya.
    V etoj glave rassmatrivaetsya vzaimodejstvie mezhdu processami i podsiste-
moj upravleniya vvodom-vyvodom, a takzhe mezhdu mashinoj i drajverami ustrojstv.
Issleduetsya obshchaya struktura i funkcionirovanie drajverov i v kachestve prime-
rov  obshchego vzaimodejstviya rassmatrivayutsya diskovye i terminal'nye drajvery.
Zavershaet glavu opisanie novogo metoda realizacii drajverov  potokovyh  ust-
rojstv.




    V  sisteme UNIX imeetsya dva tipa ustrojstv - ustrojstva vvodavyvoda blo-
kami i ustrojstva nestrukturirovannogo ili posimvol'nogo  vvoda-vyvoda.  Kak
uzhe govorilos' v glave 2, ustrojstva vvoda-vyvoda blokami, takie kak diski i
lenty,  dlya  ostal'noj  chasti sistemy vyglyadyat kak zapominayushchie ustrojstva s
proizvol'noj vyborkoj; k ustrojstvam  posimvol'nogo  vvoda-vyvoda  otnosyatsya
vse drugie ustrojstva, v tom chisle terminaly i setevoe oborudovanie. Ustroj-
stva  vvoda-vyvoda blokami mogut imet' interfejs i s ustrojstvami posimvol'-
nogo vvoda-vyvoda.
    Pol'zovatel' vzaimodejstvuet s ustrojstvami cherez posrednichestvo  fajlo-
voj  sistemy  (sm. Risunok 2.1). Kazhdoe ustrojstvo imeet imya, pohozhee na imya
fajla, i pol'zovatel' obrashchaetsya k nemu kak k fajlu. Special'nyj  fajl  ust-
rojstva imeet indeks i zanimaet mesto v ierarhii katalogov fajlovoj sistemy.
Fajl  ustrojstva  otlichaetsya  ot drugih fajlov tipom fajla, hranyashchimsya v ego
indekse, libo "blochnyj", libo "simvol'nyj special'nyj", v zavisimosti ot us-

                                    290

trojstva, kotoroe etot fajl predstavlyaet. Esli ustrojstvo imeet kak blochnyj,
tak i simvol'nyj interfejs, ego predstavlyayut dva fajla: special'nyj fajl us-
trojstva vvoda-vyvoda blokami i special'nyj  fajl  ustrojstva  posimvol'nogo
vvoda-vyvoda.  Sistemnye  funkcii dlya obychnyh fajlov, takie kak open, close,
read i write, imeyut to zhe znachenie i dlya ustrojstv, v chem my ubedimsya pozzhe.
Sistemnaya funkciya ioctl predostavlyaet processam vozmozhnost'  upravlyat'  ust-
rojstvami  posimvol'nogo  vvoda-vyvoda, no ne primenima v otnoshenii k fajlam
obychnogo tipa (*). Tem ne menee, drajveram ustrojstv net neobhodimosti  pod-
derzhivat'  polnyj  nabor sistemnyh funkcij. Naprimer, vysheupomyanutyj drajver
trassirovki daet processam  vozmozhnost'  chitat'  zapisi,  sozdannye  drugimi
drajverami, no ne pozvolyaet sozdavat' ih.




    Zadanie  konfiguracii  sistemy  eto  procedura ukazaniya administratorami
znachenij parametrov, s pomoshch'yu kotoryh proizvoditsya nastrojka sistemy. Neko-
torye iz parametrov ukazyvayut razmery tablic yadra, takih kak tablica proces-
sov, tablica indeksov i tablica fajlov, a takzhe skol'ko buferov pomeshchaetsya v
bufernom pule. S pomoshch'yu drugih parametrov ukazyvaetsya konfiguraciya  ustroj-
stv, to est' proizvodyatsya konkretnye ukazaniya yadru, kakie ustrojstva vklyucha-
yutsya  v  dannuyu  sistemnuyu realizaciyu i ih "adres". Naprimer, v konfiguracii
mozhet byt' ukazano, chto terminal'naya plata vstavlena v sootvetstvuyushchij raz®-
em na apparatnoj paneli.
    Sushchestvuet  tri  stadii, na kotoryh mozhet byt' ukazana konfiguraciya ust-
rojstv. Vo-pervyh, administratory mogut kodirovat' informaciyu o konfiguracii
v fajlah, kotorye transliruyutsya i komponuyutsya vo vremya postroeniya yadra.  In-
formaciya  o  konfiguracii  obychno ukazyvaetsya v prostom formate, i programma
konfiguracii preobrazuet ee v fajl, gotovyj dlya translyacii. Vo-vtoryh, admi-
nistratory mogut ukazyvat' informaciyu o konfiguracii posle togo, kak sistema
uzhe zapushchena; yadro dinamicheski korrektiruet vnutrennie tablicy konfiguracii.
Nakonec, samoidentificiruyushchiesya ustrojstva dayut yadru vozmozhnost' uznat', ka-
kie iz ustrojstv vklyucheny. YAdro schityvaet apparatnye klyuchi dlya  samonastroj-
ki.  Podrobnosti zadaniya sistemnoj konfiguracii vyhodyat za predely etoj kni-
gi, odnako vo vseh sluchayah rezul'tatom procedury zadaniya konfiguracii  yavlya-
etsya generaciya ili zapolnenie tablic, sostavlyayushchih osnovu programm yadra.
    Interfejs  "yadro  - drajver" opisyvaetsya v tablice klyuchej ustrojstv vvo-
da-vyvoda blokami i v tablice klyuchej  ustrojstv  posimvol'nogo  vvoda-vyvoda
(Risunok  10.1).  Kazhdyj tip ustrojstva imeet v tablice tochki vhoda, kotorye
pri vypolnenii sistemnyh funkcij adresuyut yadro k sootvetstvuyushchemu  drajveru.
Funkcii  open  i  close,  vyzyvaemye fajlom ustrojstva, "propuskayutsya" cherez
tablicy klyuchej ustrojstv v sootvetstvii  s  tipom  fajla.  Funkcii  mount  i
umount tak zhe vyzyvayut vypolnenie procedur otkrytiya i zakrytiya ustrojstv, no
dlya ustrojstv vvoda-vyvoda blokami. Funkcii read i write, vyzyvaemye ustroj-
stvami  vvoda-vyvoda  blokami  i fajlami v smontirovannyh fajlovyh sistemah,
zapuskayut algoritmy raboty s bufernym keshem, iniciiruyushchie realizaciyu strate-
gicheskoj procedury raboty s ustrojstvami. Nekotorye iz  drajverov  zapuskayut
etu proceduru iznutri iz procedur chteniya i zapisi. Bolee podrobno vzaimodej-
stvie s kazhdym drajverom rassmatrivaetsya v sleduyushchem razdele.
    Interfejs  "apparatura - drajver" sostoit iz mashinno-zavisimyh upravlyayu-
shchih registrov ili komand vvoda-vyvoda dlya upravleniya ustrojstvami i vektora-
mi preryvanij: kogda proishodit preryvanie ot ustrojstva, sistema  identifi-
ciruet ustrojstvo, vyzvavshee preryvanie, i zapuskaet programmu obrabotki so-

----------------------------------------
(*) I naoborot, sistemnaya funkciya fcntl obespechivaet kontrol' nad  dejstviya-
    mi, proizvodimymi na urovne deskriptora fajla, no ne na urovne ustrojst-
    va. V drugih realizaciyah funkciya ioctl primenima dlya fajlov vseh tipov.


                                    291

otvetstvuyushchego preryvaniya. Ochevidno, chto "programmnye ustrojstva", takie kak
drajver  sistemy  postroeniya profilya yadra (glava 8) ne imeyut apparatnogo in-
terfejsa, odnako programmy obrabotki drugih preryvanij  mogut  obrashchat'sya  k
"obrabotchiku  programmnogo  preryvaniya" neposredstvenno. Naprimer, programma
obrabotki preryvaniya po tajmeru obrashchaetsya k programme obrabotki  preryvaniya
sistemy postroeniya profilya yadra.
    Administratory ustanavlivayut special'nye fajly ustrojstv komandoj mknod,
v  kotoroj ukazyvaetsya tip fajla (blochnyj ili simvol'nyj), starshij i mladshij
nomera ustrojstva. Komanda mknod zapuskaet vypolnenie  sistemnoj  funkcii  s
tem zhe imenem, sozdayushchej fajl ustrojstva. Naprimer, v komandnoj stroke

    mknod /dev/tty13 c 2 13

"/dev/tty13"  -  imya  fajla ustrojstva, "c" ukazyvaet, chto tip fajla - "sim-
vol'nyj special'nyj" ("b", sootvetstvenno, blochnyj), "2" - starshij nomer us-
trojstva, "13" - mladshij nomer ustrojstva. Starshij nomer ustrojstva  pokazy-
vaet ego tip, kotoromu sootvetstvuet tochka vhoda v tablice klyuchej ustrojstv,
mladshij  nomer  ustrojstva - eto poryadkovyj nomer edinicy ustrojstva dannogo
tipa. Esli process otkryvaet special'nyj blochnyj fajl s imenem "/dev/dsk1" i
kodom 0, yadro zapuskaet programmu gdopen v tochke 0 tablicy klyuchej  ustrojstv
blochnogo  vvoda-vyvoda  (Risunok 10.2); esli process chitaet special'nyj sim-
vol'nyj fajl s imenem "/dev/mem" i kodom 3,


                    Podsistema upravleniya fajlami
    +------------------------------------------------------------+
    |                                    open  close             |
    | open close read write ioctl                     read write |
    |                                    mount umount            |
    +--+-----+----+-----+-----+------------+-----+-----+-----+---+
       |     |    |     |     |            |     |   +-+-----+---+
       |     |    |     |     |            |     |   | funkcii   |
       |     |    |     |     |            |     |   | raboty s  |
       |     |    |     |     |            |     |   | bufernym  |
       |     |    |     |     |            |     |   | keshem     |
       |     |    |     |     |            |     |   +-----+-----+
    +--+-----+----+-----+-----+-+         ++-----+---------+-----+
    | Tablica klyuchej ustrojstv  |         | Tablica klyuchej ust-  |
    | posimvol'nogo vvoda-vyvoda|         | rojstv vvoda-vyvoda  |
    |                           |         |        blokami       |
    +--+-----+----+-----+-----+-+         +--+------+--------+---+
    +--+-----+----+-----+-----+-+         +--+------+--------+---+
    |open close read write ioctl|  Tochki  | open  close  strategy|
    |                           |  vhoda  |                      |
    |         Drajver           |   dlya   |        Drajver       |
    |                           |  draj-  |                      |
    |programma obrabotki prery- |  verov  | programma obrabotki  |
    |   vanij ot ustrojstva     |         |preryvanij ot ustrojst|
    +------------+--------------+         +-----------+----------+
        +--------+----------+               +---------+---------+
        | Vektor preryvaniya |               | Vektor preryvaniya |
        +--------+----------+               +---------+---------+
                 +-------------------+----------------+
                                     |
                         Preryvaniya ot ustrojstv

               Risunok 10.1. Tochki vhoda dlya drajverov



                                    292

yadro zapuskaet programmu mmread v tochke 3 tablicy  klyuchej  ustrojstv  posim-
vol'nogo vvoda-vyvoda. Programma nulldev - eto "pustaya" programma, ispol'zu-
emaya  v  teh  sluchayah,  kogda otsutstvuet neobhodimost' v konkretnoj funkcii
drajvera. S odnim starshim nomerom ustrojstva mozhet  byt'  svyazano  mnozhestvo
periferijnyh  ustrojstv; mladshij nomer ustrojstva pozvolyaet otlichit' ih odno
ot drugogo. Ne nuzhno sozdavat' special'nye fajly ustrojstv pri  kazhdoj  zag-
ruzke  sistemy; ih tol'ko nuzhno korrektirovat', esli izmenilas' konfiguraciya
sistemy, naprimer, esli k ustanovlennoj konfiguracii byli dobavleny ustrojs-
tva.




    V etom razdele rassmatrivaetsya vzaimodejstvie yadra s drajverami  ustroj-
stv.  Pri  vypolnenii  teh sistemnyh funkcij, kotorye ispol'zuyut deskriptory
fajlov, yadro, sleduya za ukazatelyami, hranyashchimisya v pol'zovatel'skom deskrip-
tore fajla, obrashchaetsya k tablice

        +-----------------------------------------------+
        | tablica klyuchej ustrojstv vvoda-vyvoda blokami |
        +-------+--------+---------+--------------------+
        | vhod  |  open  |  close  |     strategy       |
        +-------+--------+---------+--------------------+
        |   0   | gdopen | gdclose |    gdstrategy      |
        +-------+--------+---------+--------------------+
        |   1   | gtopen | gtclose |    gtstrategy      |
        +-------+--------+---------+--------------------+
+----------------------------------------------------------------+
|      tablica klyuchej ustrojstv posimvol'nogo vvoda-vyvoda       |
+------+-----------+-----------+---------+-----------+-----------+
| vhod |   open    |   close   |  read   |  write    |   ioctl   |
+------+-----------+-----------+---------+-----------+-----------+
|   0  |  conopen  |  conclose | conread | conwrite  |  conioctl |
+------+-----------+-----------+---------+-----------+-----------+
|   1  |  dzbopen  |  dzbclose | dzbread | dzbwrite  |  dzbioctl |
+------+-----------+-----------+---------+-----------+-----------+
|   2  |  syopen   |  nulldev  | syread  | sywrite   |  syioctl  |
+------+-----------+-----------+---------+-----------+-----------+
|   3  |  nulldev  |  nulldev  | mmread  | mmwrite   |   nodev   |
+------+-----------+-----------+---------+-----------+-----------+
|   4  |  gdopen   |  gdclose  | gdread  | gdwrite   |   nodev   |
+------+-----------+-----------+---------+-----------+-----------+
|   5  |  gtopen   |  gtclose  | gtread  | gtwrite   |   nodev   |
+------+-----------+-----------+---------+-----------+-----------+

  Risunok 10.2. Primer zapolneniya tablic klyuchej ustrojstv vvoda-
                vyvoda blokami i simvolami


fajlov yadra i k indeksu, gde ono proveryaet tip fajla, i perehodit k  tablice
klyuchej  ustrojstv  vvoda-vyvoda blokami ili simvolami. YAdro izvlekaet iz in-
deksa starshij i mladshij nomera ustrojstva, ispol'zuet starshij nomer v kaches-
tve ukazatelya na tochku vhoda v sootvetstvuyushchej tablice i vyzyvaet vypolnenie
funkcii drajvera v sootvetstvii s vypolnyaemoj sistemnoj funkciej,  peredavaya
mladshij  nomer v kachestve parametra. Vazhnym razlichiem v realizacii sistemnyh
funkcij dlya fajlov ustrojstv i dlya fajlov obychnogo tipa yavlyaetsya to, chto in-
deks special'nogo fajla ne blokiruetsya v  to  vremya,  kogda  yadro  vypolnyaet
programmu drajvera. Drajvery chasto priostanavlivayut svoyu rabotu, ozhidaya svya-
zi s apparatnymi sredstvami ili postupleniya dannyh, poetomu yadro ne v sosto-

                                    293

yanii  opredelit',  na  kakoe  vremya process budet priostanovlen. Esli indeks
zablokirovan, drugie processy, obrativshiesya k indeksu (naprimer, posredstvom
sistemnoj funkcii stat), priostanovyatsya na neopredelennoe  vremya,  poskol'ku
odin process priostanovil drajver.
    Drajver  ustrojstva  interpretiruet parametry vyzova sistemnoj funkcii v
otnoshenii ustrojstva. Drajver  podderzhivaet  struktury  dannyh,  opisyvayushchie
sostoyanie  kazhdoj  kontroliruemoj  edinicy  dannogo tipa ustrojstva; funkcii
drajvera i programmy obrabotki preryvanij realizuyutsya v sootvetstvii s  sos-
toyaniem  drajvera  i s tem, kakoe dejstvie vypolnyaetsya v etot moment (napri-
mer, dannye vvodyatsya ili vyvodyatsya). Teper' rassmotrim kazhdyj interfejs  bo-
lee podrobno.


    +------------------------------------------------------------+
    | algoritm open      /* dlya drajverov ustrojstv */           |
    | vhodnaya informaciya:  imya puti poiska                       |
    |                      rezhim otkrytiya                        |
    | vyhodnaya informaciya: deskriptor fajla                      |
    | {                                                          |
    |    preobrazovat' imya puti poiska v indeks, uvelichit' znache-|
    |     nie schetchika ssylok v indekse;                         |
    |    vydelit' v tablice fajlov mesto dlya pol'zovatel'skogo   |
    |     deskriptora fajla, kak pri otkrytii obychnogo fajla;    |
    |                                                            |
    |    vybrat' iz indeksa starshij i mladshij nomera ustrojstva; |
    |                                                            |
    |    sohranit' kontekst (algoritm setjmp) v sluchae peredachi  |
    |     upravleniya ot drajvera;                                |
    |                                                            |
    |    esli (ustrojstvo blochnogo tipa)                         |
    |    {                                                       |
    |       ispol'zovat' starshij nomer ustrojstva v kachestve uka-|
    |        zatelya v tablice klyuchej ustrojstv vvoda-vyvoda blo- |
    |        kami;                                               |
    |       vyzvat' proceduru otkrytiya drajvera po dannomu indek-|
    |        su: peredat' mladshij nomer ustrojstva, rezhimy otkry-|
    |        tiya;                                                |
    |    }                                                       |
    |    v protivnom sluchae                                      |
    |    {                                                       |
    |       ispol'zovat' starshij nomer ustrojstva v kachestve uka-|
    |        zatelya v tablice klyuchej ustrojstv posimvol'nogo vvo-|
    |        da-vyvoda;                                          |
    |       vyzvat' proceduru otkrytiya drajvera po dannomu indek-|
    |        su: peredat' mladshij nomer ustrojstva, rezhimy otkry-|
    |        tiya;                                                |
    |    }                                                       |
    |                                                            |
    |    esli (otkrytie v drajvere ne vypolnilos')               |
    |       privesti tablicu fajlov k pervonachal'nomu vidu,      |
    |        umen'shit' znachenie schetchika v indekse;              |
    | }                                                          |
    +------------------------------------------------------------+

            Risunok 10.3. Algoritm otkrytiya ustrojstva



    Pri  otkrytii ustrojstva yadro sleduet toj zhe procedure, chto i pri otkry-

                                    294



tii fajlov obychnogo tipa (sm. razdel 5.1), vydelyaya v pamyati indeksy,  uveli-
chivaya  znachenie  schetchika ssylok i prisvaivaya znachenie tochki vhoda v tablicu
fajlov i pol'zovatel'skogo deskriptora fajla. Nakonec, yadro vozvrashchaet  zna-
chenie pol'zovatel'skogo deskriptora fajla vyzyvayushchemu processu, tak chto otk-
rytie  ustrojstva vyglyadit tak zhe, kak i otkrytie fajla obychnogo tipa. Odna-
ko, pered tem, kak vernut'sya v rezhim zadachi, yadro zapuskaet
zavisyashchuyu ot ustrojstva proceduru open (Risunok 10.3). Dlya  ustrojstva  vvo-
da-vyvoda  blokami zapuskaetsya procedura open, zakodirovannaya v tablice klyu-
chej ustrojstv vvoda-vyvoda blokami, dlya ustrojstv posimvol'nogo vvoda-vyvoda
- procedura open, zakodirovannaya v sootvetstvuyushchej tablice. Esli  ustrojstvo
imeet  kak blochnyj, tak i simvol'nyj tip, yadro zapuskaet proceduru open, so-
otvetstvuyushchuyu tipu fajla ustrojstva, otkrytogo pol'zovatelem: obe  procedury
mogut dazhe byt' identichny, v zavisimosti ot konkretnogo drajvera.
    Zavisyashchaya  ot  tipa  ustrojstva procedura open ustanavlivaet svyaz' mezhdu
vyzyvayushchim processom i otkryvaemym ustrojstvom i inicializiruet informacion-
nye struktury drajvera. Naprimer, procedura open dlya terminala mozhet  prios-
tanovit' process do teh por, poka v mashinu ne postupit signal (apparatnyj) o
tom,  chto  pol'zovatel'  predprinyal  popytku zaregistrirovat'sya. Posle etogo
inicializiruyutsya informacionnye struktury drajvera v sootvetstvii s prinyaty-
mi ustanovkami terminala (naprimer, skorost'yu peredachi informacii v  bodah).
Dlya  "programmnyh ustrojstv", takih kak pamyat' sistemy, procedura open mozhet
ne vklyuchat' v sebya inicializaciyu.
    Esli vo vremya otkrytiya ustrojstva processu prishlos'  priostanovit'sya  po
kakoj-libo iz vneshnih prichin, mozhet tak sluchit'sya, chto sobytie, kotoroe dol-
zhno bylo by vyzvat' vozobnovlenie vypolneniya processa, tak nikogda i ne pro-
izojdet. Naprimer, esli na dannom terminale eshche ne zaregistrirovalsya ni odin
iz pol'zovatelej, process getty, "otkryvshij" terminal (razdel 7.9), priosta-
navlivaetsya  do teh por, poka pol'zovatelem ne budet predprinyata popytka re-
gistracii, pri etom mozhet projti dostatochno bol'shoj promezhutok vremeni. YAdro
dolzhno imet' vozmozhnost' vozobnovit' vypolnenie processa  i  otmenit'  vyzov
funkcii  open  po  poluchenii  signala: emu sleduet sbrosit' indeks, otmenit'
tochku vhoda v tablice fajlov i pol'zovatel'skij  deskriptor  fajla,  kotorye
byli  vydeleny pered vhodom v drajver, poskol'ku otkrytie ne proizoshlo. YAdro
sohranyaet kontekst processa, ispol'zuya algoritm setjmp (razdel 6.4.4), prezh-
de chem zapustit' proceduru open; esli process vozobnovlyaetsya po signalu, yad-
ro vosstanavlivaet kontekst processa v tom sostoyanii, kotoroe on imel  pered
obrashcheniem  k drajveru, ispol'zuya algoritm longjmp (razdel 6.4.4), i vozvra-
shchaet sisteme vse vydelennye procedure open struktury dannyh. Tochno tak zhe  i
drajver mozhet ulovit' signal i ochistit' dostupnye emu struktury dannyh, esli
eto  neobhodimo. YAdro takzhe pereustanavlivaet struktury dannyh fajlovoj sis-
temy, kogda drajver stalkivaetsya s isklyuchitel'nymi situaciyami,  takimi,  kak
popytka pol'zovatelya obratit'sya k ustrojstvu, otsutstvuyushchemu v dannoj konfi-
guracii. V podobnyh sluchayah funkciya open ne vypolnyaetsya.
    Processy  mogut ukazyvat' znacheniya razlichnyh parametrov, harakterizuyushchie
osobennosti vypolneniya procedury otkrytiya. Iz nih naibolee chasto ispol'zuet-
sya "no delay" (bez zaderzhki), oznachayushchee, chto process ne budet priostanovlen
vo vremya vypolneniya procedury open, esli  ustrojstvo  ne  gotovo.  Sistemnaya
funkciya  open vozvrashchaet upravlenie nemedlenno i pol'zovatel'skij process ne
uznaet, proizoshlo li apparatnoe soedinenie ili net.  Otkrytie  ustrojstva  s
parametrom  "no delay", krome vsego prochego, zatronet semantiku vyzova funk-
cii read, chto my uvidim dalee (razdel 10.3.4).
    Esli ustrojstvo otkryvaetsya mnogokratno, yadro obrabatyvaet pol'zovatel'-
skie deskriptory fajlov, indeks i zapisi v tablice fajlov tak, kak eto  opi-
sano  v  glave  5, zapuskaya opredelyaemuyu tipom ustrojstva proceduru open pri
kazhdom vyzove sistemnoj funkcii open. Takim obrazom, drajver ustrojstva  mo-
zhet podschitat', skol'ko raz ustrojstvo bylo "otkryto", i prervat' vypolnenie
funkcii open, esli kolichestvo otkrytij prinyalo nedopustimoe znachenie. Napri-

                                    295

mer, imeet smysl razreshit' processam mnogokratno "otkryvat'" terminal na za-
pis'  dlya  togo,  chtoby  pol'zovateli mogli obmenivat'sya soobshcheniyami. No pri
etom ne sleduet dopuskat' mnogokratnogo  "otkrytiya"  pechatayushchego  ustrojstva
dlya  odnovremennoj zapisi, tak kak processy mogut zateret' drug drugu infor-
maciyu. |ti razlichiya imeyut smysl skoree na praktike, nezheli na stadii  razra-
botki:  razreshenie odnovremennoj zapisi na terminaly sposobstvuet ustanovle-
niyu vzaimodejstviya mezhdu pol'zovatelyami; zapreshchenie odnovremennoj zapisi  na
printery sluzhit povysheniyu chitabel'nosti mashinogramm (**).



    +------------------------------------------------------------+
    | algoritm close           /* dlya ustrojstv */               |
    | vhodnaya informaciya:  deskriptor fajla                      |
    | vyhodnaya informaciya: otsutstvuet                           |
    | {                                                          |
    |    vypolnit' algoritm standartnogo zakrytiya (glava 5hhh);  |
    |    esli (znachenie schetchika ssylok v tablice fajlov ne 0)   |
    |       perejti na finish;                                   |
    |    esli (sushchestvuet eshche odin otkrytyj fajl, starshij i mlad-|
    |     shij nomera kotorogo sovpadayut s nomerami zakryvaemogo  |
    |     ustrojstva)                                            |
    |       perejti na finish;     /* ne poslednee zakrytie */   |
    |    esli (ustrojstvo simvol'nogo tipa)                      |
    |    {                                                       |
    |       ispol'zovat' starshij nomer v kachestve ukazatelya v    |
    |        tablice klyuchej ustrojstva posimvol'nogo vvoda-vyvo- |
    |        da;                                                 |
    |       vyzvat' proceduru zakrytiya, opredelyaemuyu tipom draj- |
    |        vera i peredat' ej v kachestve parametra mladshij no- |
    |        mer ustrojstva;                                     |
    |    }                                                       |
    |    esli (ustrojstvo blochnogo tipa)                         |
    |    {                                                       |
    |       esli (ustrojstvo montirovano)                        |
    |          perejti na finish;                                |
    |       perepisat' bloki ustrojstva iz bufernogo kesha na ust-|
    |        rojstvo;                                            |
    |       ispol'zovat' starshij nomer v kachestve ukazatelya v    |
    |        tablice klyuchej ustrojstva vvoda-vyvoda blokami;     |
    |       vyzvat' proceduru zakrytiya, opredelyaemuyu tipom draj- |
    |        vera i peredat' ej v kachestve parametra mladshij no- |
    |        mer ustrojstva;                                     |
    |       sdelat' nedejstvitel'nymi bloki ustrojstva, ostavshie-|
    |        sya v bufernom keshe;                                 |
    |    }                                                       |
    |  finish:                                                   |
    |    osvobodit' indeks;                                      |
    | }                                                          |
    +------------------------------------------------------------+

             Risunok 10.4. Algoritm zakrytiya ustrojstva

----------------------------------------
(**)  Na praktike vyvod na pechat' obychno upravlyaetsya special'nymi processami
     buferizacii, i prava dostupa ustanavlivayutsya takim obrazom, chtoby tol'-
     ko sistema buferizacii mogla obrashchat'sya k printeru.



                                    296



    Process razryvaet svyaz' s otkrytym ustrojstvom,  zakryvaya  ego.  Odnako,
yadro  zapuskaet  opredelyaemuyu tipom ustrojstva proceduru close tol'ko v pos-
lednem vyzove funkcii close dlya etogo ustrojstva, i to tol'ko esli ne  osta-
los'  processov, kotorym ustrojstvo neobhodimo otkrytym, poskol'ku procedura
zakrytiya ustrojstva zavershaetsya razryvom apparatnogo soedineniya; otsyuda  yas-
no,  chto yadru sleduet podozhdat', poka ne ostanetsya ni odnogo processa, obra-
shchayushchegosya k ustrojstvu. Poskol'ku yadro zapuskaet proceduru otkrytiya ustrojs-
tva pri kazhdom vyzove sistemnoj funkcii open, a  proceduru  zakrytiya  tol'ko
odin raz, drajveru ustrojstva nevedomo, skol'ko processov ispol'zuyut ustroj-
stvo v dannyj moment. Drajvery mogut legko vyjti iz stroya, esli pri ih napi-
sanii  ne soblyudalas' ostorozhnost': kogda pri vypolnenii procedury close oni
priostanavlivayut svoyu rabotu i kakoj-nibud' process otkryvaet ustrojstvo  do
togo,  kak zavershitsya procedura zakrytiya, ustrojstvo mozhet stat' nedostupnym
dlya raboty, esli v rezul'tate kombinacii vyzovov open i close slozhilas'  ne-
raspoznavaemaya situaciya.

    Algoritm  zakrytiya  ustrojstva pohozh na algoritm zakrytiya fajla obychnogo
tipa (Risunok 10.4). Odnako, do togo, kak yadro osvobozhdaet indeks, v nem vy-
polnyayutsya dejstviya, specifichnye dlya fajlov ustrojstv.
 1. Prosmatrivaetsya tablica fajlov dlya togo, chtoby ubedit'sya v tom,  chto  ni
    odnomu  iz  processov ne trebuetsya, chtoby ustrojstvo bylo otkryto. CHtoby
    ustanovit', chto vyzov funkcii close dlya ustrojstva  yavlyaetsya  poslednim,
    nedostatochno  polozhit'sya  na  znachenie schetchika ssylok v tablice fajlov,
    poskol'ku neskol'ko processov mogut obrashchat'sya k odnomu i tomu  zhe  ust-
    rojstvu, ispol'zuya razlichnye tochki vhoda v tablice fajlov. Tak zhe nedos-
    tatochno  polozhit'sya  na  znachenie schetchika v tablice indeksov, poskol'ku
    odnomu i tomu zhe ustrojstvu mogut sootvetstvovat' neskol'ko fajlov  ust-
    rojstva. Naprimer, komanda ls -l pokazhet, chto odnomu i tomu zhe ustrojst-
    vu  simvol'nogo  tipa ("c" v nachale stroki) sootvetstvuyut dva fajla ust-
    rojstva, starshij i mladshij nomera u kotoryh (9 i 1) sovpadayut.  Znachenie
    schetchika  svyazej dlya kazhdogo fajla, ravnoe 1, govorit o tom, chto imeetsya
    dva indeksa.

       crw--w--w-     1 root   vis   9, 1  Aug 6 1984  /dev/tty01
       crw--w--w-     1 root   unix  9, 1  May 3 15:02 /dev/tty01

    Esli processy otkryvayut oba fajla nezavisimo odin ot drugogo, oni  obra-
    tyatsya k raznym indeksam odnogo i togo zhe ustrojstva.
 2. Esli ustrojstvo simvol'nogo tipa, yadro zapuskaet proceduru zakrytiya ust-
    rojstva i vozvrashchaet upravlenie v rezhim zadachi. Esli ustrojstvo blochnogo
    tipa,  yadro  prosmatrivaet tablicu rezul'tatov montirovaniya i proveryaet,
    ne raspolagaetsya li na ustrojstve smontirovannaya fajlovaya sistema.  Esli
    takaya sistema est', yadro ne smozhet zapustit' proceduru zakrytiya ustrojs-
    tva, poskol'ku ne byl sdelan poslednij vyzov funkcii close dlya ustrojst-
    va.  Dazhe  esli na ustrojstve net smontirovannoj fajlovoj sistemy, v bu-
    fernom keshe eshche mogut nahodit'sya bloki s dannymi, ostavshiesya ot  smonti-
    rovannoj  ranee  fajlovoj  sistemy i ne perepisannye na ustrojstvo, pos-
    kol'ku imeli pometku "otlozhennaya zapis'". Poetomu yadro prosmatrivaet bu-
    fernyj kesh v poiskah takih blokov i perepisyvaet ih na ustrojstvo  pered
    zapuskom  procedury  zakrytiya ustrojstva. Posle zakrytiya ustrojstva yadro
    vnov' prosmatrivaet bufernyj kesh i delaet nedejstvitel'nymi vse  bufery,
    kotorye soderzhat bloki dlya tol'ko chto zakrytogo ustrojstva, v to zhe vre-
    mya pozvolyaya buferam s aktual'noj informaciej ostat'sya v keshe.
 3. YAdro osvobozhdaet indeks fajla ustrojstva.
    Koroche govorya, procedura zakrytiya ustrojstva razryvaet svyaz' s ustrojst-
vom  i  inicializiruet zanovo informacionnye struktury drajvera i apparatnuyu
chast' ustrojstva s tem, chtoby  yadro  moglo  by  pozdnee  otkryt'  ustrojstvo

                                    297

vnov'.




    Algoritmy  chteniya i zapisi yadrom na ustrojstve pohozhi na analogichnye al-
goritmy dlya fajlov obychnogo tipa. Esli process proizvodit chtenie ili  zapis'
na  ustrojstve posimvol'nogo vvoda-vyvoda, yadro zapuskaet procedury read ili
write, opredelyaemye tipom drajvera. Nesmotrya na chasto  vstrechayushchiesya  situa-
cii,  kogda yadro osushchestvlyaet peredachu dannyh neposredstvenno mezhdu adresnym
prostranstvom zadachi i ustrojstvom, drajvery  ustrojstv  mogut  buferizovat'
informaciyu vnutri sebya. Naprimer, terminal'nye drajvery dlya buferizacii dan-
nyh  ispol'zuyut  simvol'nye  spiski (razdel 10.3.1). V takih sluchayah drajver
ustrojstva vydelyaet "bufer", kopiruet dannye iz prostranstva zadachi pri  vy-
polnenii  procedury  write i vyvodit ih iz "bufera" na ustrojstvo. Procedura
zapisi, upravlyaemaya drajverom, reguliruet ob®em vyvodimoj  informacii  (t.n.
upravlenie potokom dannyh): esli processy generiruyut informaciyu bystree, chem
ustrojstvo  vyvodit ee, procedura zapisi priostanavlivaet vypolnenie proces-
sov do teh por, poka ustrojstvo ne budet  gotovo  prinyat'  sleduyushchuyu  porciyu
dannyh. Pri chtenii drajver ustrojstva pomeshchaet dannye, poluchennye ot ustroj-
stva, v bufer i

                   Pamyat'

                   |     |
                   +-----+
             160110| CSR |         +------+ +---------tty00
                   | RDB +---------+ dz00 +-+---------tty01
                   | TDB |         +------+ |          ...
                   +-----+                  +---------tty07
             160120| CSR |         +------+ +---------tty08
             160122| RDB +---------+ dz01 +-+---------tty09
             160126| TDB |         +------+ |          ...
                   +-----+                  +---------tty15
                   |     |

    Risunok 10.5. Otobrazhenie v pamyati vvoda-vyvoda s ispol'zova-
                  niem kontrollera VAX DZ11


kopiruet  ih iz bufera v pol'zovatel'skie adresa, ukazannye v vyzove sistem-
noj funkcii.
    Konkretnyj metod vzaimodejstviya drajvera s ustrojstvom opredelyaetsya oso-
bennostyami apparatury. Nekotorye iz mashin obespechivayut otobrazhenie vvoda-vy-
voda v pamyati, podrazumevayushchee, chto konkretnye adresa v adresnom prostranst-
ve yadra yavlyayutsya ne nomerami yacheek v fizicheskoj pamyati, a  special'nymi  re-
gistrami,  kontroliruyushchimi sootvetstvuyushchie ustrojstva. Zapisyvaya v ukazannye
registry upravlyayushchie parametry v sootvetstvii so  specifikaciyami  apparatnyh
sredstv,  drajver  osushchestvlyaet upravlenie ustrojstvom. Naprimer, kontroller
vvoda-vyvoda dlya mashiny VAX-11 soderzhit special'nye registry dlya zapisi  in-
formacii  o sostoyanii ustrojstva (registry kontrolya i sostoyaniya) i dlya pere-
dachi dannyh (bufernye registry), kotorye formiruyutsya po special'nym  adresam
v fizicheskoj pamyati. V chastnosti, terminal'nyj kontroller VAX DZ11 upravlyaet
8 asinhronnymi liniyami terminal'noj svyazi (sm. [Levy 80], gde bolee podrobno
ob®yasnyaetsya arhitektura mashin VAX). Pust' registr kontrolya i sostoyaniya (CSR)
dlya  konkretnogo  terminala DZ11 imeet adres 160120, peredayushchij bufernyj re-
gistr (TDB) - adres 120126, a prinimayushchij bufernyj  registr  (RDB)  -  adres
160122   (Risunok  10.5).  Dlya  togo,  chtoby  peredat'  simvol  na  terminal
"/dev/tty09", drajver terminala zapisyvaet edinicu (1 = 9  po  modulyu  8)  v

                                    298

ukazannyj  dvoichnyj  razryad registra kontrolya i sostoyaniya i zatem zapisyvaet
simvol v peredayushchij bufernyj registr. Zapis' v peredayushchij  bufernyj  registr
yavlyaetsya  peredachej dannyh. Kontroller DZ11 vystavlyaet bit "vypolneno" v re-
gistre kontrolya i sostoyaniya, kogda gotov prinyat'  sleduyushchuyu  porciyu  dannyh.
Dopolnitel'no  drajver  mozhet vystavit' bit "vozmozhno preryvanie peredachi" v
registre kontrolya i sostoyaniya, chto zastavlyaet kontroller DZ11 preryvat'  ra-
botu  sistemy, kogda on gotov prinyat' sleduyushchuyu porciyu dannyh. CHtenie dannyh
iz DZ11 proizvoditsya analogichno.
    Na drugih mashinah imeetsya programmiruemyj  vvod-vyvod,  podrazumevayushchij,
chto  v mashine imeyutsya instrukcii po upravleniyu ustrojstvami. Drajvery uprav-
lyayut ustrojstvami, vypolnyaya sootvetstvuyushchie instrukcii. Naprimer,  v  mashine
IBM  370 imeetsya instrukciya "Start I/O" (Nachat' vvod-vyvod), kotoraya inicii-
ruet operaciyu vvoda-vyvoda, svyazannuyu s ustrojstvom. Sposob svyazi drajvera s
periferijnymi ustrojstvami nezameten dlya pol'zovatelya.
    Poskol'ku interfejs mezhdu drajverami ustrojstv i sootvetstvuyushchimi  appa-
ratnymi  sredstvami yavlyaetsya mashinno-zavisimym, na etom urovne ne sushchestvuet
standartnyh interfejsov. Kak v sluchae vvodavyvoda s otobrazheniem  v  pamyati,
tak  i v sluchae programmiruemogo vvoda-vyvoda drajver mozhet posylat' na ust-
rojstvo upravlyayushchie posledovatel'nosti s cel'yu ustanovleniya  rezhima  pryamogo
dostupa v pamyat' (PDP) dlya ustrojstva. Sistema pozvolyaet osushchestvlyat' masso-
vuyu  peredachu  dannyh mezhdu ustrojstvom i pamyat'yu v rezhime PDP parallel'no s
rabotoj central'nogo processora, pri etom ustrojstvo preryvaet rabotu siste-
my po zavershenii peredachi dannyh. Drajver organizuet upravlenie  virtual'noj
pamyat'yu takim obrazom, chtoby yachejki pamyati s ih dejstvitel'nymi nomerami is-
pol'zovalis' dlya PDP.
    Bystrodejstvuyushchie  ustrojstva mogut inogda peredavat' dannye neposredst-
venno v adresnoe prostranstvo zadachi, bez vmeshatel'stva bufera yadra.  V  re-
zul'tate povyshaetsya skorost' peredachi dannyh, poskol'ku pri etom proizvodit-
sya na odnu operaciyu kopirovaniya men'she, i, krome togo, ob®em dannyh, pereda-
vaemyh  za odnu operaciyu, ne ogranichivaetsya razmerom buferov yadra. Drajvery,
osushchestvlyayushchie takuyu peredachu  dannyh  bez  "obrabotki",  obychno  ispol'zuyut
blochnyj  interfejs  dlya  procedur  posimvol'nogo chteniya i zapisi, esli u nih
imeetsya dvojnik blochnogo tipa.




    YAdro ispol'zuet strategicheskij interfejs dlya peredachi dannyh  mezhdu  bu-
fernym keshem i ustrojstvom, hotya, kak uzhe govorilos' ranee, procedury chteniya
i  zapisi dlya ustrojstv posimvol'nogo vvodavyvoda inogda pol'zuyutsya procedu-
roj strategy (ih dvojnika blochnogo tipa) dlya neposredstvennoj peredachi  dan-
nyh  mezhdu  ustrojstvom  i adresnym prostranstvom zadachi. Procedura strategy
mozhet upravlyat' ocherednost'yu vypolneniya zadanij na vvod-vyvod,  svyazannyj  s
ustrojstvom, ili vypolnyat' bolee slozhnye dejstviya po planirovaniyu vypolneniya
podobnyh  zadanij. Drajvery v sostoyanii privyazyvat' peredachu dannyh k odnomu
fizicheskomu adresu ili ko mnogim. YAdro peredaet adres zagolovka bufera stra-
tegicheskoj procedure drajvera; v zagolovke soderzhitsya spisok adresov  (stra-
nic  pamyati) i razmery dannyh, peredavaemyh na ili s ustrojstva. Analogichnoe
dejstvie imeet mesto pri rabote mehanizma svopinga, opisannogo  v  glave  9.
Pri  rabote  s bufernym keshem yadro peredaet dannye s odnogo adresa; vo vremya
svopinga yadro peredaet dannye, raspolozhennye po neskol'kim adresam (stranicy
pamyati). Esli dannye kopiruyutsya iz ili v adresnoe prostranstvo zadachi, draj-
ver dolzhen blokirovat' process (ili po krajnej mere, sootvetstvuyushchie strani-
cy) v pamyati do zaversheniya peredachi dannyh.
    Naprimer, posle montirovaniya fajlovoj sistemy yadro identificiruet kazhdyj
fajl v fajlovoj sisteme po nomeru ustrojstva i nomeru indeksa. V nomere ust-
rojstva zakodirovany ego starshij i mladshij nomera. Kogda yadro  obrashchaetsya  k
bloku, kotoryj prinadlezhit fajlu, ono kopiruet nomer ustrojstva i nomer blo-
ka  v zagolovok bufera, kak uzhe govorilos' ranee v glave 3. Obrashcheniya k dis-

                                    299

ku, ispol'zuyushchie algoritmy raboty s  bufernym  keshem  (naprimer,  bread  ili
bwrite),  iniciiruyut vypolnenie strategicheskoj procedury, opredelyaemoj star-
shim nomerom ustrojstva. Strategicheskaya procedura ispol'zuet  znacheniya  polej
mladshego  nomera  i nomera bloka iz zagolovka bufera dlya identifikacii mesta
raspolozheniya dannyh na ustrojstve, a adres bufera - dlya identifikacii  mesta
naznacheniya peredavaemyh dannyh. Tochno tak zhe, kogda process obrashchaetsya k us-
trojstvu vvoda-vyvoda blokami neposredstvenno (naprimer, otkryvaya ustrojstvo
i  chitaya  ili  zapisyvaya na nego), on ispol'zuet algoritmy raboty s bufernym
keshem, i interfejs pri etom funkcioniruet vysheopisannym obrazom.




    Sistemnaya funkciya ioctl yavlyaetsya obobshcheniem  specifichnyh  dlya  terminala
funkcij  stty (zadat' ustanovki terminala) i gtty (poluchit' ustanovki termi-
nala), imevshihsya v rannih versiyah sistemy UNIX. Ona vystupaet v kachestve ob-
shchej tochki vhoda dlya vseh svyazannyh s tipom  ustrojstva  komand  i  pozvolyaet
processam  zadavat'  apparatnye  parametry, associirovannye s ustrojstvom, i
programmnye parametry, associirovannye s  drajverom.  Special'nye  dejstviya,
vypolnyaemye  funkciej ioctl dlya raznyh ustrojstv razlichny i opredelyayutsya ti-
pom drajvera. Programmy, ispol'zuyushchie vyzov ioctl, dolzhny  dolzhny  znat',  s
fajlom  kakogo tipa oni rabotayut, tak kak oni yavlyayutsya apparatno-zavisimymi.
Isklyuchenie iz obshchego pravila sdelano dlya sistemy, kotoraya ne vidit  razlichij
mezhdu  fajlami  raznyh tipov. Bolee podrobno ispol'zovanie funkcii ioctl dlya
terminalov rassmotreno v razdele 10.3.3.
    Sintaksis komandnoj stroki, soderzhashchej vyzov sistemnoj funkcii:

    ioctl(fd,command,arg);

gde fd - deskriptor fajla, vozvrashchaemyj  predvaritel'no  vyzvannoj  funkciej
open,  command  - dejstvie (komanda), kotoroe neobhodimo vypolnit' drajveru,
arg - parametr komandy (mozhet byt' ukazatelem na strukturu). Komandy  speci-
fichny  dlya razlichnyh drajverov; sledovatel'no, kazhdyj drajver interpretiruet
komandy v sootvetstvii so svoimi vnutrennimi specifikaciyami, ot  komandy,  v
svoyu  ochered', zavisit format struktury dannyh, opisyvaemoj peredavaemym pa-
rametrom. Drajvery mogut schityvat' strukturu dannyh arg iz prostranstva  za-
dachi v sootvetstvii s predopredelennym formatom ili zapisyvat' ustanovki us-
trojstva  v prostranstvo zadachi po adresu ukazannoj struktury. Naprimer, na-
lichie interfejsa, predostavlyaemogo funkciej ioctl, daet vozmozhnost'  pol'zo-
vatelyam  ustanavlivat'  dlya  terminala skorost' peredachi informacii v bodah,
perematyvat' magnitnuyu lentu, i, nakonec, vypolnyat' setevye operacii,  zada-
vaya nomera virtual'nyh kanalov i setevye adresa.




    Takie  funkcii raboty s fajlovoj sistemoj, kak stat i chmod, vypolnyayutsya
odinakovo, kak dlya obychnyh fajlov, tak i dlya ustrojstv; oni  manipuliruyut  s
indeksom, ne obrashchayas' k drajveru. Dazhe sistemnaya funkciya lseek rabotaet dlya
ustrojstv. Naprimer, esli process podvodit golovku na lentoprotyazhnom ustroj-
stve  k  ukazannomu  adresu  smeshcheniya v bajtah s pomoshch'yu funkcii lseek, yadro
korrektiruet smeshchenie v tablice fajlov no  ne  vypolnyaet  nikakih  dejstvij,
specifichnyh  dlya dannogo tipa drajvera. Kogda pozdnee process vypolnyaet chte-
nie (read) ili zapis' (write), yadro peresylaet  adres  smeshcheniya  iz  tablicy
fajlov v adresnoe prostranstvo zadachi, podobno tomu, kak eto imeet mesto pri
rabote  s fajlami obychnogo tipa, i ustrojstvo fizicheski peremeshchaet golovku k
sootvetstvuyushchemu smeshcheniyu, ukazannomu v prostranstve zadachi. |tot sluchaj il-
lyustriruetsya na primere v razdele 10.3.


                                    300

    Periferijnye         Soedinitel'naya              Vektor
     ustrojstva              panel'                preryvaniya
                                              +------------------+
                                              |         -        |
         tty00 -------------+                 |         -        |
         tty01 ....         |                 |         -        |
          ...               | +--+            +------------------+
         tty07 -------------+-+  |------------|     ttyintr 0    |
         tty08 -------------+ +--+            +------------------+
         tty09 ....         +-+  |------------|     ttyintr 1    |
          ...      +--------+ +--+            +------------------+
         tty15 ----+ +--------+  |------------|     consintr     |
       konsol' ------+        +--+            +------------------+
     printer00 -------------+-+  |------------|    printintr 0   |
               ....         | +--+            +------------------+
     printer03 -------------+ |  |            |         -        |
                              |  |            |         -        |
                              +--+            +------------------+

                Risunok 10.6. Preryvaniya ot ustrojstv





    Kak uzhe govorilos' vyshe (razdel 6.4.1), vozniknovenie preryvaniya  pobuzh-
daet yadro zapuskat' programmu obrabotki preryvanij, v osnove algoritma koto-
roj lezhit sootnoshenie mezhdu ustrojstvom, vyzvavshim preryvanie, i smeshcheniem v
tablice  vektorov  preryvanij. YAdro zapuskaet programmu obrabotki preryvanij
dlya dannogo tipa ustrojstva, peredavaya ej nomer ustrojstva ili drugie  para-
metry  dlya togo, chtoby identificirovat' edinicu ustrojstva, vyzvavshuyu prery-
vanie. Naprimer, v tablice vektorov preryvanij na Risunke 10.6 pokazany  dve
tochki  vhoda  dlya  obrabotki preryvanij ot terminalov ("ttyintr"), kazhdaya iz
kotoryh ispol'zuetsya dlya obrabotki preryvanij, postupivshih ot 8  terminalov.
Esli  ustrojstvo  tty09  prervalo rabotu sistemy, sistema vyzyvaet programmu
obrabotki preryvaniya, associirovannuyu s mestom apparatnogo podklyucheniya  ust-
rojstva.  Poskol'ku s odnoj zapis'yu v tablice vektorov preryvanij mozhet byt'
svyazano mnozhestvo fizicheskih ustrojstv, drajver  dolzhen  umet'  raspoznavat'
ustrojstvo,  vyzvavshee preryvanie. Na risunke zapisi v tablice vektorov pre-
ryvanij, sootvetstvuyushchie preryvaniyam ot terminalov, imeyut metki 0 i 1, chtoby
sistema razlichala ih mezhdu soboj pri vyzove programmy obrabotki  preryvanij,
ispol'zuya k primeru etot nomer v kachestve peredavaemogo programme parametra.
Programma  obrabotki  preryvanij  ispol'zuet etot nomer i druguyu informaciyu,
peredannuyu mehanizmom preryvaniya, dlya togo, chtoby udostoverit'sya, chto imenno
ustrojstvo tty09, a ne tty12, prervalo rabotu sistemy. |tot primer  v  upro-
shchennom vide pokazyvaet to, chto imeet mesto v real'nyh sistemah, gde na samom
dele  sushchestvuet  neskol'ko  urovnej kontrollerov i sootvetstvuyushchih programm
obrabotki preryvanij, no on illyustriruet obshchie principy.
    Esli podvesti itog, mozhno skazat', chto  nomer  ustrojstva,  ispol'zuemyj
programmoj  obrabotki preryvanij, identificiruet edinicu apparatury, a mlad-
shij nomer v fajle ustrojstva identificiruet ustrojstvo dlya yadra. Drajver us-
trojstva ustanavlivaet sootvetstvie mezhdu mladshim nomerom ustrojstva i nome-
rom edinicy apparatury.




    Tak slozhilos' istoricheski, chto diskovye ustrojstva v sistemah UNIX  raz-
bivalis'  na  razdely,  soderzhashchie  razlichnye fajlovye sistemy, chto oznachalo

                                    301

"delenie [diskovogo] paketa na neskol'ko upravlyaemyh po-svoemu chastej"  (sm.
[System  V 84b]). Naprimer, esli na diske raspolagayutsya chetyre fajlovye sis-
temy, administrator mozhet ostavit' odnu iz nih nesmontirovannoj, odnu  smon-
tirovat'  tol'ko dlya chteniya, a dve drugih tol'ko dlya zapisi. Nesmotrya na to,
chto vse fajlovye sistemy sosushchestvuyut na odnom fizicheskom ustrojstve,  pol'-
zovateli  ne  mogut ni obrashchat'sya k fajlam nemontirovannoj fajlovoj sistemy,
ispol'zuya metody dostupa, opisannye v glavah 4 i 5, ni  zapisyvat'  fajly  v
fajlovye sistemy, smontirovannye tol'ko dlya chteniya. Bolee togo, tak kak kazh-
dyj  razdel  (i,  sledovatel'no, fajlovaya sistema) zanimaet na diske smezhnye
dorozhki i cilindry, skopirovat' vsyu fajlovuyu sistemu legche, chem v  tom  slu-
chae, esli by razdel zanimal uchastki, razbrosannye po vsemu diskovomu tomu.
    Diskovyj  drajver transliruet adres fajlovoj sistemy, sostoyashchij iz logi-
cheskogo nomera ustrojstva i nomera bloka, v tochnyj nomer diskovogo  sektora.
Drajver  poluchaet adres odnim iz sleduyushchih putej: libo strategicheskaya proce-
dura ispol'zuet bufer iz bufernogo pula, zagolovok kotorogo soderzhit  nomera
ustrojstva  i  bloka,  libo  procedury  chteniya  i zapisi peredayut logicheskij
(mladshij) nomer ustrojstva v kachestve parametra; oni preobrazuyut adres  sme-
shcheniya  v  bajtah, hranyashchijsya v prostranstve zadachi, v adres sootvetstvuyushchego
bloka. Diskovyj drajver ispol'zuet nomer ustrojstva dlya identifikacii  fizi-
cheskogo  ustrojstva  i  ukazaniya ispol'zuemogo razdela, obrashchayas' pri etom k
vnutrennim tablicam dlya poiska sektora, otmechayushchego nachalo razdela na diske.
Nakonec, on dobavlyaet nomer bloka v fajlovoj sisteme k nomeru bloka, s koto-
rogo nachinaetsya kazhdyj sektor, chtoby identificirovat'  sektor,  ispol'zuemyj
dlya vvoda-vyvoda.

         +---------------------------------------------+
         | Razdel    Nachal'nyj blok     Dlina v blokah |
         |                                             |
         |           Razmer bloka = 512 bajt           |
         |                                             |
         |    0                0                 64000 |
         |    1            64000                944000 |
         |    2           168000                840000 |
         |    3           336000                672000 |
         |    4           504000                504000 |
         |    5           672000                336000 |
         |    6           840000                168000 |
         |    7                0               1008000 |
         +---------------------------------------------+

               Risunok 10.7. Razdely na diske RP07


    Istoricheski slozhilos' tak, chto razmery diskovyh razdelov ustanavlivayutsya
v  zavisimosti ot tipa diska. Naprimer, disk DEC RP07 razbit na razdely, ha-
rakteristika kotoryh privedena  na  Risunke  10.7.  Predpolozhim,  chto  fajly
"/dev/dsk0",  "/dev/dsk1",  "/dev/dsk2" i "/dev/dsk3" sootvetstvuyut razdelam
diska RP07, imeyushchim nomera ot 0 do 3, i imeyut  analogichnye  mladshie  nomera.
Pust'  razmer logicheskogo bloka v fajlovoj sisteme sovpadaet s razmerom dis-
kovogo bloka. Esli yadro pytaetsya obratit'sya k bloku s nomerom 940 v fajlovoj
sisteme, hranyashchejsya v "/dev/dsk3", diskovyj drajver  pereadresuet  zapros  k
bloku  s nomerom 336940 (razdel 3 nachinaetsya s bloka, imeyushchego nomer 336000;
336000 + 940 = 336940) na diske.
    Razmery razdelov na diske var'iruyutsya i administratory raspolagayut  faj-
lovye  sistemy v razdelah sootvetstvuyushchego razmera: bol'shie fajlovye sistemy
popadayut v razdely bol'shego razmera i t. d. Razdely na diske mogut  perekry-
vat'sya. Naprimer, razdely 0 i 1 na diske RP07 ne peresekayutsya, no vmeste oni
zanimayut  bloki  s nomerami ot 0 do 1008000, to est' ves' disk. Razdel 7 tak
zhe zanimaet ves' disk. Perekrytie razdelov ne imeet znacheniya, poskol'ku faj-

                                    302

lovye sistemy, hranyashchiesya v razdelah, razmeshchayutsya takim obrazom,  chto  mezhdu
nimi  net  peresechenij.  Imet'  odin  razdel, vklyuchayushchij v sebya vse diskovoe
prostranstvo, vygodno, poskol'ku ves' tom mozhno bystro skopirovat'.
    Ispol'zovanie razdelov fiksirovannogo  sostava  i  razmera  ogranichivaet
gibkost'  diskovoj konfiguracii. Informaciyu o razdelah v zakodirovannom vide
ne sleduet vklyuchat' v diskovyj drajver, no nuzhno pomestit' v tablicu  soder-
zhimogo diskovogo toma. Odnako, najti obshchee mesto na vseh diskah dlya razmeshche-
niya tablicy soderzhimogo diskovogo toma i sohranit' tem samym sovmestimost' s
predydushchimi  versiyami  sistemy  dovol'no  trudno. V sushchestvuyushchih realizaciyah
versii V predpolagaetsya, chto blok nachal'noj zagruzki pervoj iz fajlovyh sis-
tem na diske zanimaet pervyj sektor toma, hotya po logike eto,  kazalos'  by,
samoe podhodyashchee mesto dlya tablicy soderzhimogo toma. I vse zhe diskovyj draj-
ver  dolzhen imet' zakodirovannuyu informaciyu o meste raspolozheniya tablicy so-
derzhimogo toma dlya kazhdogo diska, ne prepyatstvuya sushchestvovaniyu diskovyh raz-
delov peremennogo razmera.
    V svyazi s tem, chto dlya sistemy UNIX yavlyaetsya  tipichnym  vysokij  uroven'
diskovogo  trafika,  drajver  diska dolzhen maksimizirovat' peredachu dannyh s
tem, chtoby obespechit' nailuchshuyu proizvoditel'nost'  vsej  sistemy.  Novejshie
diskovye kontrollery osushchestvlyayut planirovanie vypolneniya zadanij, trebuyushchih
obrashcheniya  k disku, pozicioniruyut golovku diska i obespechivayut peredachu dan-
nyh mezhdu diskom i central'nym processorom; inache eto prihoditsya delat' dis-
kovomu drajveru.
    Servisnye programmy mogut neposredstvenno obrashchat'sya  k  disku  v  obhod
standartnogo  metoda dostupa k fajlovoj sisteme, rassmotrennogo v glavah 4 i
5, kak pol'zuyas' blochnym interfejsom, tak i ne pribegaya  k  strukturirovaniyu
dannyh.  Neposredstvenno  rabotayut  s  diskom  dve vazhnye programmy - mkfs i
fsck. Programma mkfs formatiruet razdel diska  dlya  fajlovoj  sistemy  UNIX,
sozdavaya pri etom superblok, spisok indeksov, spisok svobodnyh diskovyh blo-
kov  s ukazatelyami i kornevoj katalog novoj fajlovoj sistemy. Programma fsck
proveryaet celostnost' sushchestvuyushchej fajlovoj sistemy i ispravlyaet oshibki, kak
pokazano v glave 5.
    Rassmotrim programmu, privedennuyu na Risunke 10.8, v primenenii k fajlam
"/dev/dsk15" i "/dev/rdsk15", i predpolozhim, chto komanda ls vydala sleduyushchuyu
informaciyu:
    ls -1 /dev/dsk15 /dev/rdsk15

    br--------  2 root   root   0,21 Feb 12 15:40   /dev/dsk15
    crw-rw----  2 root   root   7,21 Mar  7 09:29   /dev/rdsk15

    Otsyuda vidno, chto fajl "/dev/dsk15"  sootvetstvuet  ustrojstvu  blochnogo
tipa,  vladel'cem kotorogo yavlyaetsya pol'zovatel' pod imenem "root", i tol'ko
pol'zovatel' "root" mozhet chitat' s nego neposredstvenno. Ego starshij nomer -
0, mladshij - 21. Fajl "/dev/rdsk15" sootvetstvuet  ustrojstvu  posimvol'nogo
vvoda-vyvoda, vladel'cem kotorogo yavlyaetsya pol'zovatel' "root", odnako prava
dostupa  k kotoromu na zapis' i chtenie est' kak u vladel'ca, tak i u gruppy.
Ego starshij nomer - 7, mladshij - 21. Process,  otkryvayushchij  fajly,  poluchaet
dostup k ustrojstvu cherez tablicu klyu-
chej  ustrojstv vvoda-vyvoda blokami i tablicu klyuchej ustrojstv posimvol'nogo
vvoda-vyvoda, sootvetstvenno, a  mladshij  nomer  ustrojstva  21  informiruet
drajver o tom, k kakomu razdelu diska proizvoditsya obrashchenie, naprimer, dis-
kovod 2, razdel 1. Poskol'ku mladshie nomera u fajlov sovpadayut, oni ssylayut-
sya na odin i tot zhe razdel diska, esli predpolozhit', chto eto odno ustrojstvo
(***).  Takim  obrazom, process, vypolnyayushchij programmu, otkryvaet odin i tot

---------------------------------------
(***) Ne sushchestvuet inogo sposoba ustanovit', chto simvol'nyj i blochnyj draj-
      very ssylayutsya na odno i to zhe ustrojstvo, krome prosmotra tablic sis-
      temnoj konfiguracii i teksta programm drajvera.


                                    303

zhe drajver dvazhdy (ispol'zuya razlichnye interfejsy), pozicioniruet golovku  k
smeshcheniyu  s adresom 8192 i schityvaet dannye s etogo mesta. Rezul'taty vypol-
neniya operacij chteniya dolzhny byt'  identichnymi  pri  uslovii,  chto  rabotaet
tol'ko odna fajlovaya sistema.

    +------------------------------------------------------------+
    | #include "fcntl.h"                                         |
    | main()                                                     |
    | {                                                          |
    |      char buf1[4096], buf2[4096]                           |
    |      int fd1, fd2, i;                                      |
    |                                                            |
    |      if (((fd1 = open("/dev/dsk5/", O_RDONLY)) == -1) ||   |
    |               ((fd2 = open("/dev/rdsk5", O_RDONLY)) == -1))|
    |      {                                                     |
    |            printf("oshibka pri otkrytii\n");                |
    |            exit();                                         |
    |      }                                                     |
    |                                                            |
    |      lseek(fd1, 8192L, 0);                                 |
    |      lseek(fd2, 8192L, 0);                                 |
    |                                                            |
    |      if ((read(fd1, buf1, sizeof(buf1)) == -1) ||          |
    |          (read(fd2, buf2, sizeof(buf2)) == -1))            |
    |      {                                                     |
    |            printf("oshibka pri chtenii\n");                  |
    |            exit();                                         |
    |      }                                                     |
    |                                                            |
    |      for (i = 0; i < sizeof(buf1); i++)                    |
    |            if (buf1[i] != buf2[i])                         |
    |            {                                               |
    |                 printf("razlichie v smeshchenii %d\n", i);     |
    |                 exit();                                    |
    |            }                                               |
    |      printf("dannye sovpadayut\n");                         |
    | }                                                          |
    +------------------------------------------------------------+

    Risunok 10.8. CHtenie dannyh s diska s ispol'zovaniem blochnogo
                  interfejsa i bez strukturirovaniya dannyh


    Programmy, osushchestvlyayushchie chtenie i zapis' na disk neposredstvenno, pred-
stavlyayut  opasnost',  poskol'ku  manipuliruyut  s chuvstvitel'noj informaciej,
riskuya narushit' sistemnuyu zashchitu. Administratoram sleduet zashchishchat' interfej-
sy vvoda-vyvoda putem ustanovki prav dostupa k  fajlam  diskovyh  ustrojstv.
Naprimer,  diskovye  fajly  "/dev/dsk15" i "/dev/rdsk15" dolzhny prinadlezhat'
pol'zovatelyu s imenem "root", i prava dostupa k nim dolzhny  byt'  opredeleny
takim  obrazom,  chtoby pol'zovatelyu "root" bylo razresheno chtenie, a vsem os-
tal'nym pol'zovatelyam i chtenie, i zapis' dolzhny byt' zapreshcheny.
    Programmy, osushchestvlyayushchie chtenie i zapis' na disk neposredstvenno, mogut
takzhe narushit' celostnost' dannyh v  fajlovoj  sisteme.  Algoritmy  fajlovoj
sistemy,  rassmotrennye  v glavah 3, 4 i 5, koordiniruyut vypolnenie operacij
vvoda-vyvoda, svyazannyh s diskom, tem samym podderzhivaya celostnost' informa-
cionnyh struktur na diske, v tom chisle spiska svobodnyh  diskovyh  blokov  i
ukazatelej iz indeksov na informacionnye bloki pryamoj i kosvennoj adresacii.
Processy, obrashchayushchiesya k disku neposredstvenno, obhodyat eti algoritmy. Pust'
dazhe ih programmy napisany s bol'shoj ostorozhnost'yu, problema celostnosti vse

                                    304

ravno  ne ischeznet, esli oni vypolnyayutsya parallel'no s rabotoj drugoj fajlo-
voj sistemy. Po etoj prichine programma fsck ne dolzhna vypolnyat'sya pri  nali-
chii aktivnoj fajlovoj sistemy.
    Dva  tipa  diskovogo interfejsa razlichayutsya mezhdu soboj po ispol'zovaniyu
bufernogo kesha. Pri rabote s blochnym interfejsom yadro pol'zuetsya tem zhe  al-
goritmom,  chto i dlya fajlov obychnogo tipa, isklyuchenie sostavlyaet tot moment,
kogda posle preobrazovaniya adresa smeshcheniya logicheskogo bajta v adres  smeshche-
niya  logicheskogo bloka (sm. algoritm bmap v glave 4) ono traktuet adres sme-
shcheniya logicheskogo bloka kak fizicheskij nomer bloka v fajlovoj  sisteme.  Za-
tem,  ispol'zuya bufernyj kesh, yadro obrashchaetsya k dannym, i, v konechnom itoge,
k strategicheskomu interfejsu drajvera. Odnako, pri obrashchenii k  disku  cherez
simvol'nyj interfejs (bez strukturirovaniya dannyh), yadro ne prevrashchaet adres
smeshcheniya  v  adres  fajla, a peredaet ego nemedlenno drajveru, ispol'zuya dlya
peredachi rabochee prostranstvo zadachi. Procedury chteniya i zapisi, vhodyashchie  v
sostav drajvera, preobrazuyut smeshchenie v bajtah v smeshchenie v blokah i kopiru-
yut dannye neposredstvenno v adresnoe prostranstvo zadachi, minuya bufery yadra.
    Takim obrazom, esli odin process zapisyvaet na ustrojstvo blochnogo tipa,
a  vtoroj  process  zatem schityvaet s ustrojstva simvol'nogo tipa po tomu zhe
adresu, vtoroj process mozhet ne schitat' informaciyu, zapisannuyu  pervym  pro-
cessom,  tak  kak  informaciya  mozhet eshche nahodit'sya v bufernom keshe, a ne na
diske. Tem ne menee, esli vtoroj process obratitsya k ustrojstvu blochnogo ti-
pa, on avtomaticheski popadet na novye dannye, nahodyashchiesya v bufernom keshe.
    Pri ispol'zovanii simvol'nogo interfejsa mozhno stolknut'sya  so  strannoj
situaciej.  Esli  process  chitaet ili pishet na ustrojstvo posimvol'nogo vvo-
da-vyvoda porciyami men'shego razmera, chem, k primeru, blok, rezul'taty  budut
zaviset' ot drajvera. Naprimer, esli proizvodit' zapis' na lentu po 1 bajtu,
kazhdyj bajt mozhet popast' v lyuboj iz lentochnyh blokov.
    Preimushchestvo  ispol'zovaniya  simvol'nogo  interfejsa sostoit v skorosti,
esli ne voznikaet neobhodimost' v keshirovanii dannyh dlya dal'nejshej  raboty.
Processy,  obrashchayushchiesya k ustrojstvam vvoda -vyvoda blokami, peredayut infor-
maciyu blokami, razmer kazhdogo iz kotoryh ogranichivaetsya razmerom logicheskogo
bloka v dannoj fajlovoj sisteme. Naprimer, esli razmer logicheskogo  bloka  v
fajlovoj  sisteme 1 Kbajt, za odnu operaciyu vvoda-vyvoda mozhet byt' peredano
ne bol'she 1 Kbajta informacii. Pri etom processy, obrashchayushchiesya k disku s po-
moshch'yu simvol'nogo interfejsa, mogut peredavat'  za  odnu  diskovuyu  operaciyu
mnozhestvo  diskovyh blokov, v zavisimosti ot vozmozhnostej diskovogo kontrol-
lera. S funkcional'noj tochki zreniya, process poluchaet tot zhe  samyj  rezul'-
tat, no simvol'nyj interfejs mozhet rabotat' gorazdo bystree. Esli vospol'zo-
vat'sya  primerom, privedennym na Risunke 10.8, mozhno uvidet', chto kogda pro-
cess schityvaet 4096 bajt, ispol'zuya blochnyj interfejs dlya fajlovoj sistemy s
razmerom bloka 1 Kbajt, yadro proizvodit chetyre vnutrennie iteracii, na  kazh-
dom shage obrashchayas' k disku, prezhde chem vyzvannaya sistemnaya funkciya vozvrashcha-
et upravlenie, no kogda process ispol'zuet simvol'nyj interfejs, drajver mo-
zhet  zakonchit'  chtenie  za odnu diskovuyu operaciyu. Bolee togo, ispol'zovanie
blochnogo interfejsa vyzyvaet dopolnitel'noe kopirovanie dannyh mezhdu  adres-
nym  prostranstvom  zadachi i buferami yadra, chto otsutstvuet v simvol'nom in-
terfejse.




    Terminal'nye drajvery vypolnyayut tu zhe funkciyu, chto i ostal'nye drajvery:
upravlenie peredachej dannyh ot i na terminaly. Odnako, terminaly imeyut  odnu
osobennost',  svyazannuyu s tem, chto oni obespechivayut interfejs pol'zovatelya s
sistemoj. Obespechivaya interaktivnoe ispol'zovanie sistemy UNIX, terminal'nye
drajvery imeyut svoj vnutrennij interfejs s modulyami, interpretiruyushchimi  vvod
i  vyvod strok. V kanonicheskom rezhime interpretatory strok preobrazuyut nest-
rukturirovannye posledovatel'nosti dannyh, vvedennye s klaviatury, v kanoni-
cheskuyu formu (to est' v formu, sootvetstvuyushchuyu tomu, chto pol'zovatel' imel v

                                    305

vidu na samom dele) prezhde, chem poslat' eti  dannye  prinimayushchemu  processu;
strokovyj interfejs takzhe preobrazuet nestrukturirovannye posledovatel'nosti
vyhodnyh  dannyh, sozdannyh processom, v format, neobhodimyj pol'zovatelyu. V
rezhime bez obrabotki strokovyj interfejs peredaet dannye mezhdu processami  i
terminalom bez kakih-libo preobrazovanij.
    Programmisty,  naprimer, rabotayut na klaviature terminala dovol'no byst-
ro, no s oshibkami. Na etot sluchaj terminaly imeyut klavishu stiraniya ("erase";
klavisha mozhet byt' oboznachena takim obrazom), chtoby pol'zovatel'  imel  voz-
mozhnost'  stirat' chast' vvedennoj stroki i vvodit' korrektivy. Terminaly pe-
resylayut mashine vsyu vvedennuyu posledovatel'nost', vklyuchaya i simvoly stiraniya
(*** *). V kanonicheskom rezhime strokovyj interfejs buferizuet  informaciyu  v
stroki (nabor simvolov, zakanchivayushchijsya simvolom vozvrata karetki (*****)) i
processy  stirayut simvoly u sebya, prezhde chem pereslat' ispravlennuyu posledo-
vatel'nost' schityvayushchemu processu.
    V funkcii strokovogo interfejsa vhodyat:
  * postrochnyj razbor vvedennyh posledovatel'nostej;
  * obrabotka simvolov stiraniya;
  * obrabotka simvolov "udaleniya", otmenyayushchih vse ostal'nye simvoly, vveden-
    nye do togo v tekushchej stroke;
  * otobrazhenie simvolov, poluchennyh terminalom;
  * rasshirenie vyhodnyh dannyh, naprimer, preobrazovanie simvolov  tabulyacii
    v posledovatel'nosti probelov;
  * signalizirovanie processam o zavisanii terminalov i preryvanii strok ili
    v otvet na nazhatie pol'zovatelem klavishi udaleniya;
  *  predostavlenie  vozmozhnosti  ne obrabatyvat' special'nye simvoly, takie
    kak simvoly stiraniya, udaleniya i vozvrata karetki.

    Funkcionirovanie bez obrabotki podrazumevaet ispol'zovanie  asinhronnogo
terminala,  poskol'ku  processy  mogut schityvat' simvoly v tom vide, v kakom
oni byli vvedeny, vmesto togo, chtoby zhdat', kogda pol'zovatel' nazhmet klavi-
shu vvoda ili vozvrata karetki.
    Richi otmetil, chto pervye strokovye interfejsy, ispol'zuemye eshche pri raz-
rabotke sistemy v nachale 70-h godov, rabotali v sostave programm  komandnogo
processora  i  redaktora, no ne v yadre (sm. [Ritchie 84], str.1580). Odnako,
poskol'ku v ih funkciyah nuzhdaetsya mnozhestvo programm, ih mesto v sostave yad-
ra. Nesmotrya na to, chto strokovyj interfejs vypolnyaet takie funkcii, iz  ko-
toryh  logicheski vytekaet ego mesto mezhdu terminal'nym drajverom i ostal'noj
chast'yu yadra, yadro ne zapuskaet strokovyj interfejs inache, chem  cherez  termi-
nal'nyj  drajver.  Na  Risunke  10.9 pokazany potok dannyh, prohodyashchij cherez
terminal'nyj drajver i strokovyj interfejs, i sootvetstvuyushchie emu  upravlyayu-
shchie  vozdejstviya,  prohodyashchie cherez terminal'nyj drajver. Pol'zovateli mogut
ukazat', kakoj strokovyj interfejs ispol'zuetsya posredstvom vyzova sistemnoj
funkcii ioctl, no realizovat' shemu, po kotoroj odno ustrojstvo ispol'zovalo
by neskol'ko strokovyh interfejsov odnovremenno, pri chem kazhdyj interfejsnyj
modul', v svoyu ochered', uspeshno vyzyval by sleduyushchij  modul'  dlya  obrabotki
dannyh, dovol'no trudno.



    Strokovyj interfejs obrabatyvaet dannye v simvol'nyh spiskah. Simvol'nyj
spisok  (clist) predstavlyaet soboj peremennoj dliny spisok simvol'nyh blokov
s ispol'zovaniem ukazatelej i s podschetom kolichestva simvolov v spiske. Sim-

---------------------------------------
(****) V etom razdele rassmatrivaetsya ispol'zovanie terminalov vvoda-vyvoda,
       kotorye peredayut vse simvoly, vvedennye pol'zovatelem, bez obrabotki.
(*****) V dannoj glave ispol'zuetsya obshchij termin "vozvrat karetki" dlya oboz-
        nacheniya simvolov vozvrata karetki i perevoda stroki.


                                    306

            Potok dannyh                  Potok upravlyayushchih
                                             vozdejstvij
      +-----------------------+       +-----------------------+
      | Process chteniya/zapisi |       | Process chteniya/zapisi |
      +-----------------------+       +-----------------------+

         -  |          ^   -                 |         ^
       -    v          |     -               v         |
     - +---------------------+ -      +-----------------------+
 vyvod | Strokovyj  interfejs| vvod   | Terminal'nyj drajver  |
     - +---------------------+ -      +-----------------------+
       -    |          ^     -               |         ^
         -  v          |   -                 v         |
      +-----------------------+        +---------------------+
      | Terminal'nyj drajver  |        | Strokovyj interfejs |
      +-----------------------+        +---------------------+
                                             |         ^
                                             v         |
                                      +-----------------------+
                                      | Drajver vvoda-vyvoda  |
                                      +-----------------------+
                                             |         ^
                                             v         |
                                     +-------------------------+
                                     | Ustrojstvo vvoda-vyvoda |
                                     +-------------------------+

    Risunok 10.9. Posledovatel'nost' obrashchenij i potok dannyh che-
                  rez strokovyj interfejs

Ukazatel'   Smeshchenie  Smeshchenie
   na          do        do
sleduyushchij    nachala    konca           Massiv simvolov
  blok                          0 1 2 3 4 5 6 7 8 9        14
----------+---------+---------++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---
          |    7    |    14   ||g|a|r|b|a|g|e||| |e|q|n| ||| |...
----+-----+---------+---------++-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+---
    |
    v

                Risunok 10.10. Simvol'nyj blok


vol'nyj blok (cblock) soderzhit ukazatel' na sleduyushchij blok v spiske, nebol'-
shoj massiv hranimoj v simvol'nom vide informacii i adresa smeshchenij,  pokazy-
vayushchie  mesto  raspolozheniya  vnutri  bloka  korrektnoj  informacii  (Risunok
10.10). Smeshchenie do nachala pokazyvaet pervuyu poziciyu raspolozheniya korrektnoj
informacii v massive, smeshchenie do konca pokazyvaet pervuyu poziciyu raspolozhe-
niya nekorrektnoj informacii.
    YAdro obespechivaet vedenie spiska svobodnyh simvol'nyh blokov i vypolnyaet
nad simvol'nymi spiskami i simvol'nymi blokami shest' operacij.
 1. YAdro naznachaet drajveru simvol'nyj blok iz spiska  svobodnyh  simvol'nyh
    blokov.
 2.  Ono takzhe vozvrashchaet simvol'nyj blok v spisok svobodnyh simvol'nyh blo-
    kov.
 3. YAdro mozhet vybirat' pervyj simvol iz  simvol'nogo  spiska:  ono  udalyaet
    pervyj simvol iz pervogo simvol'nogo bloka v spiske i ustanavlivaet zna-
    cheniya  schetchika  simvolov  v  spiske i ukazatelej v bloke takim obrazom,
    chtoby posleduyushchie operacii ne vybirali odin i tot zhe simvol. Esli v  re-

                                    307

    zul'tate  operacii vybran poslednij simvol bloka, yadro pomeshchaet v spisok
    svobodnyh simvol'nyh blokov pustoj blok i pereustanavlivaet ukazateli  v
    simvol'nom  spiske.  Esli  v simvol'nom spiske otsutstvuyut simvoly, yadro
    vozvrashchaet pustoj simvol.
 4. YAdro mozhet pomestit' simvol v konec simvol'nogo spiska putem poiska pos-
    lednego simvol'nogo bloka v spiske, vklyucheniya simvola v nego i pereusta-
    novki adresov smeshchenij. Esli simvol'nyj blok zapolnen, yadro vydelyaet no-
    vyj simvol'nyj blok, vklyuchaet ego v konec simvol'nogo spiska i  pomeshchaet
    simvol v novyj blok.
 5.  YAdro  mozhet udalyat' ot nachala spiska gruppu simvolov po odnomu bloku za
    odnu operaciyu, chto ekvivalentno udaleniyu vseh simvolov v bloke  za  odin
    raz.
 6.  YAdro  mozhet pomestit' blok s simvolami v konec simvol'nogo spiska.

    Simvol'nye spiski pozvolyayut sozdat' neslozhnyj mehanizm buferizacii,  po-
leznyj pri nebol'shom ob®eme peredavaemyh dannyh, tipichnom dlya medlennyh ust-
rojstv, takih kak terminaly. Oni dayut vozmozhnost' manipulirovat' s dannymi s
kazhdym simvolom v otdel'nosti i s gruppoj simvol'nyh blokov. Naprimer, Risu-
nok 10.11 illyustriruet udalenie simvolov iz simvol'nogo spiska; yadro udalyaet
po  odnomu  simvolu iz pervogo bloka v spiske (Risunok 10.11a-v) do teh por,
poka v bloke ne ostanetsya ni odnogo simvola (Risunok

    simvol'nyj                               simvol'nye
      spisok                                   bloki

                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | p | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
+----------+-+  |      |  0 8  | | * |   | | |   | t | b | l |   |
|    27    | +--+      ++------+ +---+---+---+---+---+---+---+---+
| simvolov | +--+       v
+----------+-+  |      +-------+ +---+---+---+---+---+---+---+---+
                |      |  0 8  | | | |   | t | r | o | f | f |   |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 3  | | - | m | m |   |   |   |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (a)

                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  1 8  | |   | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
+----------+-+  |      |  0 8  | | * |   | | |   | t | b | l |   |
|    26    | +--+      ++------+ +---+---+---+---+---+---+---+---+
| simvolov | +--+       v
+----------+-+  |      +-------+ +---+---+---+---+---+---+---+---+
                |      |  0 8  | | | |   | t | r | o | f | f |   |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 3  | | - | m | m |   |   |   |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (b)


                                    308

                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  2 8  | |   |   | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
+----------+-+  |      |  0 8  | | * |   | | |   | t | b | l |   |
|    25    | +--+      ++------+ +---+---+---+---+---+---+---+---+
| simvolov | +--+       v
+----------+-+  |      +-------+ +---+---+---+---+---+---+---+---+
                |      |  0 8  | | | |   | t | r | o | f | f |   |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 3  | | - | m | m |   |   |   |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (v)

                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | * |   | | |   | t | b | l |   |
                |      ++------+ +---+---+---+---+---+---+---+---+
+----------+-+  |       v
|    19    | +--+      +-------+ +---+---+---+---+---+---+---+---+
| simvolov | +--+      |  0 8  | | | |   | t | r | o | f | f |   |
+----------+-+  |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 3  | | - | m | m |   |   |   |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (g)

       Risunok 10.11. Udalenie simvolov iz simvol'nogo spiska


    simvol'nyj                               simvol'nye
      spisok                                   bloki

                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | p | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
+----------+-+  |       v
|    22    | +--+      +-------+ +---+---+---+---+---+---+---+---+
| simvola  | +--+      |  0 8  | | * |   | | |   | t | b | l |   |
+----------+-+  |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 6  | | | |   | t | r | o | f |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (a)
                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | p | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
+----------+-+  |       v
|    23    | +--+      +-------+ +---+---+---+---+---+---+---+---+
| simvola  | +--+      |  0 8  | | * |   | | |   | t | b | l |   |
+----------+-+  |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 7  | | | |   | t | r | o | f | f |   |
                       +-------+ +---+---+---+---+---+---+---+---+

                                    309

                   (b)
                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | p | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
+----------+-+  |       v
|    24    | +--+      +-------+ +---+---+---+---+---+---+---+---+
| simvola  | +--+      |  0 8  | | * |   | | |   | t | b | l |   |
+----------+-+  |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | | |   | t | r | o | f | f |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (v)
                       +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 8  | | p | i | c |   | f | i | l | e |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
+----------+-+  |      |  0 8  | | * |   | | |   | t | b | l |   |
|    25    | +--+      ++------+ +---+---+---+---+---+---+---+---+
| simvolov | +--+       v
+----------+-+  |      +-------+ +---+---+---+---+---+---+---+---+
                |      |  0 8  | | | |   | t | r | o | f | f |   |
                |      ++------+ +---+---+---+---+---+---+---+---+
                |       v
                |      +-------+ +---+---+---+---+---+---+---+---+
                +----->|  0 1  | | - |   |   |   |   |   |   |   |
                       +-------+ +---+---+---+---+---+---+---+---+
                   (g)

       Risunok 10.12. Vklyuchenie simvolov v simvol'nyj spisok

10.11g); zatem ono ustanavlivaet ukazatel' spiska na sleduyushchij blok, kotoryj
stanovitsya pervym blokom v spiske. Podobno etomu na Risunke 10.12  pokazano,
kak  yadro vklyuchaet simvoly v simvol'nyj spisok; pri etom predpolagaetsya, chto
v odnom bloke pomeshchaetsya do 8 simvolov i chto yadro  razmeshchaet  novyj  blok  v
konce spiska (Risunok 10.12g).




    Struktury  dannyh,  s kotorymi rabotayut terminal'nye drajvery, svyazany s
tremya simvol'nymi spiskami: spiskom dlya hraneniya dannyh, vyvodimyh na termi-
nal, spiskom dlya hraneniya nestrukturirovannyh vvodnyh dannyh, postupivshih  v
rezul'tate vypolneniya programmy obrabotki preryvaniya ot terminala, vyzvanno-
go  popytkoj pol'zovatelya vvesti dannye s klaviatury, i spiskom dlya hraneniya
obrabotannyh vhodnyh dannyh, postupivshih v rezul'tate preobrazovaniya stroko-
vym interfejsom special'nyh simvolov (takih kak simvoly stiraniya i udaleniya)
v nestrukturirovannom spiske.
    Kogda process vedet zapis' na  terminal  (Risunok  10.13),  terminal'nyj
drajver zapuskaet strokovyj interfejs. Strokovyj interfejs v cikle schityvaet
simvoly iz adresnogo prostranstva processa i pomeshchaet ih v simvol'nyj spisok
dlya  hraneniya  vyvodnyh dannyh do teh por, poka potok dannyh ne budet ischer-
pan. Strokovyj interfejs obrabatyvaet vyvodimye simvoly,  naprimer,  zamenyaya
simvoly tabulyacii na posledovatel'nosti probelov. Esli kolichestvo simvolov v
spiske  dlya hraneniya vyvodnyh dannyh prevysit verhnyuyu otmetku, strokovyj in-
terfejs vyzyvaet procedury  drajvera,  peresylayushchie  dannye  iz  simvol'nogo
spiska na terminal i posle etogo priostanavlivayushchie vypolnenie processa, ve-


                                    310

    +------------------------------------------------------------+
    | algoritm terminal_write                                    |
    | {                                                          |
    |     vypolnit' (poka iz prostranstva zadachi eshche postupayut   |
    |      dannye)                                               |
    |     {                                                      |
    |         esli (na terminal postupaet informaciya)            |
    |         {                                                  |
    |             pristupit' k vypolneniyu operacii zapisi dannyh |
    |              iz spiska, hranyashchego vyvodnye dannye;         |
    |             priostanovit'sya (do togo momenta, kogda termi- |
    |              nal budet gotov prinyat' sleduyushchuyu porciyu dan- |
    |              nyh);                                         |
    |             prodolzhit';   /* vozvrat k nachalu cikla */     |
    |         }                                                  |
    |         skopirovat' dannye v ob®eme simvol'nogo bloka iz   |
    |          prostranstva zadachi v spisok, hranyashchij vyvodnye   |
    |          dannye: strokovyj interfejs preobrazuet simvoly   |
    |          tabulyacii i t.d.;                                 |
    |     }                                                      |
    |                                                            |
    |     pristupit' k vypolneniyu operacii zapisi dannyh iz spis-|
    |      ka, hranyashchego vyvodnye dannye;                        |
    | }                                                          |
    +------------------------------------------------------------+

         Risunok 10.13. Algoritm perepisi dannyh na terminal


dushchego  zapis'. Kogda ob®em informacii v spiske dlya hraneniya vyvodnyh dannyh
padaet za nizhnyuyu otmetku, programma obrabotki preryvanij vozobnovlyaet vypol-
nenie vseh processov, priostanovlennyh do togo momenta, kogda terminal  smo-
zhet  prinyat' sleduyushchuyu porciyu dannyh. Strokovyj interfejs zavershaet cikl ob-
rabotki, skopirovav vsyu vyvodimuyu informaciyu iz adresnogo prostranstva zada-
chi v sootvetstvuyushchij simvol'nyj spisok, i vyzyvaet vypolnenie procedur draj-
vera, peresylayushchih dannye na terminal, o kotoryh uzhe bylo skazano vyshe.
    Esli na terminal vedut zapis' neskol'ko processov, oni  nezavisimo  drug
ot  druga sleduyut ukazannoj procedure. Vyvodimaya informaciya mozhet byt' iska-
zhena; to est' na terminale dannye, zapisyvaemye  processami,  mogut  perese-
kat'sya.  |to mozhet proizojti iz-za togo, chto processy vedut zapis' na termi-
nal, ispol'zuya neskol'ko vyzovov sistemnoj funkcii write. YAdro mozhet  perek-
lyuchat'  kontekst, poka process vypolnyaetsya v rezhime zadachi, mezhdu posledova-
tel'nymi vyzovami funkcii write, i vnov' zapushchennye processy mogut vesti za-
pis' na terminal, poka pervyj iz processov priostanovlen.  Vyvodimye  dannye
mogut byt' takzhe iskazheny i na terminale, poskol'ku process mozhet priostano-
vit'sya na seredine vypolneniya sistemnoj funkcii write, ozhidaya zaversheniya vy-
voda  na  terminal iz sistemy predydushchej porcii dannyh. YAdro mozhet zapustit'
drugie processy, kotorye veli zapis' na terminal do togo, kak pervyj process
byl povtorno zapushchen. Po etoj prichine, yadro ne garantiruet,  chto  soderzhimoe
bufera  dannyh,  vyvodimoe v rezul'tate vyzova sistemnoj funkcii write, poya-
vitsya na ekrane terminala v nepreryvnom vide.
    Rassmotrim programmu, privedennuyu na Risunke 10.14. Roditel'skij process
sozdaet do 18 porozhdennyh processov; kazhdyj iz porozhdennyh processov zapisy-
vaet stroku (s pomoshch'yu bibliotechnoj funkcii sprintf) v massiv output,  koto-
ryj  vklyuchaet  soobshchenie  i  znachenie schetchika i v moment vypolneniya funkcii
fork, i zatem vhodit v cikl poshagovoj perepisi stroki  v  fajl  standartnogo
vyvoda. Esli standartnym vyvodom yavlyaetsya terminal, terminal'nyj drajver re-
guliruet  potok postupayushchih dannyh. Vyvodimaya stroka imeet bolee 64 simvolov


                                    311

+----------------------------------------------------------------+
| char form[]="eto primer vyvoda stroki iz porozhdennogo processa"|                                                            |
| main()                                                         |
| {                                                              |
|     char output[128];                                          |
|     int i;                                                     |
|                                                                |
|     for (i = 0; i < 18; i++)                                   |
|     {                                                          |
|           switch (fork())                                      |
|           {                                                    |
|           case -1:    /* oshibka --- prevysheno maksimal'noe chis-|
|                          lo processov */                       |
|                exit();                                         |
|                                                                |
|           default:    /* roditel'skij process */               |
|                break;                                          |
|                                                                |
|           case 0:     /* porozhdennyj process */                |
|                /* format vyvoda stroki v peremennoj output */  |
|                sprintf(output,"%%d\n%s%d\n",form,i,form,i);    |
|                for (;;)                                        |
|                       write(1,output,sizeof(output));          |
|           }                                                    |
|     }                                                          |
| }                                                              |
+----------------------------------------------------------------+

      Risunok 10.14. Peredacha dannyh cherez standartnyj vyvod


v dlinu, to est' slishkom velika dlya togo,  chtoby  pomestit'sya  v  simvol'nom
bloke  (dlinoj  64  bajta)  v versii V sistemy. Sledovatel'no, terminal'nomu
drajveru trebuetsya bolee odnogo simvol'nogo bloka dlya kazhdogo vyzova funkcii
write, inache vyvodnoj potok  mozhet  stat'  iskazhennym.  Naprimer,  sleduyushchie
stroki  byli  chast'yu  vyvodnogo  potoka, poluchennogo v rezul'tate vypolneniya
programmy na mashine AT&T 3B20:

  this is a sample output string from child 1
  this is a sample outthis is a sample output string from child 0

    CHtenie dannyh s terminala v kanonicheskom rezhime bolee slozhnaya  operaciya.
V vyzove sistemnoj funkcii read ukazyvaetsya kolichestvo bajt, kotorye process
hochet  schitat', no strokovyj interfejs vypolnyaet chtenie po poluchenii simvola
perevoda karetki, dazhe esli kolichestvo simvolov ne  ukazano.  |to  udobno  s
prakticheskoj  tochki  zreniya,  tak  kak  process  ne v sostoyanii predugadat',
skol'ko simvolov pol'zovatel' vvedet s klaviatury, i, s drugoj  storony,  ne
imeet smysla zhdat', kogda pol'zovatel' vvedet bol'shoe chislo simvolov. Napri-
mer,  pol'zovateli vvodyat komandnye stroki dlya komandnogo processora shell i
ozhidayut otveta shell'a na komandu po poluchenii simvola vozvrata karetki. Pri
etom net nikakoj raznicy, yavlyayutsya li vvedennye stroki  prostymi  komandami,
takimi kak "date" ili "who", ili zhe eto bolee slozhnye posledovatel'nosti ko-
mand, podobnye sleduyushchej:

    pic file* | tbl | eqn | troff -mm -Taps | apsend

    Terminal'nyj  drajver i strokovyj interfejs nichego ne znayut o sintaksise
komandnogo processora shell, i eto pravil'no,  poskol'ku  drugie  programmy,
kotorye  schityvayut informaciyu s terminalov (naprimer, redaktory), imeyut raz-

                                    312

lichnyj sintaksis komand. Poetomu strokovyj interfejs vypolnyaet chtenie po po-
luchenii simvola vozvrata karetki.
    Na Risunke 10.15 pokazan algoritm chteniya s terminala.  Predpolozhim,  chto
terminal  rabotaet v kanonicheskom rezhime; v razdele 10.3.3 budet rassmotrena
rabota v rezhime bez obrabotki. Esli v nastoyashchij moment v lyubom iz simvol'nyh
spiskov dlya hraneniya vvodnoj informacii otsutstvuyut dannye, process,  vypol-

    +------------------------------------------------------------+
    | algoritm terminal_read                                     |
    | {                                                          |
    |    esli (v kanonicheskom simvol'nom spiske otsutstvuyut dan- |
    |     nye)                                                   |
    |    {                                                       |
    |       vypolnit' (poka v spiske dlya nestrukturirovannyh     |
    |        vvodnyh dannyh otsutstvuet informaciya)              |
    |       {                                                    |
    |           esli (terminal otkryt s parametrom "no delay"    |
    |            (bez zaderzhki))                                 |
    |               vozvratit' upravlenie;                       |
    |           esli (terminal v rezhime bez obrabotki s ispol'zo-|
    |            vaniem tajmera i tajmer ne aktiven)             |
    |               predprinyat' dejstviya k aktivizacii tajmera   |
    |                (tablica otvetnyh signalov);                |
    |           priostanovit'sya (do postupleniya dannyh s termina-|
    |            la);                                            |
    |       }                                                    |
    |                                                            |
    |       /* v spiske dlya nestrukturirovannyh vvodnyh dannyh   |
    |          est' informaciya */                                |
    |       esli (terminal v rezhime bez obrabotki)               |
    |           skopirovat' vse dannye iz spiska dlya nestrukturi-|
    |            rovannyh vvodnyh dannyh v kanonicheskij spisok;  |
    |       v protivnom sluchae    /* terminal v kanonicheskom re- |
    |                                zhime */                     |
    |       {                                                    |
    |           vypolnit' (poka v spiske dlya nestrukturirovannyh |
    |            vvodnyh dannyh est' simvoly)                    |
    |           {                                                |
    |               kopirovat' po odnomu simvolu iz spiska dlya   |
    |                nestrukturirovannyh vvodnyh dannyh v kano-  |
    |                nicheskij spisok:                            |
    |                vypolnit' obrabotku simvolov stiraniya i uda-|
    |                leniya;                                      |
    |               esli (simvol - "vozvrat karetki" ili "konec  |
    |                fajla")                                     |
    |                   prervat'sya;    /* vyhod iz cikla */      |
    |           }                                                |
    |       }                                                    |
    |    }                                                       |
    |                                                            |
    |    vypolnit' (poka v kanonicheskom spiske eshche est' simvoly  |
    |     i ne ischerpano kolichestvo simvolov, ukazannoe v vyzove |
    |     funkcii read)                                          |
    |       kopirovat' simvoly iz simvol'nyh blokov kanonicheskogo|
    |        spiska v adresnoe prostranstvo zadachi;              |
    | }                                                          |
    +------------------------------------------------------------+

              Risunok 10.15. Algoritm chteniya s terminala

                                    313



nyayushchij chtenie, priostanavlivaetsya do postupleniya pervoj stroki dannyh. Kogda
dannye  postupayut,  programma  obrabotki  preryvaniya  ot terminala zapuskaet
"programmu obrabotki preryvaniya"  strokovogo  interfejsa,  kotoraya  pomeshchaet
dannye v spisok dlya hraneniya nestrukturirovannyh vvodnyh dannyh dlya peredachi
processam,  osushchestvlyayushchim  chtenie, i v spisok dlya hraneniya vyvodnyh dannyh,
peredavaemyh v kachestve ehosoprovozhdeniya na terminal. Esli vvedennaya  stroka
soderzhit simvol vozvrata karetki, programma obrabotki preryvaniya vozobnovlya-
et vypolnenie vseh priostanovlennyh processov chteniya. Kogda process, osushches-
tvlyayushchij  chtenie, vypolnyaetsya, drajver vybiraet simvoly iz spiska dlya hrane-
niya nestrukturirovannyh vvodnyh dannyh, obrabatyvaet simvoly stiraniya i uda-
leniya i pomeshchaet simvoly v kanonicheskij simvol'nyj spisok. Zatem on kopiruet
stroku simvolov v adresnoe prostranstvo zadachi do simvola  vozvrata  karetki
ili  do  ischerpaniya  chisla  simvolov,  ukazannogo v vyzove sistemnoj funkcii
read, chto vstretitsya ran'she. Odnako, process mozhet obnaruzhit',  chto  dannyh,
radi  kotoryh  on  vozobnovil  svoe vypolnenie, bol'she ne sushchestvuet: drugie
processy schitali dannye s terminala i udalili ih iz spiska dlya  nestrukturi-
rovannyh vvodnyh dannyh do togo, kak pervyj process byl zapushchen vnov'. Takaya
situaciya pohozha na tu, kotoraya imeet mesto, kogda iz kanala schityvayut dannye
neskol'ko processov.
    Obrabotka  simvolov  v napravlenii vvoda i v napravlenii vyvoda asimmet-
richna, chto vidno iz nalichiya dvuh simvol'nyh spiskov dlya vvoda i odnogo - dlya
vyvoda. Strokovyj interfejs vyvodit dannye iz prostranstva zadachi, obrabaty-
vaet ih i pomeshchaet ih v spisok dlya hraneniya vyvodnyh dannyh.  Dlya  simmetrii
sledovalo by imet'
tol'ko  odin spisok dlya vvodnyh dannyh. Odnako, v takom sluchae potrebovalos'
by ispol'zovanie programmy obrabotki preryvanij dlya  interpretacii  simvolov

  +--------------------------------------------------------------+
  | char input[256];                                             |
  |                                                              |
  | main()                                                       |
  | {                                                            |
  |    register int i;                                           |
  |                                                              |
  |    for (i = 0; i < 18; i++)                                  |
  |    {                                                         |
  |       switch (fork())                                        |
  |       {                                                      |
  |       case -1:       /* oshibka */                            |
  |          printf("operaciya fork ne vypolnena iz-za oshibki\n");|
  |          exit();                                             |
  |                                                              |
  |       default:       /* roditel'skij process */              |
  |          break;                                              |
  |                                                              |
  |       case 0:        /* porozhdennyj process */               |
  |          for (;;)                                            |
  |          {                                                   |
  |              read(0,input,256);     /* chtenie stroki */      |
  |              printf("%d chtenie %s\n",i,input);               |
  |          }                                                   |
  |       }                                                      |
  |    }                                                         |
  | }                                                            |
  +--------------------------------------------------------------+

     Risunok 10.16. Konkurenciya za dannye, vvodimye s terminala

                                    314



stiraniya  i  udaleniya, chto sdelalo by proceduru bolee slozhnoj i dlitel'noj i
zapretilo by vozniknovenie drugih preryvanij na vse kriticheskoe  vremya.  Is-
pol'zovanie  dvuh  simvol'nyh spiskov dlya vvoda podrazumevaet, chto programma
obrabotki preryvanij mozhet prosto sbrosit' simvoly v spisok dlya nestrukturi-
rovannyh vvodnyh dannyh i vozobnovit' vypolnenie  processa,  osushchestvlyayushchego
chtenie, kotoryj sobstvenno i voz'met na sebya rabotu po interpretacii vvodnyh
dannyh.  Pri etom programma obrabotki preryvanij nemedlenno pomeshchaet vveden-
nye simvoly v spisok dlya hraneniya vyvodnyh dannyh, tak chto pol'zovatel'  is-
pytyvaet  lish' minimal'nuyu zaderzhku pri prosmotre vvedennyh simvolov na ter-
minale.
    Na Risunke 10.16 privedena programma, v kotoroj roditel'skij process po-
rozhdaet neskol'ko processov, osushchestvlyayushchih  chtenie  iz  fajla  standartnogo
vvoda, konkuriruya za poluchenie dannyh, vvodimyh s terminala. Vvod s termina-
la  obychno osushchestvlyaetsya slishkom medlenno dlya togo, chtoby udovletvorit' vse
processy, vedushchie chtenie, poetomu processy bol'shuyu chast' vremeni nahodyatsya v
priostanovlennom sostoyanii v sootvetstvii s algoritmom terminal_read, ozhidaya
vvoda dannyh. Kogda pol'zovatel' vvodit stroku dannyh,  programma  obrabotki
preryvanij ot terminala vozobnovlyaet vypolnenie vseh processov, vedushchih chte-
nie;  poskol'ku oni byli priostanovleny s odnim i tem zhe urovnem prioriteta,
oni vybirayutsya dlya zapuska s odinakovym urovnem prioriteta. Pol'zovatel'  ne
v  sostoyanii  predugadat', kakoj iz processov vypolnyaetsya i schityvaet stroku
dannyh; uspeshno sozdannyj process pechataet znachenie peremennoj  i  v  moment
ego  sozdaniya.  Vse drugie processy v konce koncov budut zapushcheny, no vpolne
vozmozhno, chto oni ne obnaruzhat vvedennoj informacii v spiskah  dlya  hraneniya
vvodnyh  dannyh  i  ih  vypolnenie snova budet priostanovleno. Vsya procedura
povtoryaetsya dlya kazhdoj vvedennoj stroki; nel'zya dat' garantiyu, chto  ni  odin
iz processov ne zahvatit vse vvedennye dannye.
    Odnovremennomu  chteniyu  s terminala neskol'kimi processami prisushcha neod-
noznachnost', no yadro spravlyaetsya s situaciej  nailuchshim  obrazom.  S  drugoj
storony,  yadro  obyazano  pozvolyat' processam odnovremenno schityvat' dannye s
terminala, inache porozhdennye komandnym processorom shell processy,  chitayushchie
iz standartnogo vvoda, nikogda ne budut rabotat', poskol'ku shell tozhe obra-
shchaetsya k standartnomu vvodu. Koroche govorya, processy dolzhny sinhronizirovat'
svoi obrashcheniya k terminalu na pol'zovatel'skom urovne.
    Kogda pol'zovatel' vvodit simvol "konec fajla" (Ctrl-d v ASCII), stroko-
vyj interfejs peredaet funkcii read vvedennuyu stroku do simvola konca fajla,
no ne vklyuchaya ego. On ne peredaet dannye (kod vozvrata 0) funkcii read, esli
v  simvol'nom spiske vstretilsya tol'ko simvol "konec fajla"; vyzyvayushchij pro-
cess sam raspoznaet, chto obnaruzhen konec fajla i bol'she ne sleduet schityvat'
dannye s terminala. Esli eshche raz obratit'sya k primeram programm po  shell'u,
privedennym  v glave 7, mozhno otmetit', chto cikl raboty shell'a zavershaetsya,
kogda pol'zovatel' nazhimaet : funkciya read vozvrashchaet 0  i  proizvo-
ditsya vyhod iz shell'a.
    V etom razdele rassmotrena rabota terminalov vvoda-vyvoda, kotorye pere-
dayut  dannye  na  mashinu  po odnomu simvolu za odnu operaciyu, v tochnosti kak
pol'zovatel' ih vvodit s klaviatury. Intellektual'nye terminaly  podgotavli-
vayut  svoj  vvodnoj potok na vneshnem ustrojstve, osvobozhdaya central'nyj pro-
cessor dlya drugoj raboty. Struktura drajverov dlya takih  terminalov  pohodit
na strukturu drajverov dlya terminalov vvoda-vyvoda, nesmotrya na to, chto fun-
kcii strokovogo interfejsa razlichayutsya v zavisimosti ot vozmozhnostej vneshnih
ustrojstv.


    10.3.3 Terminal'nyj drajver v rezhime bez obrabotki simvolov

Pol'zovateli ustanavlivayut parametry terminala, takie kak simvoly stira- niya i udaleniya, i izvlekayut znacheniya tekushchih ustanovok s pomoshch'yu sistemnoj 315 funkcii ioctl. Shodnym obrazom oni ustanavlivayut neobhodimost' eho-soprovozh- deniya vvoda dannyh s terminala, zadayut skorost' peredachi informacii v bodah, zapolnyayut ocheredi simvolov vvoda i vyvoda ili vruchnuyu zapuskayut i ostanavli- vayut vyvodnoj potok simvolov. V informacionnoj strukture terminal'nogo draj- vera hranyatsya razlichnye upravlyayushchie ustanovki (sm. [SVID 85], str.281), i strokovyj interfejs poluchaet parametry funkcii ioctl i ustanavlivaet ili schityvaet znacheniya sootvetstvuyushchih polej struktury dannyh. Kogda process us- tanavlivaet znacheniya parametrov terminala, on delaet eto dlya vseh processov, ispol'zuyushchih terminal. Ustanovki terminala ne sbrasyvayutsya avtomaticheski pri vyhode iz processa, sdelavshego izmeneniya v ustanovkah. Processy mogut takzhe perevesti terminal v rezhim bez obrabotki simvolov, v kotorom strokovyj interfejs peredaet simvoly v tochnom sootvetstvii s tem, kak pol'zovatel' vvel ih: obrabotka vvodnogo potoka polnost'yu otsutstvuet. Odnako, yadro dolzhno znat', kogda vypolnit' vyzvannuyu pol'zovatelem sistemnuyu funkciyu read, poskol'ku simvol vozvrata karetki traktuetsya kak obychnyj vve- dennyj simvol. Ono vypolnyaet funkciyu read posle togo, kak s terminala budet vvedeno minimal'noe chislo simvolov ili po prohozhdenii fiksirovannogo prome- zhutka vremeni ot momenta polucheniya s terminala lyubogo nabora simvolov. V poslednem sluchae yadro hronometriruet vvod simvolov s terminala, pomeshchaya za- pisi v tablicu otvetnyh signalov (glava 8). Oba kriteriya (minimal'noe chislo simvolov i fiksirovannyj promezhutok vremeni) zadayutsya v vyzove funkcii ioctl. Kogda sootvetstvuyushchie kriterii udovletvoreny, programma obrabotki preryvanij strokovogo interfejsa vozobnovlyaet vypolnenie vseh priostanovlen- nyh processov. Drajver peresylaet vse simvoly iz spiska dlya hraneniya nest- rukturirovannyh vvodnyh dannyh v kanonicheskij spisok i vypolnyaet zapros pro- cessa na chtenie, sleduya tomu zhe samomu algoritmu, chto i v sluchae raboty v kanonicheskom rezhime. Rezhim bez obrabotki simvolov osobenno vazhen v ekran- no-orientirovannyh prilozheniyah, takih kak ekrannyj redaktor vi, mnogie iz komand kotorogo ne zakanchivayutsya simvolom vozvrata karetki. Naprimer, koman- da dw udalyaet slovo v tekushchej pozicii kursora. Na Risunke 10.17 privedena programma, ispol'zuyushchaya funkciyu ioctl dlya sohraneniya tekushchih ustanovok terminala dlya fajla s deskriptorom 0, chto soot- vetstvuet znacheniyu deskriptora fajla standartnogo vvoda. Funkciya ioctl s ko- mandoj TCGETA prikazyvaet drajveru izvlech' ustanovki i sohranit' ih v strukture s imenem savetty v ad- resnom prostranstve zadachi. |ta komanda chasto ispol'zuetsya dlya togo, chtoby opredelit', yavlyaetsya li fajl terminalom ili net, poskol'ku ona nichego ne iz- menyaet v sisteme: esli ona zavershaetsya neudachno, processy predpolagayut, chto fajl ne yavlyaetsya terminalom. Zdes' zhe, process vtorichno vyzyvaet funkciyu ioctl dlya togo, chtoby perevesti terminal v rezhim bez obrabotki: on otklyuchaet eho-soprovozhdenie vvoda simvolov i gotovitsya k vypolneniyu operacij chteniya s +----------------------------------------------------------------+ | #include | | #include | | struct termio savetty; | | main() | | { | | extern sigcatch(); | | struct termio newtty; | | int nrd; | | char buf[32]; | | signal(SIGINT,sigcatch); | | if (ioctl(0,TCGETA,&savetty) == -1) | | { | | printf("ioctl zavershilas' neudachno: net terminala\n"); | | exit(); | | } | | newtty = savetty; | 316 | newtty.c_lflag &= ~ICANON;/* vyhod iz kanonicheskogo rezhima */| | newtty.c_lflag &= ~ECHO; /* otklyuchenie eho-soprovozhdeniya*/ | | newtty.c_cc[VMIN] = 5; /* minimum 5 simvolov */ | | newtty.c_cc[VTIME] = 100; /* interval 10 sekund */ | | if (ioctl(0,TCSETAF,&newtty) == -1) | | { | | printf("ne mogu perevesti ter-l v rezhim bez obrabotki\n");| | exit(); | | } | | for(;;) | | { | | nrd = read(0,buf,sizeof(buf)); | | buf[nrd] = 0; | | printf("chtenie %d simvolov '%s'\n",nrd,buf); | | } | | } | | sigcatch() | | { | | ioctl(0,TCSETAF,&savetty); | | exit(); | | } | +----------------------------------------------------------------+ Risunok 10.17. Rezhim bez obrabotki - chtenie 5-simvol'nyh blokov +----------------------------------------------------------------+ | #include | | | | main() | | { | | register int i,n; | | int fd; | | char buf[256]; | | | | /* otkrytie terminala tol'ko dlya chteniya s opciej "no delay" */ | | if((fd = open("/dev/tty",O_RDONLY|O_NDELAY)) == -1) | | exit(); | | | | n = 1; | | for(;;) /* vsegda */ | | { | | for(i = 0; i < n; i++) | | ; | | | | if(read(fd,buf,sizeof(buf)) > 0) | | { | | printf("chtenie s nomera %d\n",n); | | n--; | | } | | else | | /* nichego ne prochitano; vozvrat vsledstvie "no delay" */ | | n++; | | } | | } | +----------------------------------------------------------------+ Risunok 10.18. Opros terminala 317 terminala po poluchenii s terminala 5 simvolov, kak minimum, ili po prohozhde- nii 10 sekund s momenta vvoda pervoj porcii simvolov. Kogda process poluchaet signal o preryvanii, on sbrasyvaet pervonachal'nye parametry terminala i za- vershaetsya.

    10.3.4 Opros terminala

Inogda udobno proizvodit' opros ustrojstva, to est' schityvat' s nego dannye, esli oni est', ili prodolzhat' vypolnyat' obychnuyu rabotu - v protivnom sluchae. Programma na Risunke 10.18 illyustriruet etot sluchaj: posle otkrytiya terminala s parametrom "no delay" (bez zaderzhki) processy, vedushchie chtenie s nego, ne priostanovyat svoe vypolnenie v sluchae otsutstviya dannyh, a vernut upravlenie nemedlenno (sm. algoritm terminal_read, Risunok 10.15). |tot me- tod rabotaet takzhe, esli process sledit za mnozhestvom ustrojstv: on mozhet otkryt' kazhdoe ustrojstvo s parametrom "no delay" i oprosit' vseh iz nih, ozhidaya postupleniya informacii s kazhdogo. Odnako, etot metod rastrachivaet vy- chislitel'nye moshchnosti sistemy. V sisteme BSD est' sistemnaya funkciya select, pozvolyayushchaya proizvodit' op- ros ustrojstva. Sintaksis vyzova etoj funkcii: select(nfds,rfds,wfds,efds,timeout) gde nfds - kolichestvo vybiraemyh deskriptorov fajlov, a rfds, wfds i efds ukazyvayut na dvoichnye maski, kotorymi "vybirayut" deskriptory otkrytyh faj- lov. To est', bit 1 << fd (sdvig na 1 razryad vlevo znacheniya deskriptora faj- la) sootvetstvuet ustanovke na tot sluchaj, esli pol'zovatelyu nuzhno vybrat' etot deskriptor fajla. Parametr timeout (tajm-aut) ukazyvaet, na kakoe vremya sleduet priostanovit' vypolnenie funkcii select, ozhidaya postupleniya dannyh, naprimer; esli dannye postupayut dlya lyubyh deskriptorov i tajm-aut ne zakon- chilsya, select vozvrashchaet upravlenie, ukazyvaya v dvoichnyh maskah, kakie desk- riptory byli vybrany. Naprimer, esli pol'zovatel' pozhelal priostanovit'sya do momenta polucheniya dannyh po deskriptoram 0, 1 ili 2, parametr rfds ukazhet na dvoichnuyu masku 7; kogda select vozvratit upravlenie, dvoichnaya maska budet zamenena maskoj, ukazyvayushchej, po kakim iz deskriptorov imeyutsya gotovye dan- nye. Dvoichnaya maska wfds vypolnyaet pohozhuyu funkciyu v otnoshenii zapisi desk- riptorov, a dvoichnaya maska efds ukazyvaet na sushchestvovanie isklyuchitel'nyh uslovij, svyazannyh s konkretnymi deskriptorami, chto byvaet polezno pri rabo- te v seti.

    10.3.5 Naznachenie operatorskogo terminala

Operatorskij terminal - eto terminal, s kotorogo pol'zovatel' registri- ruetsya v sisteme, on upravlyaet processami, zapushchennymi pol'zovatelem s ter- minala. Kogda process otkryvaet terminal, drajver terminala otkryvaet stro- kovyj interfejs. Esli process vozglavlyaet gruppu processov kak rezul'tat vy- polneniya sistemnoj funkcii setpgrp i esli process ne svyazan s odnim iz ope- ratorskih terminalov, strokovyj interfejs delaet otkryvaemyj terminal opera- torskim. On sohranyaet starshij i mladshij nomera ustrojstva dlya fajla termina- la v adresnom prostranstve, vydelennom processu, a nomer gruppy processov, svyazannoj s otkryvaemym processom, v strukture dannyh terminal'nogo drajve- ra. Otkryvaemyj process stanovitsya upravlyayushchim processom, obychno vhodnym (nachal'nym) komandnym processorom, chto my uvidim dalee. Operatorskij terminal igraet vazhnuyu rol' v obrabotke signalov. Kogda pol'zovatel' nazhimaet klavishi "delete" (udaleniya), "break" (preryvaniya), stiraniya ili vyhoda, programma obrabotki preryvanij zagruzhaet strokovyj in- terfejs, kotoryj posylaet sootvetstvuyushchij signal vsem processam v gruppe. 318 Podobno etomu, kogda pol'zovatel' "zavisaet", programma obrabotki preryvanij ot terminala poluchaet informaciyu o "zavisanii" ot apparatury, i strokovyj interfejs posylaet sootvetstvuyushchij signal vsem processam v gruppe. Takim ob- razom, vse processy, zapushchennye s konkretnogo terminala, poluchayut signal o "zavisanii"; reakciej po umolchaniyu dlya bol'shinstva processov budet vyhod iz programmy po poluchenii signala; eto pohozhe na to, kak pri zavershenii raboty pol'zovatelya s terminalom iz sistemy udalyayutsya pobochnye processy. Posle po- sylki signala o "zavisanii" programma obrabotki preryvanij ot terminala raz- ®edinyaet terminal s gruppoj processov, chtoby processy iz etoj gruppy ne mog- li bol'she poluchat' signaly, voznikayushchie na terminale.

    10.3.6 Drajver kosvennogo terminala

Zachastuyu processam neobhodimo prochitat' il zapisat' dannye neposredst- venno na operatorskij terminal, hotya standartnyj vvod i vyvod mogut byt' pe- renaznacheny v drugie fajly. Naprimer, shell mozhet posylat' srochnye soobshcheniya neposredstvenno na terminal, nesmotrya na to, chto ego standartnyj fajl vyvoda i standartnyj fajl oshibok, vozmozhno, perenaznacheny v drugoe mesto. V versiyah sistemy UNIX podderzhivaetsya "kosvennyj" dostup k terminalu cherez fajl ust- rojstva "/dev/tty", v kotorom dlya kazhdogo processa opredelen upravlyayushchij (operatorskij) terminal. Pol'zovateli, proshedshie registraciyu na otdel'nyh terminalah, mogut obrashchat'sya k fajlu "/dev/tty", no oni poluchat dostup k raznym terminalam. Sushchestvuet dva osnovnyh sposoba poiska yadrom operatorskogo terminala po imeni fajla "/dev/tty". Vo-pervyh, yadro mozhet special'no ukazat' nomer ust- rojstva dlya fajla kosvennogo terminala s otdel'noj tochkoj vhoda v tablicu klyuchej ustrojstv posimvol'nogo vvoda-vyvoda. Pri zapuske kosvennogo termina- la drajver etogo terminala poluchaet starshij i mladshij nomera operatorskogo terminala iz adresnogo prostranstva, vydelennogo processu, i zapuskaet draj- ver real'nogo terminala, ispol'zuya dannye tablicy klyuchej ustrojstv posim- vol'nogo vvoda-vyvoda. Vtoroj sposob, obychno ispol'zuemyj dlya poiska opera- torskogo terminala po imeni "/dev/tty", svyazan s proverkoj sootvetstviya starshego nomera ustrojstva nomeru kosvennogo terminala pered vyzovom proce- dury open, opredelyaemoj tipom dannogo drajvera. V sluchae sovpadeniya nomerov osvobozhdaetsya indeks fajla "/dev/tty", vydelyaetsya indeks operatorskomu ter- minalu, tochka vhoda v tablicu fajlov pereustanavlivaetsya tak, chtoby ukazy- vat' na indeks operatorskogo terminala, i vyzyvaetsya procedura open, prinad- lezhashchaya terminal'nomu drajveru. Deskriptor fajla, vozvrashchennyj posle otkry- tiya fajla "/dev/tty", ukazyvaet neposredstvenno na operatorskij terminal i ego drajver.

    10.3.7 Vhod v sistemu

Kak pokazano v glave 7, process nachal'noj zagruzki, imeyushchij nomer 1, vy- polnyaet beskonechnyj cikl chteniya iz fajla "/etc/inittab" instrukcij o tom, chto nuzhno delat', esli zagruzhaemaya sistema opredelena kak "odnopol'zovatel'- skaya" ili "mnogopol'zovatel'skaya". V mnogopol'zovatel'skom rezhime samoj per- voj obyazannost'yu processa nachal'noj zagruzki yavlyaetsya predostavlenie pol'zo- vatelyam vozmozhnosti registrirovat'sya v sisteme s terminalov (Risunok 10.19). On porozhdaet processy, imenuemye getty-processami (ot "get tty" - poluchit' terminal), i sledit za tem, kakoj iz processov otkryvaet kakoj terminal; kazhdyj getty-process ustanavlivaet svoyu gruppu processov, ispol'zuya vyzov sistemnoj funkcii setpgrp, otkryvaet otdel'nuyu terminal'nuyu liniyu i obychno priostanavlivaetsya vo vremya vypolneniya funkcii open do teh por, poka mashina ne poluchit apparatnuyu svyaz' s terminalom. Kogda funkciya open vozvrashchaet up- ravlenie, getty-process ispolnyaet programmu login (registracii v sisteme), kotoraya trebuet ot pol'zovatelej, chtoby oni identificirovali sebya ukazaniem 319 registracionnogo imeni i parolya. Esli pol'zovatel' zaregistrirovalsya uspesh- no, programma login nakonec zapuskaet komandnyj processor shell i pol'zova- tel' pristupaet k rabote. |tot vyzov shell'a imenuetsya "login shell" (regis- tracionnyj shell, registracionnyj interpretator komand). Process, svyazannyj s shell'om, imeet tot zhe identifikator, chto i nachal'nyj getty-process, poe- tomu login shell yavlyaetsya processom, vozglavlyayushchim gruppu processov. Esli pol'zovatel' ne smog uspeshno zaregistrirovat'sya, programma registracii za- vershaetsya cherez opredelennyj promezhutok vremeni, zakryvaya otkrytuyu termi- nal'nuyu liniyu, a process nachal'noj zagruzki porozhdaet dlya etoj linii sleduyu- shchij getty-process. Process nachal'noj zagruzki delaet pauzu do polucheniya sig- nala ob okonchanii porozhdennogo ranee processa. Posle vozobnovleniya raboty on vyyasnyaet, byl li prekrativshij sushchestvovanie process registracionnym shell'om i esli eto tak, porozhdaet eshche odin getty-process, otkryvayushchij terminal, vmesto prekrativshego sushchestvovanie. +------------------------------------------------------------+ | algoritm login /* procedura registracii */ | | { | | ispolnyaetsya getty-process: | | ustanovit' gruppu processov (vyzov funkcii setpgrp); | | otkryt' terminal'nuyu liniyu; /* priostanov do zaversheniya| | otkrytiya */ | | esli (otkrytie zavershilos' uspeshno) | | { | | ispolnit' programmu registracii: | | zaprosit' imya pol'zovatelya; | | otklyuchit' eho-soprovozhdenie, zaprosit' parol'; | | esli (registraciya proshla uspeshno) | | /* najden sootvetstvuyushchij parol' v /etc/passwd */ | | { | | perevesti terminal v kanonicheskij rezhim (ioctl);| | ispolnit' shell; | | } | | v protivnom sluchae | | schitat' kolichestvo popytok registracii, pytat'sya| | zaregistrirovat'sya snova do dostizheniya oprede- | | lennoj tochki; | | } | | } | +------------------------------------------------------------+ Risunok 10.19. Algoritm registracii

    10.4 POTOKI

Shema realizacii drajverov ustrojstv, hotya i otvechaet zalozhennym trebo- vaniyam, stradaet nekotorymi nedostatkami, kotorye s godami stali zametnee. Raznye drajvery imeyut tendenciyu dublirovat' svoi funkcii, v chastnosti draj- very, kotorye realizuyut setevye protokoly i kotorye obychno vklyuchayut v sebya sekciyu upravleniya ustrojstvom i sekciyu protokola. Nesmotrya na to, chto sekciya protokola dolzhna byt' obshchej dlya vseh setevyh ustrojstv, na praktike eto ne tak, poskol'ku yadro ne imeet adekvatnyh mehanizmov dlya obshchego ispol'zovaniya. Naprimer, simvol'nye spiski mogli by byt' poleznymi blagodarya svoim vozmozh- nostyam v buferizacii, no oni trebuyut bol'shih zatrat resursov na posimvol'nuyu obrabotku. Popytki obojti etot mehanizm, chtoby povysit' proizvoditel'nost' sistemy, priveli k narusheniyu modul'nosti podsistemy upravleniya vvodom-vyvo- dom. Otsutstvie obshchnosti na urovne drajverov rasprostranyaetsya vplot' do 320 urovnya komand pol'zovatelya, na kotorom neskol'ko komand mogut vypolnyat' ob- shchie logicheskie funkcii, no razlichnymi sredstvami. Eshche odin nedostatok post- roeniya drajverov zaklyuchaetsya v tom, chto setevye protokoly trebuyut ispol'zo- vaniya sredstva, podobnogo strokovomu interfejsu, v kotorom kazhdaya disciplina realizuet odnu iz chastej protokola i sostavnye chasti soedinyayutsya gibkim ob- razom. Odnako, soedinit' tradicionnye strokovye interfejsy dovol'no trudno. Richi nedavno razrabotal shemu, poluchivshuyu nazvanie "potoki" (streams), dlya povysheniya modul'nosti i gibkosti podsistemy upravleniya vvodom-vyvodom. Nizhesleduyushchee opisanie osnovyvaetsya na ego rabote [Ritchie 84b], hotya reali- zaciya etoj shemy v versii V slegka otlichaetsya. Potok predstavlyaet soboj pol- nodupleksnuyu svyaz' mezhdu processom i drajverom ustrojstva. On sostoit iz so- vokupnosti linejno svyazannyh mezhdu soboj par ocheredej, kazhdaya iz kotoryh (para) vklyuchaet odnu ochered' dlya vvoda i druguyu - dlya vyvoda. Kogda process zapisyvaet dannye v potok, yadro posylaet dannye v ocheredi dlya vyvoda; kogda drajver ustrojstva poluchaet vhodnye dannye, on peresylaet ih v ocheredi dlya vvoda k processu, proizvodyashchemu chtenie. Ocheredi obmenivayutsya soobshcheniyami s sosednimi ocheredyami, ispol'zuya chetko opredelennyj interfejs. Kazhdaya para ocheredej svyazana s odnim iz modulej yadra, takim kak drajver, strokovyj in- terfejs ili protokol, i moduli yadra rabotayut s dannymi, proshedshimi cherez so- otvetstvuyushchie ocheredi. Kazhdaya ochered' predstavlyaet soboj strukturu dannyh, sostoyashchuyu iz sleduyu- shchih elementov: * procedury otkrytiya, vyzyvaemoj vo vremya vypolneniya sistemnoj funkcii open * procedury zakrytiya, vyzyvaemoj vo vremya vypolneniya sistemnoj funkcii close * procedury "vyvoda", vyzyvaemoj dlya peredachi soobshcheniya v ochered' * procedury "obsluzhivaniya", vyzyvaemoj, kogda ochered' zaplanirovana k is- polneniyu * ukazatelya na sleduyushchuyu ochered' v potoke * ukazatelya na spisok soobshchenij, ozhidayushchih obsluzhivaniya * ukazatelya na vnutrennyuyu strukturu dannyh, s pomoshch'yu kotoroj podderzhiva- etsya rabochee sostoyanie ocheredi * flagov, a takzhe verhnej i nizhnej otmetok, ispol'zuemyh dlya upravleniya potokami dannyh, dispetcherizacii i podderzhaniya rabochego sostoyaniya ochere- di. YAdro vydelyaet pary ocheredej, sosedstvuyushchie v pamyati; sledovatel'no, oche- red' legko mozhet otyskat' svoego partnera po pare. +----------+ | Indeks | +-----------------------+ fajla | | |ustrojstva| v +----------+ +------------+-----------+ Zagolovok | Ochered' | Ochered' | potoka | dlya vyvoda | dlya vvoda | +------+-----+-----------+ | ^ v | +------------+-----+-----+ Drajver | Ochered' | Ochered' |------- para ocheredej | dlya vyvoda | dlya vvoda | +------------+-----------+ Risunok 10.20. Potok posle otkrytiya Ustrojstvo s potokovym drajverom yavlyaetsya ustrojstvom posimvol'nogo vvo- 321 da-vyvoda; ono imeet v tablice klyuchej ustrojstv sootvetstvuyushchego tipa speci- al'noe pole, kotoroe ukazyvaet na strukturu inicializacii potoka, soderzhashchuyu adresa procedur, a takzhe verhnyuyu i nizhnyuyu otmetki, upomyanutye vyshe. Kogda yadro vypolnyaet sistemnuyu funkciyu open i obnaruzhivaet, chto fajl ustrojstva imeet tip "special'nyj simvol'nyj", ono proveryaet nalichie novogo polya v tab- lice klyuchej ustrojstv posimvol'nogo vvoda-vyvoda. Esli v tablice otsutstvuet sootvetstvuyushchaya tochka vhoda, to drajver ne yavlyaetsya potokovym, i yadro vypol- nyaet proceduru, obychnuyu dlya ustrojstv posimvol'nogo vvoda-vyvoda. Odnako, pri pervom zhe otkrytii potokovogo drajvera yadro vydelyaet dve pary ocheredej - odnu dlya zagolovka potoka i druguyu dlya drajvera. U vseh otkrytyh potokov mo- dul' zagolovka imeet identichnuyu strukturu: on soderzhit obshchuyu proceduru "vy- voda" i obshchuyu proceduru "obsluzhivaniya" i imeet interfejs s modulyami yadra bo- lee vysokogo urovnya, vypolnyayushchimi funkcii read, write i ioctl. YAdro inicia- liziruet strukturu ocheredej drajvera, naznachaya znacheniya ukazatelyam kazhdoj ocheredi i kopiruya adresa procedur drajvera iz struktury inicializacii draj- vera, i zapuskaet proceduru otkrytiya. Procedura otkrytiya drajvera vypolnyaet obychnuyu inicializaciyu, no pri etom sohranyaet informaciyu, neobhodimuyu dlya povtornogo obrashcheniya k associirovannoj s etoj proceduroj ocheredi. Nakonec, yadro otvodit special'nyj ukazatel' v kopii indeksa v pamyati dlya ssylki na zagolovok potoka (Risunok 10.20). Kogda eshche odin process otkryvaet ustrojst- vo, yadro obnaruzhivaet naznachennyj ranee potok s pomoshch'yu etogo ukazatelya i zapuskaet proceduru otkrytiya dlya vseh modulej potoka. Moduli podderzhivayut svyaz' so svoimi sosedyami po potoku putem peredachi soobshchenij. Soobshchenie sostoit iz spiska zagolovkov blokov, soderzhashchih infor- maciyu soobshcheniya; kazhdyj zagolovok bloka soderzhit ssylku na mesto raspolozhe- niya nachala i konca informacii bloka. Sushchestvuet dva tipa soobshchenij - uprav- lyayushchee i informacionnoe, kotorye opredelyayutsya ukazatelyami tipa v zagolovke soobshcheniya. Upravlyayushchie soobshcheniya mogut byt' rezul'tatom vypolneniya sistemnoj funkcii ioctl ili rezul'tatom osobyh uslovij, takih kak zavisanie terminala, a informacionnye soobshcheniya mogut voznikat' v rezul'tate vypolneniya sistemnoj funkcii write ili v rezul'tate postupleniya dannyh ot ustrojstva. Soobshchenie 1 Soobshchenie 2 Soobshchenie 3 +---------+ +---------+ +---------+ | Blok +--------->| +-------->| | +----+----+ +---------+ +----+----+ v v +---------+ +---------+ | | | | +----+----+ +---------+ v +---------+ | | +---------+ Risunok 10.21. Soobshcheniya v potokah Kogda process proizvodit zapis' v potok, yadro kopiruet dannye iz adres- nogo prostranstva zadachi v bloki soobshcheniya, kotorye vydelyayutsya modulem zago- lovka potoka. Modul' zagolovka potoka zapuskaet proceduru "vyvoda" dlya modu- lya sleduyushchej ocheredi, kotoraya obrabatyvaet soobshchenie, nezamedlitel'no pere- daet ego v sleduyushchuyu ochered' ili stavit v etu zhe ochered' dlya posleduyushchej ob- rabotki. V poslednem sluchae modul' svyazyvaet zagolovki blokov soobshcheniya v spisok s ukazatelyami, formiruya dvunapravlennyj spisok (Risunok 10.21). Zatem on ustanavlivaet v strukture dannyh ocheredi flag, pokazyvaya tem samym, chto imeyutsya dannye dlya obrabotki, i planiruet sobstvennoe obsluzhivanie. Modul' vklyuchaet ochered' v spisok ocheredej, trebuyushchih obsluzhivaniya i zapuskaet meha- nizm dispetcherizacii; planirovshchik (dispetcher) vyzyvaet procedury obsluzhiva- 322 niya dlya kazhdoj ocheredi v spiske. YAdro mozhet planirovat' obsluzhivanie modulej po programmnomu preryvaniyu, podobno tomu, kak ono vyzyvaet funkcii v tablice otvetnyh signalov (sm. glavu 8); obrabotchik programmnyh preryvanij vyzyvaet individual'nye procedury obsluzhivaniya. +----------+ | Indeks | +-----------------------+ fajla | | |ustrojstva| v +----------+ +------------+-----------+ Zagolovok | Ochered' | Ochered' | potoka | dlya vyvoda | dlya vvoda | +------+-----+-----------+ | ^ | | v | +------------+-----------+ Strokovyj | Ochered' | Ochered' | interfejs | dlya vyvoda | dlya vvoda | +------+-----+-----------+ | ^ | | v | +------------+-----+-----+ Terminal'nyj | Ochered' | Ochered' | drajver | dlya vyvoda | dlya vvoda | +------------+-----------+ Risunok 10.22. Prodvizhenie modulya k potoku Processy mogut "prodvigat'" moduli k otkrytomu potoku, ispol'zuya vyzov sistemnoj funkcii ioctl. YAdro pomeshchaet vydvinutyj modul' srazu pod zagolov- kom potoka i svyazyvaet ukazateli ocheredi takim obrazom, chtoby sohranit' dvu- napravlennuyu strukturu spiska. Moduli, raspolozhennye v potoke nizhe, ne bes- pokoyatsya o tom, svyazany li oni s zagolovkom potoka ili zhe s vydvinutym modu- lem: interfejsom vystupaet procedura "vyvoda" sleduyushchej ocheredi v potoke; a sleduyushchaya ochered' prinadlezhit tol'ko chto vydvinutomu modulyu. Naprimer, pro- cess mozhet vydvinut' modul' strokovogo interfejsa v potok terminal'nogo drajvera s cel'yu obrabotki simvolov stiraniya i udaleniya (Risunok 10.22); mo- dul' strokovogo interfejsa ne imeet teh zhe sostavlyayushchih, chto i strokovye in- terfejsy, rassmotrennye v razdele 10.3, no vypolnyaet te zhe funkcii. Bez mo- dulya strokovogo interfejsa terminal'nyj drajver ne obrabotaet vvodnye simvo- ly i oni postupyat v zagolovok potoka v neizmenennom vide. Segment programmy, otkryvayushchij terminal i vydvigayushchij strokovyj interfejs, mozhet vyglyadet' sle- duyushchim obrazom: fd = open("/dev/ttyxy",O_RDWR); ioctl(fd,PUSH,TTYLD); gde PUSH - imya komandy, a TTYLD - chislo, identificiruyushchee modul' strokovogo interfejsa. Ne sushchestvuet ogranicheniya na kolichestvo modulej, mogushchih byt' vydvinutymi v potok. Process mozhet vytalkivat' moduli iz potoka v poryadke postupleniya, "pervym prishel - pervym vyshel", ispol'zuya eshche odin vyzov sis- temnoj funkcii ioctl ioctl(fd,POP,0); Pri tom, chto modul' strokovogo interfejsa vypolnyaet obychnye funkcii po 323 upravleniyu terminalom, sootvetstvuyushchee emu ustrojstvo mozhet byt' sredstvom setevoj svyazi vmesto togo, chtoby obespechivat' svyaz' s odnim-edinstvennym terminalom. Modul' strokovogo interfejsa rabotaet odinakovo, nezavisimo ot togo, kakogo tipa modul' raspolozhen nizhe nego. |tot primer naglyadno demonst- riruet povyshenie gibkosti vsledstvie soedineniya modulej yadra.

    10.4.1 Bolee detal'noe rassmotrenie potokov

Pajk opisyvaet realizaciyu mul'tipleksnyh virtual'nyh terminalov, ispol'- zuyushchuyu potoki (sm. [Pike 84]). Pol'zovatel' vidit neskol'ko virtual'nyh ter- minalov, kazhdyj iz kotoryh zanimaet otdel'noe okno na ekrane fizicheskogo terminala. Hotya v stat'e Pajka rassmatrivaetsya shema dlya intellektual'nyh graficheskih terminalov, ona rabotala by i dlya terminalov vvoda-vyvoda tozhe; kazhdoe okno zanimalo by celyj ekran i pol'zovatel' dlya pereklyucheniya virtu- al'nyh okon nabiral by posledovatel'nost' upravlyayushchih klavish. +---------+ +---------+ +-----------------+ Uroven' | shell 1 | | shell 2 | | mpx | pol'zovatelya +---------+ +---------+ +-----------------+ ---------------+---------------+-----------+---+-------+---- Uroven' yadra | ^ | ^ +--+ ^ | ^ | ^ | | | | | +--+ | | | | | | | | | | | | | | v | v | so- v | v | so- | | termi- +-+++ termi- +-+++ ob-+-+++ +-+++ob- | | nal'naya | | | nal'naya | | | shche-| | | | | |shche- | | liniya +++-+ liniya +++-+ niya+++-+ +++-+niya | | | ^ +-----------+-^------+ ^ | ^ | | | | | +---------+-+--------+ | | | | | | | | | | +-----------+ | | | v | v | v | v +-----------+ v | +-+++-+++ +-+++-+++ +-+++ psevdo- | | | | | | | | | | psevdo- | | | termi- +++-+++-+ +++-+++-+ termi- +-+-+ nal'naya | ^ | ^ | ^ | ^ nal'naya termi- para 1 | +-+ | | +-+ | para 2 nal'nyj +-----+ +-----+ drajver Risunok 10.23. Otobrazhenie virtual'nyh okon na ekrane fizi- cheskogo terminala Na Risunke 10.23 pokazana shema raspolozheniya processov i modulej yadra. Pol'zovatel' vyzyvaet process mpx, kontroliruyushchij rabotu fizicheskogo termi- nala. Mpx chitaet dannye iz linii fizicheskogo terminala i zhdet ob®yavleniya ob upravlyayushchih sobytiyah, takih kak sozdanie novogo okna, pereklyuchenie upravle- niya na drugoe okno, udalenie okna i t.p. Kogda mpx poluchaet uvedomlenie o tom, chto pol'zovatelyu nuzhno sozdat' no- voe okno, on sozdaet process, upravlyayushchij novym oknom, i podderzhivaet svyaz' s nim cherez psevdoterminal. Psevdoterminal - eto programmnoe ustrojstvo, ra- botayushchee po principu pary: vyhodnye dannye, napravlyaemye k odnoj sostavlyayu- shchej pary, posylayutsya na vhod drugoj sostavlyayushchej; vhodnye dannye posylayutsya tomu modulyu potoka, kotoryj raspolozhen vyshe po techeniyu. Dlya togo, chtoby otk- ryt' okno (Risunok 10.24), mpx naznachaet psevdoterminal'nuyu paru i otkryvaet odnu iz sostavlyayushchih pary, napravlyaya potok k nej (otkrytie drajvera sluzhit garantiej togo, chto psevdoterminal'naya para ne byla vybrana ran'she). Mpx vetvitsya i novyj process otkryvaet druguyu sostavlyayushchuyu psevdoterminal'noj 324 +----------------------------------------------------------------+ | /* predpolozhim, chto deskriptory fajlov 0 i 1 uzhe otnosyatsya k | | fizicheskomu terminalu */ | | dlya(;;) /* cikl */ | | { | | vybrat'(vvod); /* zhdat' vvoda iz kakoj-libo linii */ | | prochitat' dannye, vvedennye iz linii; | | pereklyuchit'(liniyu s vvodimymi dannymi) | | { | | esli vybran fizicheskij terminal: /* dannye vvodyatsya po li- | | nii fizicheskogo termi- | | nala */ | | esli(schitana upravlyayushchaya komanda) /* naprimer, sozdanie | | novogo okna */ | | { | | otkryt' svobodnyj psevdoterminal; | | pojti po vetvi novogo processa: | | esli(process roditel'skij) | | { | | vydvinut' interfejs soobshchenij v storonu mpx; | | prodolzhit'; /* vozvrat v cikl "dlya" */ | | } | | /* process-potomok */ | | zakryt' nenuzhnye deskriptory fajlov; | | otkryt' drugoj psevdoterminal iz pary, vybrat' stdin, | | stdout, stderr; | | vydvinut' strokovyj interfejs terminala; | | zapustit' shell; /* podobno virtual'nomu terminalu */| | } | | /* "obychnye" dannye, poyavivshiesya cherez virtual'nyj terminal */ | | demul'tipleksirovat' schityvanie dannyh s fizicheskogo ter-| | minala, snyat' zagolovki i vesti zapis' na sootvetstvuyu- | | shchij psevdoterminal; | | prodolzhit'; /* vozvrat v cikl "dlya" */ | | | | esli vybran logicheskij terminal: /* virtual'nyj terminal | | svyazan s oknom */ | | zakodirovat' zagolovok, ukazyvayushchij naznachenie informacii| | okna; | | perepisat' zagolovok i informaciyu na fizicheskij terminal;| | prodolzhit'; /* vozvrat v cikl "dlya" */ | | } | | } | +----------------------------------------------------------------+ Risunok 10.24. Psevdoprogramma mul'tipleksirovaniya okon pary. Mpx vydvigaet modul' upravleniya soobshcheniyami v psevdoterminal'nyj po- tok, chtoby preobrazovyvat' upravlyayushchie soobshcheniya v informacionnye (ob etom v sleduyushchem paragrafe), a porozhdennyj process pomeshchaet v psevdoterminal'nyj potok modul' strokovogo interfejsa pered zapuskom shell'a. |tot shell teper' vypolnyaetsya na virtual'nom terminale; dlya pol'zovatelya virtual'nyj terminal neotlichim ot fizicheskogo. Process mpx yavlyaetsya mul'tipleksorom, napravlyayushchim vyvod dannyh s virtu- al'nyh terminalov na fizicheskij terminal i demul'tipleksiruyushchim vvod dannyh s fizicheskogo terminala na podhodyashchij virtual'nyj. Mpx zhdet postupleniya dan- nyh po lyuboj iz linij, ispol'zuya sistemnuyu funkciyu select. Kogda dannye pos- tupayut ot fizicheskogo terminala, mpx reshaet vopros, yavlyayutsya li postupivshie 325 dannye upravlyayushchim soobshcheniem, izveshchayushchim o neobhodimosti sozdaniya novogo okna ili udaleniya starogo, ili zhe eto informacionnoe soobshchenie, kotoroe ne- obhodimo razoslat' processam, schityvayushchim informaciyu s virtual'nogo termina- la. V poslednem sluchae dannye imeyut zagolovok, identificiruyushchij tot virtu- al'nyj terminal, k kotoromu oni otnosyatsya; mpx stiraet zagolovok s soobshcheniya i perepisyvaet dannye v sootvetstvuyushchij psevdoterminal'nyj potok. Drajver psevdoterminala otpravlyaet dannye cherez strokovyj interfejs terminala pro- cessam, osushchestvlyayushchim chtenie. Obratnaya procedura imeet mesto, kogda process vedet zapis' na virtual'nyj terminal; mpx prisoedinyaet zagolovok k dannym, informiruya fizicheskij terminal, dlya vyvoda v kakoe iz okon prednaznacheny eti dannye. Esli process vyzyvaet funkciyu ioctl s virtual'nogo terminala, strokovyj interfejs terminala zadaet neobhodimye ustanovki terminala dlya ego virtual'- noj linii; dlya kazhdogo iz virtual'nyh terminalov ustanovki mogut byt' raz- lichnymi. Odnako, na fizicheskij terminal dolzhna byt' poslana i koe-kakaya in- formaciya, zavisyashchaya ot tipa ustrojstva. Modul' upravleniya soobshcheniyami preob- razuet upravlyayushchie soobshcheniya, generiruemye funkciej ioctl, v informacionnye soobshcheniya, prednaznachennye dlya chteniya i zapisi ih processom mpx, i eti soob- shcheniya peredayutsya na fizicheskoe ustrojstvo.

    10.4.2 Analiz potokov

Richi upominaet o tom, chto im byla predprinyata popytka sozdaniya potokov tol'ko s procedurami "vyvoda" ili tol'ko s procedurami obsluzhivaniya. Odnako, procedura obsluzhivaniya neobhodima dlya upravleniya potokami dannyh, tak kak moduli dolzhny inogda stavit' dannye v ochered', esli sosednie moduli na vremya zakryty dlya priema dannyh. Procedura "vyvoda" tak zhe neobhodima, poskol'ku dannye dolzhny inogda dostavlyat'sya v sosednie moduli nezamedlitel'no. Napri- mer, strokovomu interfejsu terminala nuzhno vesti eho-soprovozhdenie vvoda dannyh na terminale v tempe s processom. Sistemnaya funkciya write mogla by zapuskat' proceduru "vyvoda" dlya sleduyushchej ocheredi neposredstvenno, ta, v svoyu ochered', vyzyvala by proceduru "vyvoda" dlya sleduyushchej ocheredi i tak da- lee, ne nuzhdayas' v mehanizme dispetcherizacii. Process priostanovilsya by v sluchae perepolneniya ocheredej dlya vyvoda. Odnako, so storony vvoda moduli ne mogut priostanavlivat'sya, poskol'ku ih vypolnenie vyzyvaetsya programmoj ob- rabotki preryvanij, inache byl by priostanovlen sovershenno bezobidnyj pro- cess. Svyaz' mezhdu modulyami ne dolzhna byt' simmetrichnoj v napravleniyah vvoda i vyvoda, hotya eto i delaet shemu menee izyashchnoj. Takzhe bylo by zhelatel'no realizovat' kazhdyj modul' v vide otdel'nogo processa, no ispol'zovanie bol'shogo kolichestva modulej privelo by k perepol- neniyu tablicy processov. Moduli nadelyayutsya special'nym mehanizmom dispetche- rizacii - programmnym preryvaniem, nezavisimym ot obychnogo planirovshchika pro- cessov. Po etoj prichine moduli ne mogut priostanavlivat' svoe vypolnenie, tak kak oni priostanavlivali by tem samym proizvol'nyj process (tot, kotoryj prervan). Moduli dolzhny hranit' vnutri sebya informaciyu o svoem sostoyanii, chto delaet lezhashchie v ih osnove programmy bolee gromozdkimi, chem esli by pri- ostanovka vypolneniya byla razreshena. V realizacii potokov mozhno vydelit' neskol'ko otklonenij ili nesootvets- tvij: * Uchet resursov processa v potokah zatrudnyaetsya, poskol'ku modulyam neobya- zatel'no vypolnyat'sya v kontekste processa, ispol'zuyushchego potok. Oshibochno predpolagat', chto vse processy odinakovo ispol'zuyut moduli potokov, pos- kol'ku odnim processam mozhet potrebovat'sya ispol'zovanie slozhnyh setevyh protokolov, togda kak drugie mogut ispol'zovat' prostye strokovye inter- fejsy. * Pol'zovateli imeyut vozmozhnost' perevodit' terminal'nyj drajver v rezhim bez obrabotki, v kotorom funkciya read vozvrashchaet upravlenie cherez korot- kij promezhutok vremeni v sluchae otsutstviya dannyh (naprimer, esli 326 newtty.c_cc[VMIN] = 0 na Risunke 10.17). |tu osobennost' slozhno realizo- vat' v potokovoj srede bez podklyucheniya special'noj programmy na urovne zagolovka potoka. * Potoki vystupayut sredstvami linejnoj svyazi i ne mogut pozvolit' proizvo- dit' s legkost'yu mul'tipleksirovanie na urovne yadra. V primere ispol'zo- vaniya okon, rassmotrennom v predydushchem razdele, vypolnyalos' mul'tiplek- sirovanie na urovne pol'zovatel'skogo processa. Nesmotrya na eti nesootvetstviya, s potokami svyazyvayutsya bol'shie nadezhdy v sovershenstvovanii razrabotki modulej drajvera. .te1 10.5 VYVODY Dannaya glava predstavlyaet soboj obzor drajverov ustrojstv v sisteme UNIX. Ustrojstva mogut byt' libo blochnogo, libo simvol'nogo tipa; interfejs mezhdu ustrojstvami i ostal'noj chast'yu yadra opredelyaetsya tipom ustrojstv. In- terfejsom dlya ustrojstv blochnogo tipa vystupaet tablica klyuchej ustrojstv vvoda-vyvoda blokami, sostoyashchaya iz tochek vhoda, sootvetstvuyushchih proceduram otkrytiya i zakrytiya ustrojstv i strategicheskoj procedure. Strategicheskaya procedura upravlyaet peredachej dannyh ot i k ustrojstvu blochnogo tipa. Inter- fejsom dlya ustrojstv simvol'nogo tipa vystupaet tablica klyuchej ustrojstv po- simvol'nogo vvoda-vyvoda, kotoraya sostoit iz tochek vhoda, sootvetstvuyushchih proceduram otkrytiya i zakrytiya ustrojstva, chteniya, zapisi i procedure ioctl. Sistemnaya funkciya ioctl ispol'zuet pri obrashchenii k ustrojstvam simvol'nogo tipa svoj sobstvennyj interfejs, kotoryj pozvolyaet osushchestvlyat' peredachu up- ravlyayushchej informacii mezhdu processami i ustrojstvami. Po poluchenii preryva- niya ot ustrojstva yadro vyzyvaet programmu obrabotki sootvetstvuyushchego prery- vaniya, opirayas' na informaciyu, hranyashchuyusya v tablice vektorov preryvanij, i na parametry, soobshchennye ustrojstvom, ot kotorogo postupilo preryvanie. Diskovye drajvery prevrashchayut nomera logicheskih blokov, ispol'zuemye faj- lovoj sistemoj, v fizicheskie adresa na diske. Blochnyj interfejs daet vozmozh- nost' yadru buferizovat' dannye. Vzaimodejstvie bez obrabotki uskoryaet vvod-vyvod na disk, no ignoriruet bufernyj kesh, uvelichivaya tem samym shansy razrushit' fajlovuyu sistemu. Terminal'nye drajvery osushchestvlyayut neposredstvennoe vzaimodejstvie s pol'zovatelyami. YAdro svyazyvaet s kazhdym terminalom tri simvol'nyh spiska, odin dlya nestrukturirovannogo vvoda s klaviatury, odin dlya vvoda s obrabot- koj simvolov stiraniya, udaleniya i vozvrata karetki i odin dlya vyvoda. Sis- temnaya funkciya ioctl daet processam vozmozhnost' sledit' za tem, kak yadro ob- rabatyvaet vvodimye dannye, perevodya terminal v kanonicheskij rezhim ili usta- navlivaya znacheniya razlichnyh parametrov dlya rezhima bez obrabotki simvolov. Getty-process otkryvaet terminal'nye linii i zhdet svyazi: on formiruet gruppu processov vo glave s registracionnym shell'om, inicializiruet s pomoshch'yu fun- kcii ioctl parametry terminala i obrashchaetsya k pol'zovatelyu s predlozheniem zaregistrirovat'sya. Ustanovlennyj takim obrazom operatorskij terminal posy- laet processam v gruppe signaly v otvet na vozniknovenie takih sobytij, kak "zavisanie" pol'zovatelya ili nazhatie im klavishi preryvaniya. Potoki vystupayut sredstvom povysheniya modul'nosti postroeniya drajverov ustrojstv i protokolov. Potok - eto polnodupleksnaya svyaz' mezhdu processami i drajverami ustrojstv, kotoraya mozhet vklyuchat' v sebya strokovye interfejsy i protokoly dlya promezhutochnoj obrabotki dannyh. Moduli potokov harakterizuyutsya chetko opredelennym vzaimodejstviem i gibkost'yu, pozvolyayushchej ispol'zovat' ih v sochetanii s drugimi modulyami. |ta gibkost' imeet osoboe znachenie dlya sete- vyh protokolov i drajverov. .te1 10.6 UPRAZHNENIYA *1. Predpolozhim, chto v sisteme imeyutsya dva fajla ustrojstv s odnimi i temi zhe starshim i mladshim nomerami, pri tom, chto oba ustrojstva - simvol'no- 327 go tipa. Esli dva processa zhelayut odnovremenno otkryt' fizicheskoe ust- rojstvo, ne budet nikakoj raznicy, otkryvayut li oni odin i tot zhe fajl ustrojstva ili zhe raznye fajly. CHto proizojdet, kogda oni stanut zakry- vat' ustrojstvo ? *2. Vspomnim iz glavy 5, chto sistemnoj funkcii mknod trebuetsya razreshenie superpol'zovatelya na sozdanie novogo special'nogo fajla ustrojstva. Es- li dostup k ustrojstvu upravlyaetsya pravami dostupa k fajlu, pochemu fun- kcii mknod nuzhno razreshenie superpol'zovatelya ? 3. Napishite programmu, kotoraya proveryaet, chto fajlovye sistemy na diske ne perekryvayutsya. |toj programme potrebovalis' by dva argumenta: fajl ust- rojstva, predstavlyayushchij diskovyj tom, i deskriptor fajla, otkuda berut- sya nomera sektorov i ih razmer dlya diska dannogo tipa. Dlya proverki ot- sutstviya perekrytij etoj programme ponadobilas' by informaciya iz super- blokov. Budet li takaya programma vsegda pravil'noj ? 4. Programma mkfs inicializiruet fajlovuyu sistemu na diske putem sozdaniya superbloka, vydeleniya mesta dlya spiska indeksov, vklyucheniya vseh infor- macionnyh blokov v svyazannyj spisok i sozdaniya kornevogo kataloga. Kak by vy napisali programmu mkfs ? Kak izmenitsya eta programma pri nalichii tablicy soderzhimogo toma ? Kakim obrazom sleduet inicializirovat' tab- licu soderzhimogo toma ? 5. Programmy mkfs i fsck (glava 5) yavlyayutsya programmami pol'zovatel'skogo urovnya, a ne chast'yu yadra. Prokommentirujte eto. 6. Predpolozhim, chto programmistu nuzhno razrabotat' bazu dannyh, rabotayushchuyu v srede OS UNIX. Programmy bazy dannyh vypolnyayutsya na pol'zovatel'skom urovne, a ne v sostave yadra. Kak sistema upravleniya bazoj dannyh budet vzaimodejstvovat' s diskom ? Podumajte nad sleduyushchimi voprosami: * Ispol'zovanie standartnogo interfejsa fajlovoj sistemy vmesto nepos- redstvennoj raboty s nestrukturirovannymi dannymi na diske, * Potrebnost' v bystrodejstvii, * Neobhodimost' znat', kogda fakticheski dannye raspolagayutsya na diske, * Razmer bazy dannyh: dolzhna li ona pomeshchat'sya v odnoj fajlovoj siste- me, zanimat' soboj ves' diskovyj tom ili zhe raspolagat'sya na neskol'- kih diskovyh tomah ? 7. YAdro sistemy UNIX po umolchaniyu predpolagaet, chto fajlovaya sistema ras- polagaetsya na ideal'nyh diskah. Odnako, diski mogut soderzhat' oshibki, kotorye delayut neprigodnymi i vyvodyat iz stroya opredelennye sektora, nesmotrya na to, chto ostal'naya chast' diska ostalas' "prigodnoj". Kak diskovomu drajveru (ili intellektual'nomu kontrolleru diska) sleduet uchityvat' nebol'shoe kolichestvo plohih sektorov. Kak eto otrazilos' by na proizvoditel'nosti sistemy ? 8. Pri montirovanii fajlovoj sistemy yadro zapuskaet proceduru otkrytiya dlya dannogo drajvera, no pozzhe osvobozhdaet indeks special'nogo fajla ust- rojstva po zavershenii vypolneniya vyzova sistemnoj funkcii mount. Pri demontirovanii fajlovoj sistemy yadro obrashchaetsya k indeksu special'nogo fajla ustrojstva, zapuskaet proceduru zakrytiya dlya dannogo drajvera i vnov' osvobozhdaet indeks. Sravnite etu posledovatel'nost' operacij nad indeksom, a takzhe obrashchenij k proceduram otkrytiya i zakrytiya drajvera, s posledovatel'nost'yu dejstvij, sovershaemyh pri otkryvanii i zakryvanii ustrojstva blochnogo tipa. Prokommentirujte rezul'taty sravneniya. 9. Vypolnite programmu, privedennuyu na Risunke 10.14, no naprav'te vyvod dannyh v fajl. Sravnite soderzhimoe fajla s soderzhimym vyvodnogo potoka, kogda vyvod idet na terminal. Vam pridetsya prervat' processy, chtoby os- tanovit' ih; tol'ko prezhde pust' oni poluchat dostatochno bol'shoe koli- chestvo dannyh. CHto proizojdet, esli vyzov funkcii write v programme za- menit' na printf(output); 10. CHto proizojdet, esli pol'zovatel' popytaetsya vypolnit' redaktirovanie teksta na fone programmy: ed file & Obosnujte otvet. 328 11. K fajlam terminalov obychno ustanavlivayutsya sleduyushchie prava dostupa crw--w--w- 2 mjb lus 33,11 Oct 25 20:27 tty61 pri vhode pol'zovatelya v sistemu. To est', chtenie i zapis' razreshayutsya pol'zovatelyu s imenem "mjb", a ostal'nym pol'zovatelyam razreshena tol'ko zapis'. Pochemu ? 12. Predpolozhim, chto vam izvestno imya fajla terminala vashego tovarishcha. Na- pishite programmu zapisi soobshchenij s vashego terminala na terminal vashego tovarishcha. Kakaya eshche informaciya vam nuzhna, chtoby zakodirovat' priemlemoe vosproizvedenie obychnoj komandy write ? 13. Vypolnite komandu stty: esli parametry ne ukazany, ona vybiraet znache- niya ustanovok terminala i soobshchaet ih pol'zovatelyu. V protivnom sluchae pol'zovatel' mozhet v interaktivnom rezhime sdelat' razlichnye ustanovki sam. 14. Napishite elementarnyj strokovyj interfejs, zapisyvayushchij identifikator mashiny v nachale kazhdoj stroki vyvodnogo potoka. 15. V kanonicheskom rezhime pol'zovatel' mozhet na vremya priostanovit' vyvod dannyh na terminal, nazhav posledovatel'nost' klavish , i prodol- zhit' vyvod, nazhav . Kak v standartnom strokovom interfejse rea- lizuetsya eta osobennost' ? *16. Process nachal'noj zagruzki porozhdaet getty-process dlya kazhdoj termi- nal'noj linii v sisteme. CHto proizoshlo by, esli by dlya odnogo i togo zhe terminala sushchestvovali by odnovremenno dva getty-processa, ozhidayushchie registracii pol'zovatelya ? Mozhet li yadro pomeshat' etomu ? 17. Pust' komandnyj processor shell realizovan takim obrazom, chto on "igno- riruet" konec fajla i prodolzhaet schityvat' dannye iz standartnogo vvo- da. CHto proizoshlo by, esli by pol'zovatel' (v registracionnom shell'e) ugadal konec fajla i prodolzhil vvod s klaviatury ? *18. Predpolozhim, chto process schityvaet dannye s operatorskogo terminala, no ignoriruet ili ulavlivaet signaly o "zavisanii". CHto proizojdet, kogda process prodolzhit schityvat' dannye s operatorskogo terminala posle za- visaniya ? 19. Programma getty-processa neset otvetstvennost' za otkrytie terminal'noj linii, a programma login - za proverku registracionnyh imen i parolej. Kakie preimushchestva v tom, chto eti funkcii vypolnyayutsya otdel'nymi prog- rammami ? 20. Rassmotrim dva metoda realizacii drajvera kosvennogo terminala ("/dev /tty"), opisannye v razdele 10.3.6. Kakie razlichiya mezhdu nimi chuvstvuet pol'zovatel' ? (Sovet: podumajte o sistemnyh funkciyah stat i fstat). 21. Razrabotajte metod planirovaniya vypolneniya modulej potoka, v sootvetst- vii s kotorym yadro imeet v svoem sostave special'nyj process, vypolnyayu- shchij procedury obsluzhivaniya modulej togda, kogda vypolnenie etih proce- dur zaplanirovano. *22. Razrabotajte shemu postroeniya virtual'nyh terminalov (okon) s ispol'zo- vaniem tradicionnyh (ne potokovyh) drajverov. *23. Razrabotajte metod realizacii virtual'nyh terminalov s ispol'zovaniem potokov, v kotorom mul'tipleksirovaniem vvoda-vyvoda mezhdu virtual'nym i fizicheskim terminalami zanimalsya by odin iz modulej yadra, a ne pol'- zovatel'skij process. Opishite mehanizm soedineniya potokov so svertkoj i razvertkoj. CHto luchshe: vklyuchit' modul', osushchestvlyayushchij mul'tipleksiro- vanie, v sostav yadra ili postroit' ego kak pol'zovatel'skij process ? 24. Komanda ps soobshchaet interesnuyu informaciyu ob aktivnosti processov v ra- botayushchej sisteme. V tradicionnyh realizaciyah ps schityvaet informaciyu iz tablicy processov, pryamo iz pamyati yadra. Takoj metod ne sovsem udoben v srede razrabotki, kogda razmer zapisej tablicy processov menyaetsya i ko- mande ps stanovitsya nelegko obnaruzhit' v tablice sootvetstvuyushchie polya. Razrabotajte drajver, nechuvstvitel'nyj k izmeneniyam sredy. 329

Last-modified: Thu, 12 Feb 1998 07:20:28 GMT
Ocenite etot tekst: