Windows NT 4



Microsoft Windows NT 4.0


Cu cateva luni in urma Microsoft a distribuit al doilea beta a unei noi versiuni a celui mai apreciat sistem de operare al sau, Windows NT. Noua versiune se va numi Windows NT 4.0 si va combina interfata frumoasa, flexibila si usor de utilizat specifica Windows 95 cu stabilitatea, puterea si viteza cu care am fost obisnuiti in vechile versiuni de Windows NT. Window NT 4.0 este cu mult mai mult decat o simpla aranjare cosmetica a codului, versiunea aducand o serie de facilitati suplimentare, indelung asteptate de catre utilizatorii de Windows.



Inainte de a intra in subiectul propriu-zis, si anume prezentarea noii versiuni, sa precizam inca o data care este viziunea Microsoft asupra rolului sistemelor sale de operare. Cele trei sisteme principale de la Microsoft sunt Windows, Windows NT Workstation si Windows NT Server. Microsoft a avut ambitia sa dezvolte un set de API-uri comune pentru toate aceste trei sisteme de operare, in asa fel incat sa putem scrie o aplicatie o singura data si sa o putem rula pe oricare dintre aceste sisteme de operare. Telul a fost cu atat mai greu de atins cu cat Windows NT ruleaza atat pe procesoare Intel cat si pe procesoare RISC precum procesoarele MIPS, Alpha sau PowerPC.

Dincolo de aceste API-uri comune, intre cele trei sisteme de operare exista diferente majore, mai ales in ceea ce priveste implementarea interna a acestor API-uri. Windows 95 se bazeaza pe un nucleu propriu in timp ce Windows NT Server si Windows NT Workstation au la baza un alt nucleu de sistem de operare. Diferentele intre ultimele doua sisteme de operare sunt mai ales in zona de facilitati cu care vine sistemul in mod nativ si in zona de parametrii de configurare impliciti ai sistemului. Pe moment, nucleul Windows 95 este mai putin stabil si flexibil dar Microsoft promite pentru anul 1999 trecerea intregii familii pe nucleul NT.

Inca in acest an, Microsoft spera sa lanseze versiunea finala pentru Windows NT 4.0 Server si Workstation si o versiune actualizata OEM de Windows 95 care sa contina printre altele Internet Explorer 3.0. Spre sfarsitul lui 96 va fi lansat si Internet Add-on pentru Windows 95 si Windows NT (numele de cod al acestui produs este acum Nashville) care va fi in principal o integrare intre shell si browser. In fine, in anul 1997 va fi lansat Cairo ca un continuator al lui Windows NT si Memphis ca un continuator a lui Windows 95. De altfel, o parte dintre tehnologiile preconizate pentru Cairo au fost introduse in avans in Windows NT 4.0, de exemplu Distributed COM (vezi ilustratia "Urmatorii pasi in dezvoltarea sistemelor Windows" din pagina urmaroare).

In ceea ce priveste Internetul, Microsoft are de data aceasta o viziune foarte clara: in prezent avem aplicatii standalone si pagini Web statice. In viitor, va fi dezvoltata o tehnologie care sa ne permita sa cream obiecte comune celor doua abordari facandu-le pe acestea sa poata comunica intre ele. Primul pas este desigur tehnologia ActiveX care ne permite crearea de obiecte (controale OLE) care pot fi folosite atat in dialogurile aplicatiilor standalone cat si in paginile Web.

Ce mai e nou

Principalele noi trasaturi in Windows NT 4.0 sunt urmatoarele: s-au executat modificari asupra shell-ului, s-au imbunatatit mecanismele de listare, s-a marit performanta sistemului grafic, s-au modificat unele API-uri si unele mecanisme necesare driverelor.

Unul dintre principalele scopuri declarate ale proiectantilor noii versiuni a fost acela de a imbunatati performantele sistemului. Pentru aceasta, s-a mers pana la unele restructurari chiar in interiorul nucleului Windows NT. In plus, s-a ajuns la o compatibilitate foarte buna intre API-ul Windows 95 si API-ul Windows NT. Desigur, shell-ul implementat in Windows NT este superior celui din Windows 95 prin faptul ca are suport complet pentru Unicode si toate celelalte trasaturi specifice Windows NT care lipsesc din Windows 95. Printre acestea, enumeram extensiile proprietatilor fisierelor de tip .ink, suport imbunatatit pentru variabilele sistem, profiluri pe grupuri de masini, interfata pentru comprimarea fisierelor, securitate suplimentara pentru cosurile de gunoi (Recycle Bin), un convertor de fonturi Type 1, si un manager extins de procese care permite o manipulare suplimentara in cazul aplicatiilor care nu isi creaza propriile ferestre.

In ceea ce priveste robustetea si performanta noului shell, acestea vin din extensii precum o utilizare mult mai intensa a firelor de executie, un suport mai bun pentru oprirea aplicatiilor care s-au agatat. Microsoft anunta ca au fost eliminate multe scame din shell-ul Windows 95 si zone de memorie uitate alocate au fost eliberate.

In ceea ce priveste schimbarile legate de mecanismele de listare, aceste sunt legate in primul rand de faptul ca a fost introdusa noua interfata de tip Windows 95. In noul Windows NT directoarele de imprimante se pot partaja intre calculatoare permitandu-se astfel administrarea de la distanta a imprimantelor. Se poate merge chiar pana la instalarea de la distanta a unui driver pe un calculator cu o arhitectura diferita fata de calculatorul de pe care se face instalarea. In plus, Windows NT 4.0 adauga o interfata utilizator comuna tuturor driverelor de imprimanta usurand astfel sarcina proiectantilor de drivere si utilizarea driverelor in acelasi timp. In fine, pentru metafisierele extinse din Windows prelucrarile necesare imprimarii se pot executa la distanta, pe calculatorul pe care este instalata imprimanta.

In ceea ce priveste sistemul grafic, schimbarile se refera in primul rand la noile drivere care au fost introduse in sistem pentru WD ThinkPad, Matrox, Millennium, Trident, Number 9 Imagine, Cirrus. In plus, programul SETUP al Windows NT 4.0 tine acum cont si de eventualele drivere de la terti prezente in timpul instalarii. In fine, a fost introdus un nou API: DirectDraw 2.0 si suport pentru schimbarea dinamica a rezolutiei ecranului (fara repornirea sistemului). In acelasi timp a fost extinsa si implementarea de OpenGL existenta in Windows NT pentru conformanta cu standardul OpenGL 1.1. Noua implementare ruleaza complet in spatiul utilizator si exista surse comune pentru implementarea de Windows 95 si Windows NT.

La nivelul API-urilor, modificarile au dus in primul rand la faptul ca noul API Windows NT este un superset al API-ului Windows 95 (au fost implementate toate functiile specifice Windows 95). In plus, a fost adaugat suport pentru aplicatiile foarte mari in ceea ce priveste firele usoare de executie (lightweight threads sau fibers), si cateva apeluri noi precum: SwitchToThread, SignalObjectAndWait, QuequeUserApc, afinitate la procesor bazata pe proces si timere dupa care se poate astepta.

In zona de drivere, s-au extins driverele pentru CD-uri, SCSI si Enhanced IDE, a aparut inceputul unui suport Plug and Play (doar extendere de bus Hal). Sportul complet pentru Plug and play a fost anuntat pentru inceputul lui 97.

Alte extensii ale Windows NT Workstation includ API-ul de telefonie, API-ul de criptografie, Windows Messaging Subsystem (servicii de posta Microsoft si Internet), suport pentru profiluri hardware la pornirea sistemului, care permit startarea a diverse configuratii de rezolutii video, servicii si dispozitive instalate. Pe platformele RISC, a aparut un emulator 486 care permite rularea aplicatiilor de 16 biti care au nevoie de modul 386 extins sa ruleze pe masini RISC.

In ceea ce priveste Windows NT Server, acesta ofera in plus serverul de informatii Internet (IIS), PPTP (Point to point tunneling protocol), un router multiprotocol (TCP/IP, AppleTalk si IPX/SPX), performanta superioara, integrare intre DNS (Domain Name Server) si WINS, serviciul RPL care permite statiilor Windows 95 fara disc sa booteze de pe serverul NT, extensii ale servicii lor de acces la distanta (RAS). In plus, au fost introdusi o serie de vrajitori (wizzards) administrativi care trebuie sa ajute la operatiile mai des executate, precum ar fi: Add User Accouts Wizzard, Group Management Wzzard, Managing File and Folder Access Wizzard, Add Printer Wizzard, Add/Remove Programs Wizzard, Install new Modem Wizzard, Network Client Administrator Wizzard, Licence Wizzard.

Schimbari arhitecturale

In vechile versiuni de nucleu Windows NT, inclusiv 3.51, subsistemul Win32 rula in mod utilizator, cu alte cuvinte in afara spatiului nucleului propriu-zis. Ratiunea acestui mod de lucru era aceea ca sistemul era mult mai stabil datorita faptului ca driverele de dispozitive grafice, aflate in interiorul subsistemului Win32, rulau in mod utilizator. Aceste drivere nu erau in general dezvoltate de Microsoft ci de parteneri terti si puteau crea probleme in cazul in care contineau erori. (vezi figura "Detalii ale vechiului Subsistem Win32').

Din pacate, acesta arhitectura a dus la costuri mari ale apelurilor catre modulele USER si GDI, la o implementare complexa de sistem cache si batch pentru executia acestor apeluri in interiorul sistemului, consum mare de resurse, greutati suplimentare la intretinere si depanare, scaderi de performanta si, in sfarsit, dificultate crescuta la implementarea trasaturilor specifice Windows 95.

La constructia versiunii 4.0, proiectantii au luat hotararea sa mute modulele USER si GDI in executivul NT sub forma de drivere incarcate dinamic. Facilitatile expuse de executiv catre aceste module sunt deci facilitatile expuse de catre executiv in mod normal catre un driver de dispozitiv sau catre un sistem de fisiere. Se evita astfel accesul direct al modulelor USER si GDI la structurile de date interne ale executivului, acest acces facandu-se prin interfete bine definite (vezi figura "Detalii ale noii arhitecturi Win32').

Microsoft sustine ca acesta schimbare nu va afecta stabilitatea sau modularitatea sistemului desi alte pareri sustin contrariul. Cert este ca imbunatatirile de performanta grafica sunt vizibile in Windows NT 4.0. In noua arhitectura, aplicatiile nu pot accesa sau corupe datele interne ale subsistemului Win32, erorile in subsistemul Win32 (drivere) pot fi controlate si fixate in acelasi mod ca si erorile din executiv sau sistemul de fisiere, iar in timpul rularii aplicatiilor se intampla mult mai putine schimbari de context procesor ceea ce duce la o scalabilitate superioara a masinilor multiprocesor simetrice.

Arhitectura de retea

In Windows NT 4.0 Microsoft a anuntat numeroase extensii in zonele de internetworking, acces la distanta, TAPI, NDIS 4.0, Windows Sockets, DNS si securitate. Sa vedem mai detaliat cateva dintre aceste extensii.

In serverul Windows NT 4.0 rutarea a fost integrata prin introducerea unui suport multiprotocol. Acest suport lucreaza cu RIP/IP, RIP/IPX si RTMP/Appletalk. Suportul multiprotocol permite extensii prin introducerea de drivere specifice unor noi medii de transfer sau protocoale.

NDIS 4.0 a fost si el extins. Principalele trasaturi nou adaugate sunt optimizarea cailor de transmitere si receptie prin transmiterea/primirea de mai multe pachete cu un singur apel API, interfete pentru suportul unor medii aditionale, scalabilitate de multiprocesor pentru driverele miniport, detectia automata a cartelelor de retea PCI si EISA ale caror drivere sunt in biblioteca de drivere a sistemului.

Noua versiune de Windows NT va implementa deasemenea API-ul Windows Sockets 2.0. Aceasta noua versiune de Windows Sockets va contine o independenta fata de transport (TC/IP, IPX/SPX, Appletalk), o integrare superiara cu Win32 si servicii superioare pentru multimedia. Extensiile de performanta ale Windows Sockets 2.0 sunt cele care permit transmisia unui fisier intreg in Internet (se elimina astfel tranzitiile multiple intre nucleu si aplicatie in cazul unor tranzactii lungi Internet) si modificari aduse apelului AcceptEx care reduc numarul de operatii necesare pentru acceptarea unei conexiuni Internet.

In noua sa versiune, Windows NT devine o platforma care ofera servicii multiple, printre care servicii ale retelei Windows, servicii de informatii Internet (IIS ruleaza mult mai performant sub Windows NT 4.0 si intreaga sa administratie a fost mutata sub forma de pagini Web), servicii pentru retele NetWare (server de fisiere, listare, directory management), servicii pentru Macintosh (server de fisiere, listare), servicii NFS (necesita achizitionarea unor produse de la terti).

In ceea ce priveste serviciile specifice retelelor Windows, Microsoft anunta ca performanta transferurilor este mult imbunatatita, in special in cazul mediilor de 100Mb. Se pot accesa servere de oriunde din Internet pe baza adresei de Internet (data de un server DNS). De altfel serviciile DNS si WINS sunt concepute pentru a lucra impreuna si a isi rezolva problemele reciproc. In plus, Microsoft a anuntat extensii pentru integrarea statiilor Windows 95 cu serverele NT in ceea ce priveste performanta operatiilor client-server si a listarii pe imprimante NT.

Calculatoarele Macintosh conectate in retele Windows NT pot beneficia de serviciile serverelor NT 4.0 fara nici un efort special. Serviciile de fisiere si imprimare sunt disponibile direct prin software-ul standard Appleshare iar conturile Macintosh sunt conturi standard Windows NT. Sistemul de fisiere NTFS, cu spatii de nume multiple, poate memora nume de fisiere Macintosh iar iconurile aplicatiilor create cu un PC sunt afisate corect datorita extensiei de asociere de tipuri care se poate instala pe Macintosh. In fine, calculatoarele Macintosh pot tipari fisiere de orice fel, inclusiv Postscript la orice imprimanta conectata la Windows NT.

Viitoarele domenii de interes pentru Microsoft in zona retelelor vor fi standardele de transmisie in retea pentru multimedia (ATM, RSVP, RTP), cresterea usurintei de configurare, integrare superioara cu Internetul, cresterea performantei si a scalabilitatii.

COM Distribuit

Poate ca acest nume vi se pare necunoscut, dar el nu este in fapt decat o redenumire pentru vechiul tel Microsoft prevazut pentru Cairo si anume Network OLE. In fapt, cei dintre dumneavoastra care stiu ce este si cum functioneaza COM (Component Object Model) stiu deja si cum va functiona viitorul DCOM: este un COM cu reteaua activata.

Actualele utilitare de constructie a aplicatiilor distribite sunt extrem de greu de utilizat si destul de limitate. RPC necesita cunostinte foarte multe despre retele si este suportat de putine utilitare de dezvoltare. Alternativa HTTP/CGI este o comunicatie intr-o singura directie, foarte greu de depanat. In plus, un OLE transpus in retea ar avea avantajul ca permite pastrarea cunostentelor si aplicatiilor deja existente.

DCOM va permite o comunicatie in doua directii, simetrica si o performanta acceptabila. In plus, scalabilitatea va fi mult mai buna. Toate aplicatiile existente, scrise in COM vor putea fi portate fara nici o modificare spre COM distribuit. DCOM va fi optimizat in principal pentru protocoale interactive (mult mai eficiente, mai ales peste UDP), definirea usoara de API-uri de obiecte care pot fi extinse, integrare cu tehnologia ActiveX, trasaturi de securitate elaborate.

Microsoft, foarte mandru de tehnologiile OLE in general si de COM si DCOM in special face un efort sustinut de portare a acestei tehnologii pe alte platforme. Astfel, firma a facut un contract cu Software AG pentru a porta DCOM pe diverse platforme Unix. Digital Equipment Corporation lucreaza si el la integrarea DCOM cu CORBA/ObjectBroker si introducerea infrastructurii DCE pe acelasi platforme Unix. Primele rezultate ale portarilor se vor vedea la sfarsitul anului 1996. In plus, Microsoft face eforturi sa integreze COM cu clasele de obiecte create cu ajutorul limbajului Java in noua sa masina virtuala Java (care va fi disponibila impreuna cu Visual J++).

Microsoft si Internetul

Microsoft, chiar daca putin mai tarziu decat ar fi trebuit, a realizat in sfarsit ca PC-urile impreuna cu Internetul vor reprezenta principala atractie in viitor. De aceea in interiorul firmei au fost lansate cateva proiecte de prima urgenta care sa duca la reducerea decalajului. Aceste proiecte intra in doua mari grupuri: tehnologia de navigare si tehnologia de server de informatii.

Microsoft spune ca strategia sa Internet se poate rezuma astfel: imbratiseaza, extinde, adauga valoare. A imbratisa inseamna la Microsoft preluarea standardelor de succes in Internet si integrarea acestora in produsele de baza. Extinderea inseamna imbunatatirea protocoalelor, standardelor si produselor pentru satisfacerea superioara a clientilor. In sfarsit, adaugarea de valoare inseamna impunerea noilor idei inapoi in Internet pentru a oferi o functionalitate superioara intr-un mod deschis.

Intrebarea de baza pe care si-a pus-o Microsoft este aceea daca aplicatiile standalone, specifice PC-urilor trebuie sa fie pentru totdeauna despartite de paginile Web statice specifice Internetului. Amandoua aceste solutii ofera interfete grafice, componente software, aplicatii client-server, multimedia, 3D si conferinte interactive. De ce nu ar putea fi unificate aceste doua abordari? De ce n-ar putea fi create aplicatii care sa preia ce este mai bun din Web si PC pentru a crea aplicatii interactive distribuite si comunicatii interactive multimedia intre indivizi? In aceasta situatie, Microsoft a decis sa creeze o strategie care sa duca la integrarea produselor din Microsoft BackOffice cu Web-ul.

Impreuna cu Windows NT 4.0 beta 2 vine integrat Internet Explorer 2.0, navigatorul gratuit construit de Microsoft ca raspuns la raspandirea extraordinara a lui Nescape Navigator. Probabil ca in produsul final va fi integrat deja Internet Explorer 3.0 care contine tehnologia ActiveX si suport pentru appleturi Java. Internet Explorer 3.0 este disponibil deja in versiune beta 2. Principala trasatura pe care Internet Explorer o opune concurentului sau de la Netscape este suportul pentru tehnologia ActiveX. Aceasta noua tehnologie mult laudata de Microsoft are urmatoarele trasaturi: este independenta de limbaj, ruleaza pe platforme multiple, este rapida, compatibila cu controalele OLE, appleturile Java pot fi vazute automat ca si controale ActiveX, se poate utiliza in pagini Web sau in aplicatii standalone, este suportata de foarte multe utilitare de dezvoltare (toate care includ suport pentru OCX).

Noua tehnologie suporta desigur script-urile pentru minimizarea traficului intre client si server. In principal, ActiveX suporta VBScript si JavaScript dar exista si suport pentru dezvoltarea unor noi limbaje de catre terti. Suportul multimedia in ActiveX este foarte dezvoltat, incluzand Direct3D (grafica de mare performanta, construita direct pe API-ul DirectX), ActiveVRML pentru crearea de lumi virtuale si ActiveX Movie pentru aplicatii sofisticate care necesita video sau audio.

Cel de-al doilea punct de interes la Microsoft este serverul de informatii pentru Internet (IIS), care este in esenta un server Web. Serverul vine integrat in Windows NT 4.0 Server si contine urmatoarele componente: servicii FTP, Gopher, HTTP, documentatii multiple on-line, suport pentru standarde industriale de extensie precum CGI, ISAPI (Information Server API), interfata de conectare la baze de date (Internet Database Connector), aplicatii de administrare.

Serviciile Web contin trasaturi excelente, precum ar fi servere virtuale (serverul poate fi vazut sub mai multe nume), parolele sunt transmise criptat, exista un API (ISAPI) care ofera o cale usoara de extindere a functionalitatii serverului, conexiune cu dazele de date care permite incarcarea informatiilor dintr-o baza de date in paginile Web si SSL care ofera posibilitati de comunicare criptata. Cu serverul IIS se poate limita traficul in retea, se poate controla multimea clientilor care au acces la server, se pot crea fisiere de logare a traficului (vezi figura "Arhitectura serverului de informatii Internet').

Interfata ISAPI permite crearea de extensii ale serverului Web intr-un mod standard. Aceste extensii beneficiaza de o perfomanta ridicata ruland chiar in interiorul procesului si isi pastreaza starea de la o cerere la alta. Cu ajutorul aplicatiilor ActiveX se pot crea machete, se pot procesa informatii sau se poate genera dinamic continutul unei pagini. Cu ajutorul filtrelor ActiveX se pot monitoriza cererile, se pot genera statistici, se poate extinde mecanismul de autentificare, se pot executa translatari ale informatiilor.

Conectorul de baze de date ofera integrare intre serverul Web si serverul SQL sau alta sursa de date ODBC. Acest conector este de fapt o extensie ISAPI ceea ce il face foarte rapid. Configurarea este foarte usoara si nu necesita programare. Se pot executa cereri dinamice si statice complexe sau actualizari si se pot apela proceduri memorate in baza de date. In fine, conectorul vine in mod standard cu ODBC 2.5 si driverul pentru SQL Server. Modul in care gandeste Microsoft extinderea BackOffice pentru suportul Internet este prezentat in figura alaturata.

Administrare

Principalele teluri ale noului sistem de administrare al Windows NT 4.0 sunt: o administrare mai usoara a sistemului pentru cei care nu sunt obisnuiti cu sistemul si o administrare usoara a retelelor eterogene de Windows NT si Windows 95.

In primul rand Microsoft a construit o multime de vrajitori (pe care i-am enumerat deja) care sa ajute la executia operatiilor celor mai comune pentru un administrator sau utilizator. In al doilea rand, au aparut noi utilitare corespunzatoare noilor facilitati aflate in sistem. A aparut astfel un monitor de retea, un administrator de DNS, un editor de politica a sistemului, utilitare de administrarea a Windows NT de pe un sistem Windows 95, un administrator pentru configurarea DCOM.

In fine, managementul domeniilor si utilizatorilor este mult imbunatatit pentru a putea controla mai bine drepturile si preferintele fiecarui utilizator conectat la un sistem NT.

Performanta

Microsoft anunta ca noul sau server si-a imbunatatit mult performantele generale. Performantele serverului de fisiere par sa fi crescut cu peste 100% datorita redirectorului modificat, schimbarilor din SMP si din serverul de fisiere propriu-zis. Performanta se obtine mai ales in retele de 100 MB/s pentru care a fost optimizat Windows NT 4.0. In ceea ce priveste serverul de aplicatii, acesta si-a imbunatatit scalabilitatea, a definit noi API-uri pentru aplicatiile sofisticate precum afinitatea soft (la un anumit procesor), dezactivarea cresterii dinamice de prioritate (dynamic priority boosting), crearea unei operatii atomice de semnalizare si asteptare sau atasarea conditionala a unei sectiuni critice.

Microsoft anunta ca serverul sau SQL ruleaza sub Windows NT mult mai repede acum si bate un server Oracle ruland sub UnixWare sau Solaris ca sa nu mai vorbim de Sybase sau Oracle pentru NT. Ultimele doua raman in urma, dupa spusele lui Microsoft, datorita unei proaste implementari vis-a-vis de facilitatile sistemului. In ceea ce priveste IIS, Microsoft afirma ca acesta merge de 3-4 ori mai repede decat competitorul sau Netscape NetSite.

Nuclee monolitice

De la aparitia ideii de micro-nucleu, aceasta a suscitat un enorm entuziasm printre cercetatori si industriasi. Tehnica promitea sa rezolve elegant o multime de probleme din proiectarea sistemelor de operare, si sa permita scrierea de sisteme distribuite cu mare usurinta. In mod paradoxal insa, la aceasta data, toate sistemele de operare de uz general au mai curind o arhitectura monolitica. Chiar si despre Windows NT, un cal pe care multa lume serioasa pariaza ca invingator in cursa sistemelor de operare, se ride adesea: "a plecat ca un micro-nucleu, dar s-a umflat pina a ajuns mai mare ca un macro-nucleu'.
Am spus mai sus "sisteme de operare de uz general'. Toate consideratiile arhitecturale pe care le prezint sint valabile pentru majoritatea sistemelor de operare existente la zi. Consideratiile despre eficienta, care sint cruciale in supravietuirea comerciala a unui sistem, sint insa semnificative numai pentru sistemele de operare pentru calculatoare obisnuite. Prin contrast, sistemele de operare specializate (de exemplu, sistemele de timp real pentru controlul proceselor, sau pentru masini electronice de jocuri) sint intr-adevar micro-nuclee, si isi fac foarte bine treaba lor.
Cheia este insa aceasta: treaba lor este intr-adevar foarte specializata; o masina SEGA de jocuri electronice nu are nici disc, nici retea, nici periferice prea multe, asa ca sistemul de operare este special scris. Atentia noastra se apleaca mai ales asupra sistemelor tip Unix/Windows (3.1/NT/95)/ VMS, care sint concepute sa permita rularea unei varietati nelimitate de aplicatii si partajarea resurselor intre programe care nu stiu unul despre celalalt, adesea in medii "deschise' (retele). O sa procedez pe parcursul acestui articol indirect: voi atinge tot felul de probleme care aparent nu au mare legatura cu subiectul central, dupa care, in final, intr-o sectiune sumara, voi arata cum consecintele faptelor pe care le-am tot insiruit, si pe care le socotesc nu lipsite de interes in sine, se aduna intru concluzia indicata mai sus, care promite dominatia sistemelor monolitice.

Apeluri de sistem

In aceasta sectiune voi face o scurta recapitulare a modului de functionare a nucleului, pentru a intelege de unde izvorasc toate problemele. Pentru ca am vorbit aiurea despre aceste lucruri mai pe larg, aici voi fi oarecum succint. Cititorul interesat poate gasi o descriere a functionarii unui nucleu de sistem de operare in articolul meu publicat in serial, in PC Report, in septembrie/octombrie 1996 [Pentru cei care nu au cumparat revista, articolele la care fac referinta sint disponibile in postscript din pagina mea de web.]. Nucleul unui sistem de operare se poate asemui cu o biblioteca de functii care sint puse la dispozitia proceselor utilizatorilor. Practic intreg accesul la perifericele conectate este mediat de nucleu, din motive de reutilizare a codului, eficienta si, mai ales, securitate [Se inregistreaza fireste si tendinte de a permite accesul proceselor direct la periferice, cum ar fi, de exemplu, in tehnologia Unet, in care procesele pot scrie direct pe placa de retea; deocamdata sistemele comerciale insa nu au mers atit de departe.]. Pentru utilizatorul normal acest lucru se manifesta prin prezenta unei colectii de functii gata facute, cu care el poate manipula perifericele (terminal, disc, fisiere, retea, etc.). Un exemplu tipic este functia write() din Unix, prin care se pot trimite date spre un periferic. Functiile puse la dispozitie de catre nucleu se numesc apeluri de sistem (SYSTEM CALLS). O alta functie importanta a nucleului, vizibila utilizatorului prin apeluri de sistem pentru crearea, distrugerea si manipularea proceselor, este cea de management al proceselor. Un proces este un program care se executa. Nucleul permite mai multor programe independente sa fie "incarcate' in memorie, puse in executie, oprite si terminate. O functie care este mai rar sub controlul utilizatorului este cea de "planificare' (scheduling) a proceselor: oprirea proceselor care s-au executat prea mult si pornirea celor care tinjesc dupa putina activitate. Nucleul implementeaza de asemenea notiunea de spatiu de adrese, folosind sistemul de memorie virtuala. In arhitecturile "clasice', fiecare proces are impresia ca poseda in intregime memoria calculatorului. Acest truc este realizat folosind translatarea adreselor (address mapping): pentru fiecare proces nucleul mentine o lista a zonelor de memorie care-i sint vizibile, iar orice referinta la memorie a unui proces este recalculata si tradusa intr-o referinta intr-una din zonele care i-au fost alocate. Astfel, adresa 5 ("adresa virtuala') va indica o locatie diferita de memorie in RAM ("adresa fizica') pentru fiecare proces. Vom vedea un pic mai jos ca sistemul de memorie virtuala permite citeodata vizibilitatea unei zone de memorie mai multor procese, pentru usurarea comunicarii intre ele. Nucleul insusi este protejat folosind memoria virtuala. Pentru a putea apela serviciile nucleului, el trebuie sa fie cumva vizibil proceselor. Dar zona de memorie in care se afla nucleul devine accesibila numai atunci cind procesele invoca serviciile nucleului, fiind invizibila sau inaccesibila in mod normal.

Structura unui apel

Sa vedem cum poate un proces ordinar beneficia de serviciile nucleului, pastrind totusi nucleul inaccesibil. (Nucleul poseda o gramada de structuri de date, despre toate procesele, asa incit citirea lor ar putea reprezenta o periculoasa scurgere de informatii. Cu atit mai mult scrierea in zona de memorie fizica in care se afla nucleul trebuie sa fie prohibita in mod normal). Atita vreme cit un proces se executa, el foloseste Unitatea Centrala intr-un mod neprivilegiat (user mode). Procesul "vede' din memoria fizica numai portiunea care i-a fost alocata de nucleu, cam ca in figura "Mod utilizator". Sa presupunem ca procesul vrea sa cheme un apel de sistem (write(), ca sa fim concreti). (Un scenariu asemanator este valabil pentru cazul survenirii unei intreruperi sau executarii unei operatii ilegale.) Pentru acest scop procesul cheama o functie de biblioteca oferita de fabricantii sistemului, care impacheteaza argumentele in niste registri, iar intr-un registru convenit (de pilda AX) codul apelului de sistem (write() sa zicem ca are codul 3), dupa care executa o instructiune speciala a microprocesorului. Aceasta instructiune are un efect dramatic: cauzeaza trecerea procesorului in mod privilegiat (kernel-mode), dupa care sare la o rutina speciala. Aceasta rutina in primul rind transforma modul in care se face translatarea adreselor, "aducind' nucleul in spatiul de adrese al procesului curent. (Aceasta "aducere' se poate face automat prin faptul ca zonele de memorie ale nucleului pot fi accesibile numai in modul privilegiat; depinde de caracteristicile unitatii de management a memoriei si procesorului prin ce detalii anume se obtine vizibilitatea.) Cert este ca, subit, imaginea arata ca in figura "Mod privilegiat". Deodata toate structurile de date si codul nucleului au devenit vizibile. Apoi rutina speciala (care tocmai se executa) se uita in registrii conveniti pentru a depista apelul facut (in exemplul nostru gaseste in AX un 3). Apoi in functie de acesta cheama una sau alta din procedurile de tratare din codul nucleului (de-multiplexeaza apelul, de obicei folosind o tabela care pentru fiecare apel contine o adresa in nucleu: call syscall[AX]). Mai departe, procedura de tratare a apelului de sistem, care este specifica pentru apelul nostru (write) cauta in locurile convenite argumentele (de obicei tot in registri), verifica validitatea lor si incepe executarea apelului. Un apel de sistem de genul lui write() roaga nucleul sa transfere date spre un periferic. In cazul lui write datele sint indicate prin adresa virtuala a unui buffer si marimea lui: write(periferic, buffer, marime). In mod normal, nucleul trebuie sa copieze continutul intregului buffer in interiorul nucleului pentru prelucrare. De ce? Pentru ca acest proces va fi suspendat acum, in asteptarea terminarii executarii apelului de sistem (in general, interactiunea cu perifericele este foarte lenta si cauzeaza suspendarea proceselor). Ori daca acest proces este suspendat, un altul va fi pornit. Dar acest lucru va schimba modul in care este translatat spatiul de adrese virtuale, deci adresa virtuala a buffer-ului indicat nu va mai avea aceeasi semnificatie pentru nucleu! Facind tot felul de trucuri uneori nucleul reuseste sa evite copierea datelor [De pilda, nucleul poate retine adresa fizica a buffer-ului, si poate marca in tabelele interne acea zona ca fiind "tabu' (pentru a nu fi modificata de algoritmii de paginare, care refolosesc memoria fizica) pina continutul ei a fost prelucrat.]. Pentru anumite operatii insa, copierea datelor in interiorul nucleului nu poate fi evitata: de exemplu, cind datele trebuie sa plece in retea ele trebuie impachetate si sparte in bucati mai mici, sau atunci cind merg spre disc trebuie re-aliniate si mutate in cache. De asemenea, cind datele se duc spre un alt proces (de pilda printr-un pipe in Unix) ele trebuie din nou copiate in interiorul nucleului, pentru a lasa procesul care face write sa continue sa foloseasca buffer-ul fara a modifica datele deja trimise (dupa scrierea intr-o "teava' (pipe) procesul care face scrierea de obicei isi continua executia, dar datele sint pastrate pina cind un proces de la celalalt capat al "tevii' le citeste. Pastrarea se face in nucleu).

Comutarea proceselor

Sa ne uitam acum si la operatiile care insotesc comutarea executiei de la un proces la altul, pentru ca acest cost este foarte important in micro-nuclee. Comutarea proceselor implica salvarea starii procesului curent si incarcarea starii procesului care urmeaza pentru executie. Pentru ca cea mai mare parte din stare este continuta in tabele aflate in memorie, schimbarea se poate face relativ simplu incarcind valoarea unui pointer spre noua casuta din tabela care se va folosi (pentru a comuta de la procesul 3 la procesul 5, nucleul va pune in pointerul spre casuta din tabel cu datele procesului curent, valoarea 5 in locul lui 3). In general insa, trebuie luate in calcul mai multe operatii. Anume trebuie facute urmatoarele operatiuni, nici una foarte complicata:

Faza 1: salvarea starii:

Salvarea registrilor curenti;

Salvarea starii coprocesorului matematic;

Salvarea registrilor de depanare, daca procesul curent era depanat;

Salvarea registrilor si starii unitatii de management a memoriei; salvarea tabelei de translatare a adreselor, a procesului curent (tabela de translatare indica modul in care se interpreteaza adresele virtuale pentru procesul curent);

Modificarea contoarelor si ceasurilor de executie pentru a reflecta timpul consumat de procesul care se opreste;


Faza 2: comutarea:

Rularea algoritmului de planificare (scheduling), care parcurge cozile de procese gata de executie in ordinea prioritatilor, alegind pe cel mai urgent;

Golirea cache-urilor de translatare a adreselor --- Translation Lookaside Buffer [vedeti si articolul meu despre cache-uri din PC Report din martie 1997 pentru o discutie a TLB.] TLB este un cache care retine felul in care se traduc adresele virtuale cele mai des folosite pentru procesul curent; din moment ce semnificatia adresei virtuale 5 pentru noul proces va fi alta, vechea ei asociere trebuie stearsa si din TLB.

Faza 3: incarcarea noului proces:

Incarcarea tuturor registrilor salvati (de pasii 1--3), cu valorile lor pentru noul proces;

Incarcarea tabelei de translatare a adreselor, a noului proces si a registrilor unitatii de management a memoriei. In acest fel noul spatiu de adrese virtuale devine vizibil si cel vechi invizibil;

Pentru ca in timp ce noul proces "dormea' s-au putut intimpla evenimente interesante pentru el (de exemplu, in Unix i-a fost trimis un semnal), acum este momentul de a lua actiuni speciale (in cazul semnalelor Unix, se construiesc cadre pe stiva pentru procedurile de tratare a semnalelor, sau procesul este omorit);
11. Schimbarea pointerilor spre a puncta spre noul proces.
Dupa cum vedeti, sint totusi o sumedenie de operatii de facut. Nuclee foarte sofisticate pot avea operatiile de comutare a proceselor chiar mai complicate decit cele descrise aici. Sa observam ca in comutarea proceselor mai exista cel putin un cost ascuns, implicat de operatia de schimbarea localitatii de adresare: pentru ca incepem rularea unui nou proces, care va folosi un spatiu de adrese complet diferit, cache-ul microprocesorului va genera foarte multe rateuri pentru inceput, fiind incarcat cu date din spatiul vechiului proces. De asemenea, TLB a fost golit (in pasul 7 mai sus), deci pentru a-l umple din nou cu traducerea adreselor in noul proces, va trebui sa fie consultata tabela de traducere a adreselor pentru noul proces, operatie costisitoare, deoarece implica accese suplimentare la memorie. Un alt posibil cost va fi platit pina noul proces isi aduce de pe memoria secundara (disc) paginile de memorie din setul de lucru (working set); datorita faptului ca paginile de memorie indelung ne-folosite sint de obicei scoase afara pe disc, s-ar putea ca procesul care tocmai porneste sa trebuiasca sa si le ia de acolo. Aducerea unei pagini este o operatie extrem de costisitoare, care implica, pe linga accesul la disc, si oprirea procesului care cere pagina pina la venirea acesteia, ceea ce inseamna inca o comutare de procese!

Plasarea serviciilor Exista in mod logic trei locuri unde poate fi implementat un serviciu:
1. In spatiul procesului care il foloseste, ca o biblioteca de functii;
2. In interiorul nucleului, accesat printr-un apel de sistem;
3. In gestiunea unui proces separat, numit "server'.
(Un al patrulea loc, mai putin uzual, va fi de asemenea discutat.)
Figura "Unde sunt serviciile" prezinta cele trei cazuri. Le vom analiza pe fiecare pe scurt. Pentru un serviciu dat, foarte adesea proiectantul sistemului are la dispozitie toate cele 3 posibilitati. Modul dominant in care sint plasate serviciile (adica locul majoritatii serviciilor) da si clasificarea unui sistem in taxonomia sistemelor de operare. Practic, fiecare sistem de operare va avea servicii in toate cele trei parti, astfel incit diferenta este mai curind una de grad decit de natura. Astfel, sistemele care aleg varianta 2 pentru majoritatea serviciilor se numesc monolitice, pentru ca tind sa aiba un nucleu foarte mare, cu o gramada de cod. Sistemele care opteaza pentru varianta 3 se numesc prin contrast "micro-nuclee', pentru ca nucleul avind putine servicii devine foarte mic. In fine, sisteme in care majoritatea serviciilor sint plasate in spatiul proceselor insele, in functii de biblioteca, sint relativ putin raspindite. Vom vedea insa niste candidati putin mai jos.

In biblioteci

Cu servicii plasate in biblioteci, este obisnuit orice programator care a folosit un limbaj de genul C sau Pascal. O biblioteca este o colectie de functii gata scrise, la care programele utilizatorilor se pot "lega', si pe care le pot folosi. Legarea (linking) la functiile din biblioteci se poate face, fie atunci cind programul este creat (la sfirsitul compilarii), si atunci se numeste "legare statica' (static linking), fie abia dupa ce programul a fost pornit in executie, fiind atunci numita legare dinamica (dynamic linking). Cert este ca se face doar odata, asa incit costul legarii se "amortizeaza' cind functiile din biblioteca sint folosite intens. "Costul' unui astfel de serviciu este extrem de scazut; cel mai scazut posibil probabil, pentru ca implementarea unui apel de functie in termenii microprocesorului este foarte ieftina. Trebuie insa sa observam ca natura codului din bibliotecile partajate care se incarca dinamic [Este vorba de faptul ca acest cod este "independent de pozitie' (POSITION INDEPENDENT CODE; PIC).] il face citeodata mai ineficient decit codul obisnuit, cu factori cuprinsi intre 1% si 30%. In caseta "Exemple: servicii in biblioteci" sunt prezentate cateva exemple faimoase de servicii plasate in biblioteci.

In nucleu

Al doilea loc unde poate fi plasat un serviciu este in nucleu. Sistemele de operare monolitice pun in nucleu mai toate serviciile care au o utilizare frecventa. Sisteme monolitice tipice sint (si veti recunoaste toate sistemele dominante pe piata): Windows 3.1, Windows 95, Unix, VMS, JavaOS [Informatiile mele in legatura cu JavaOS nu sint foarte ample, dar cred ca poate fi categorisit ca monolitic.]. Windows NT este considerat in continuare un sistem micro-nucleu, desi contine in nucleu servicii care la Unix (un monolit tipic) sint in afara nucleului, cum ar fi sistemul de ferestre sau serverul de fisiere. Dupa cum vedeti, granitele sint difuze intre categorii Sistemele monolitice sint comercial cele mai raspindite. Pentru ilustrare, sa vedem care sint categoriile de servicii oferite de un sistem Unix tipic:

Operatii cu procese (creare, distrugere, etc.)*;
Depanarea si masurarea (profiling) proceselor*;
Planificarea si executia proceselor*;
Accounting (contabilitate) si tarifare dupa consumul resurselor*;
Operatii cu fisiere;
Comunicatie inter-proces:* tevi-conducte (pipes), semnale, memorie partajata, semafoare, mesaje;
Protocoale de comunicatie in retea (TCP/IP);
Gestiunea memoriei virtuale*;
Alocarea si eliberarea memoriei*;
Timere si alarme;
Mecanisme de protectie si securitate*;
Legarea dinamica;
Managementul perifericelor.

Am marcat cu asterisc serviciile care in orice implementare a unui sistem de operare, fie ea monolit sau micro-nucleu, trebuie sa fie oferite de nucleu. (Cum se descurca exokernel-ul fara ele, mie personal nu imi este foarte clar.) Sistemele monolitice sint destul de greu de scris si relativ inflexibile: o schimbare a serviciilor oferite se poate face in mod traditional doar oprind sistemul si recompilind o imagine a nucleului [Sistemele moderne Unix pot incarca dinamic unele portiuni de nucleu.]. Exista insa o cantitate considerabila de experienta in folosirea si manipularea acestor sisteme. Cea mai dezirabila trasatura a acestor sisteme (comparate cu bibliotecile) este separatia neta intre spatiul de adrese al nucleului si cel al proceselor utilizator. Aceasta permite nucleului sa aiba un control foarte strins [Cel putin teoretic; faptul ca se raporteaza mereu noi bug-uri in securitatea sistemelor Unix nu zguduie de loc increderea adeptilor in aceasta teza.] asupra operatiilor care pot fi efectuate de procese, si ii permite sa forteze cu usurinta respectarea politicilor de folosire a resurselor.

In server(e)

In fine, putem lua o resursa partajata si o putem depune in bratele unui proces, care sa aiba grija de ea; procesul care ne "serveste' cu aceasta resursa se va numi "server'. Nucleul trebuie sa puna la dispozitia proceselor o metoda eficace prin care sa comunice intre ele; de indata ce au aceasta metoda la dispozitie, procesele care au nevoie de resursa detinuta de server devin "clientii' lui, trimitindu-i un mesaj cu cererea lor. Serverul le raspunde clientilor cu datele cerute. Marele avantaj al acestei formule este ca teoretic se poate aplica si in cazul in care clientul si serverul sint pe masini diferite si comunica printr-o retea. Intr-adevar, majoritatea covirsitoare a aplicatiilor din retea folosesc aceasta arhitectura. De aici apar insa si problemele, dupa cum vom vedea intr-o sectiune ulterioara consacrata in mod special sistemelor micro-nucleu, care tind sa exploateze tehnologia client-server. Pentru a ilustra diferenta de performanta, pe acelasi calculator pe care am facut masuratorile anterioare, un nucleu experimental extrem de simplu (PicOS --- implementat de autor), fara memorie virtuala, cu procese integral rezidente in RAM, permite schimbarea a circa 5000 de mesaje/sec intre doua procese pe aceeasi masina. Asta inseamna deja 200 de microsecunde pentru un mesaj, adica 400 pentru un apel complet cerere/raspuns. Comparati cu performanta unui apel de sistem si cu a unui apel de procedura. Caseta "Exemple: Servere si resurse" ilustreaza citeva exemple reale de folosire a serverelor pentru gestiunea resurselor.

Resurse fara servere

Sa notam in treacat ca toate cele trei solutii citate dau fiecare resursa pe seama cuiva: o biblioteca, un nucleu, un proces. Exista si o solutie "democratica', in care nimeni nu poseda un obiect; acest stil de proiectare se numeste "fara servere' (serverless). Din pacate, algoritmii folositi pentru acest fel de probleme sint in general putin robusti si extrem de complicati, si tradeaza adesea tocmai cauza pentru care erau creati: evitarea unei "gituituri' (bottleneck) in accesul la resursa, reprezentata de serverul care o gestioneaza. Sa notam totusi o aplicatie a acestui gen de algoritmi in sistemele de calcul paralele si distribuite, mai ales a celor care implementeaza ceea ce se numeste memorie distribuita partajata (Distributed Shared Memory, DSM). Ideea centrala este de a avea pentru toate calculatoarele dintr-o retea un singur spatiu de adrese urias, in care toate scriu si citesc, dar care nu este memorat fizic in vreun loc fixat, ci ale carui "locatii' se "plimba' dupa necesitati intre masinile care le folosesc. Exista si sisteme de fisiere implementate dupa aceasta schema, dar progresele comerciale sint (inca) slabute. Nici noi nu o sa le consacram deci prea mare importanta in acest articol, care iar a inceput sa ia proportii mai mari decit cele anticipate initial de autor.

Semantica operatiilor

"Unde sa plasam un serviciu, in care din cele trei posturi?' Aparent raspunsul la aceasta intrebare depinde doar de consideratii de eficienta si estetica, precum si de extravaganta design-erului. Dar lucrurile nu stau chiar asa! Vom vedea ca anumite insusiri ale unui serviciu depind esential de plasarea sa, si ca fiecare din cele trei scheme are proprietati speciale, care nu pot fi simulate nicicum in intregime de celelalte. (Vom ignora asemenea consideratii elementare cum ar fi ca nu putem plasa servicii de creare a proceselor intr-o biblioteca, pentru ca atunci cine creaza procesul in care se afla biblioteca?) Lista de diferente care urmeaza nu este in nici un caz exhaustiva, ci doar vrea sa ilustreze prin exemple problema.
Diferente semantice biblioteca-nucleu
Deosebirea dintre biblioteca si nucleu este cu siguranta familiara oricarui programator in C care, frustrat, a incercat sa-si depaneze programele punind printf()-uri pe ici-colo, dar care nu dadeau nici un efect! Explicatia este simpla: printf() scrie, dupa cum am vazut, intr-un buffer, care este golit numai in anumite circumstante. Daca o eroare survine inainte ca apelul de sistem write() sa fie executat si procesul moare, continutul din buffer este definitiv pierdut! (Solutia este, fireste, sa fortam golirea buffer-ului folosind functia fflush().) Asa ceva nu se va intimpla daca folosim direct write(), pentru ca odata apelul de sistem executat, datele au fost copiate de nucleu si vor ajunge pina la urma la perifericul-destinatie. Diferenta esentiala intre cele doua cazuri este de durata de viata a informatiei: daca informatia este intr-o biblioteca, locala unui proces, atunci ea nu poate supravietui mortii procesului [Fireste, o biblioteca partajata poate servi drept depozit de informatie]. Nucleul in schimb supravietuieste tuturor proceselor (teoretic), deci poate mentine in siguranta informatiile globale pentru intregul sistem. Un alt exemplu faimos este implementarea protocoalelor de retea in biblioteci, care pune infernale dificultati (de altfel, acesta este unul dintre motivele atacurilor la exokernel, care, va amintiti, este o biblioteca mare): de exemplu, standardul TCP/IP impune ca dupa inchiderea unei conexiuni de retea, unul din capete sa retina identificatorul conexiunii pentru o vreme nefolosit ("30 de secunde' scrie la carte), in asa fel incit sa nu fie insusit de o alta conexiune (in acel caz, pachete intirziate ale conexiunii precedente care mai ratacesc pe retea ar putea fi incorect primite pe conexiunea noua). Puteti vedea in Unix lista tuturor conexiunilor cu comanda netstat. Cele care sint in starea TIME_WAIT sint conexiuni de acest gen: terminate, dar memorate. Pe un server de web trebuie sa fie o multime de astfel de conexiuni la un moment dat [Daca nu aveti la indemina un server de web, creati o conexiune cu telnet localhost, vedeti ambele capete cu netstat, inchideti conexiunea cu exit si apoi vedeti informatia ramasa din nou cu netstat.]. Ei bine, pe un proces care are protocoalele de comunicatie implementate in biblioteci il vor trece toate sudorile sa mentina identificatorul conexiunii dupa moartea procesului.
Diferente semantice nucleu--server
O deosebire de acelasi gen de semantica (semnificatie), de acelasi gen al serviciilor subzista intre serviciile oferite de nucleu si cele oferite de servere aflate la distanta: in mod normal, pe o masina, ori merge nucleul si procesele, ori, daca nucleul nu merge, nu merge nimic. Cu alte cuvinte, daca procesele pot cere servicii de la nucleu sint sigure ca gestionarul lor este sanatos. Acest lucru nu mai este adevarat in cazul proceselor care cer servicii de la distanta: cind arunci niste informatie in retea si nu primesti raspuns este greu de zis daca informatia a ajuns si raspunsul nu, sau informatia s-a pierdut, sau a ajuns si serverul a murit inainte sau dupa ce a primit-o. De aici si complexitatea enorma a protocoalelor de retea si a algoritmilor distribuiti. O alta diferenta, greu de mascat intre solutia unei probleme cu nucleu si solutia cu servere este in incredere. Un nucleu stie ca toate procesele care ruleaza pe masina lui au fost create de el si sint "legitime'. Pe de alta parte, cind un server primeste o cerere de la distanta (sau chiar pe aceeasi masina), el nu are la dispozitie mijloacele nucleului de verificare. Un mecanism complet diferit trebuie inventat pentru a asigura serverul de identitatea clientilor, un lucru nenecesar pentru un serviciu plasat in nucleu.

Promisiunile micro-nucleelor

Iata care sint unele din avantajele (reale sau fictive) ale arhitecturii micro-nucleu; unele din aceste merite sint atribuite arhitecturii client-server, altele arhitecturii de micro-nucleu, dar am vazut ca a doua o implica pe prima. Modularitate. Intr-un nucleu monolitic diferitele parti comunica foarte adesea folosind variabile globale, ceea ce ridica probleme dificile privitoare la corectitudinea codului. Mai ales pe multiprocesoare, unde mai multe programe pot actiona simultan asupra aceleiasi structuri de date, se pot ivi tot felul de comportamente ciudate. Prin contrast, in solutia cu servere, un server gestioneaza o cantitate redusa de resurse, iar interactiunea cu alte programe se face prin interfete foarte bine precizate (mesaje). E clar, micro-nucleele incurajeaza modularitatea. Scalabilitate. Vrei un serviciu mai puternic: mai adaugi niste servere sau niste clienti, inlocuiesti serverele cu altele mai performante. O masina este prea incarcata: muti din servere pe alta masina. Toate acestea sint aspecte ale cresterii incrementale a unui sistem, sau crestere in raport cu resursele si necesitatile disponibile. Distribuire facila. Daca primitiva ta de baza este trimite_mesaj(), atunci esti incurajat sa dezvolti solutii pentru programe in care nu conteaza unde se afla server-ul. Mediile de calcul distribuit (DCE: Distributed Computing Environment al lui OSF: Open Software Foundation) sint un exemplu de standard de scriere a unei aplicatii independent de numarul de calculatoare pe care se executa. Adaptabilitate (customizability). Nucleul nu poate fi schimbat decit in mica masura, cu mare grija, si arar fara a opri sistemul. Pe de alta parte, serverele sint simple procese, care pot fi create si omorite dinamic, fara a avea nevoie de privilegii administrative extraordinare. Cu alte cuvinte fiecare utilizator al unui micro-nucleu ar putea sa-si construiasca mediul care ii convine; cine nu foloseste fisiere nu porneste nici un server de fisiere, si are mai multe resurse pentru alte ocupatii. Dimensiune redusa. Virful de lance al creatorilor de micro-nuclee este: platesti numai pentru ce folosesti. Nu ai nevoie de ceva: nu primesti. Un nucleu monolit contine toate serviciile, fie ca le vrei, fie ca nu. Comunicatie puternica inter-proces. Aceasta este o conditie necesara pentru viabilitatea unui micro-nucleu. Comunicatia trebuie sa fie eficienta, pentru ca fiecare serviciu implica cel putin un schimb de doua mesaje (cerere/raspuns), si flexibila pentru a permite transmiterea unei variate game de mesaje (de la un numar, la un fisier de megaocteti cu imagini).

RPC

Orice discutie serioasa despre arhitectura client-server trebuie sa atinga macar in trecere subiectul apelului procedurilor la distanta (remote procedure calls). Subiectul este fascinant si merita o tratare mult mai ampla. Observati ca in cazul folosirii serverelor nu numai ca am mutat un serviciu intr-un proces separat, dar am schimbat si natura modului in care serviciul este invocat: inainte era printr-un apel de functie (sau de sistem), dar acum este prin trimiterea unui mesaj. E aceeasi diferenta de perspectiva ca intre o procedura si un fisier; pentru un programator paradigma mesajului este mai incomoda. Din cauza asta a fost inventata impachetarea mesajelor in proceduri. Practic programatorul cheama o procedura (dintr-o biblioteca), care procedura construieste mesajul, il trimite, asteapta raspunsul si se intoarce in mod uzual. In acest fel programatorul opereaza din nou cu conceptul familiar de procedura. O astfel de procedura chemata la distanta se numeste in engleza "remote procedure call', prescurtat RPC. Un pachet RPC face multe lucruri: dintr-o specificare de nivel inalt a procedurii oferite de server[Intr-un limbaj de descriere a interfetei, "interface definition language', prescurtat IDL.] el construieste automat functiile pentru client si server. Functiile acestea care manipuleaza mesajul se numesc in engleza STUB. Misiunea lor este de a impacheta argumentele procedurii intr-un mesaj (operatie numita marshalling ), de a trimite mesajul si a despacheta valorile la receptia unui mesaj. Functionarea este prezentata schematic in figura RPC. Procedurile stub sint generate de compilatoare speciale din simpla descriere a interfetei lor (tipul argumentelor si al rezultatelor). O alta problema rezolvata de un pachet RPC este de a localiza serverele care ofera servicii. Cind un client porneste, el stie doar ca undeva ar trebui sa se afle un server care exporta serviciile care il intereseaza. Operatia de descoperire a server-ului se numeste tot "legare', dar in engleza foloseste termenul BINDING, care este un sinonim partial pentru "linking' (corespunzind acestei faze din compilarea traditionala). O calitate a unui pachet RPC bun este ca permite invocarea de proceduri pe masini diferite arhitectural de cea pe care se afla clientul. Pentru asta procedurile stub de impachetare trebuie sa foloseasca un standard comun de reprezentare a datelor, astfel incit calculatoare care folosesc reprezentari diferite (ex. big/little endian) diferite sa se inteleaga totusi intre ele. Exista o multime de probleme cu RPC, care scad oarecum din meritele metodei; in principal, o serie de diferente intre semantica unui apel de procedura obisnuita si al unei proceduri distante sint aproape de nedepasit. De exemplu, cum trimiti un pointer la distanta si la ce-i foloseste server-ului, care are alt spatiu de adrese?

Problema micro-nucleelor

Din cit am divagat, probabil ca problema sare-n ochi: intr-un micro-nucleu costul unui serviciu este prea ridicat. Asta pentru ca transmiterea unui mesaj implica:
1. Apeluri de sistem pentru trimitere si receptie de mesaje, atit de partea clientului cit si a serverului;
2. Cel putin o comutare de procese;
3. Pentru RPC impachetarea si despachetarea argumentelor;
4. Copierea argumentelor din spatiul de adrese al clientului, in nucleu, eventual prin retea, si apoi in spatiul serverului;
5. Crearea unui thread in server pentru a trata cererea;
6. Daca mesajul trece prin retea este posibil sa fie copiat de mai multe ori: de pilda din nucleu pe placa de retea si invers la receptie; 7.
Copierea raspunsului pe traseul invers server ---> client.
O alta observatie interesanta este ca, in general, in micro-nuclee tendinta este de a fragmenta un serviciu oferit de un nucleu monolit in MAI MULTE servicii oferite de servere diferite. De exemplu, apelul open(fisier) din Unix de obicei devine un apel pentru a traduce numele de fisier intr-un identificator unic, executat de serverul de directoare (sau, mai rau, traducerea fiecarei parti din "carare' (path) independent, printr-un apel separat al unui alt server!), si apoi "deschiderea' fisierului la serverul de fisiere propriu-zis (figura 6 ilustreaza acest fapt). In acest caz, ceea ce initial era un singur apel de sistem poate deveni o suita de zeci de mesaje schimbate cu mai multe servere!

In loc de FINAL: arhitectura NT

Vom incheia acest articol urmarind citeva din trucurile facute de proiectantii sistemului Windows NT in lupta cu microsecundele. Trebuie spus din capul locului ca pentru a pastra compatibilitatea cu atitea sisteme existente (Windows 95, OS/2, etc.) ei nu aveau de ales intre prea multe variante arhitecturale, si ca solutia cu serverele din figura 4 este cea mai flexibila.
Local procedure call (LPC)
Un pachet RPC face o gramada de operatii de care nu este nevoie in cazul in care clientul si serverul sint pe aceeasi masina. De exemplu, conversia datelor intr-un format standard si inapoi este curata sinucidere, din moment ce procesorul este acelasi. Pe de alta parte o cantitate impresionanta de mesaje in NT tind sa fie intre programe locale; de exemplu, tot ce tine de afisare pe ecran se plimba intre unul din serverele de emulare si serverul Windows 95, care singur are in mina gestiunea ecranului. Din cauza asta intre NT 3.54 si NT 4.0 serverul de ecran a coborit in nucleu, cum apare si in figura din caseta "Arhitectura lui Windows NT".
Mai apar si alte mesaje locale, de exemplu intre un program Unix si serverul de emulare Unix. Proiectantii NT au optimizat in mod special acest gen de comunicare, numind-o "apel de procedura locala' (Local Procedure Call, LPC). Cind apelul unei functii dintr-un server este pe aceeasi masina, majoritatea operatiilor costisitoare sint pur si simplu evitate. Din pacate, nici atita nu este suficient pentru a atinge performanta necesara. Iata alte doua trucuri care sint folosite cu succes in cazul NT, pentru servere locale.


Memoria partajata

Daca se elimina operatiile care transforma datele (marshalling), atunci cel mai mare cost nu este dat nici de apelul de sistem, nici de comutarea proceselor, ci de copierea argumentelor mari. Foarte adesea serverele de fisiere sint implementate folosind RPC; operatii tipice vor transfera cantitati mari de date din/spre fisier. Copierea datelor din client in nucleu si apoi in server pentru un write() (sau invers la citirea unui fisier) este o risipa majora (overhead) fara nici un beneficiu real. Proiectantii lui Windows NT au folosit un mod special de transmitere a datelor intre un client si un server, care foloseste mecanismul de memorie virtuala oferit de nucleu. Astfel, clientul aloca o zona de memorie partajata (pagini din RAM care sint vizibile in mai multe spatii virtuale) si trimite server-ului doar o descriere a zonei partajate. De pilda, pentru un write() clientul aloca zona (printr-un apel special de sistem), scrie datele in zona, face un LPC write() la server, dind descrierea zonei partajate. Serverul poate accesa acum direct memoria comuna cu clientul. Nici un octet nu a fost mutat in bufferele din nucleu si inapoi! Singura operatie este modificarea tabelelor de translatare a adreselor pentru a face zona vizibila si in server. Zona partajata este facuta vizibila in spatiul server-ului in timp ce serverul executa apelul, dupa care devine din nou invizibila pentru server. Aceeasi tehnologie, a memoriei partajate, este folosita si in anumite implementari ale serverelor de ferestre X Windows, in care clientii locali pot da direct zone de memorie, si nu continutul lor.

Prealocarea resurselor

Amintiti-va, din sectiunea dedicata serviciilor oferite de servere, cum functioneaza un server in NT: face "pui' (thread-uri) pentru fiecare noua cerere, care mor dupa executia cererii. Aceasta creare de thread-uri pentru fiecare serviciu este de asemenea o sursa importanta de ineficienta. De aceea, Windows NT mai incalca inca odata regulile bunelor maniere si face o optimizare speciala. Proiectantii spun ca aceasta optimizare este atit de urita incit nici nu este accesibila utilizatorului obisnuit; ea este folosita numai intre serverele de emulare si modulul grafic. Pe scurt, intre un client foarte activ si un server se stabileste o cale extrem de rapida de comunicare la cererea clientului. Astfel, server-ul aloca un thread special pentru acel client, care va executa numai cererile acestui client. Mai exista o zona partajata alocata permanent pentru uzul celor doi, si o pereche de "evenimente' (event pair). Perechea de evenimente este de fapt un intrerupator prin care clientul si thread-ul alocat din server isi semnaleaza reciproc (mai exact ii semnaleaza planificatorului din nucleu) cind au nevoie de serviciile celuilalt. Acest mecanism simplifica multe operatii: thread-ul nu mai este creat/distrus, tabela de pagini pentru memoria partajata nu mai este modificata (pentru ca zona partajata va fi folosita pentru totdeauna de doua thread-uri fixate), planificatorul (scheduler-ul) nu mai are de facut nici o decizie de alegere, pentru ca va rula server-ul in cuanta de timp neconsumata a client-ului.

Concluzii

Microsoft pare sa fi facut un efort substantial la constructia noii versiuni de Windows NT, pentru a pregati o lovitura decisiva concurentilor sai (in principal Unix-uri). Si, dupa cum se pare acum, batalia se va da in principal pe doua campuri: bazele de date si Internetul. Daca tot ceea ce si-a propus Microsoft va fi rezolvat cu adevarat, Windows NT va deveni un concurent serios al serverelor Unix care stapanesc inca in marile companii.