Asynkron filingångsutgång c. Villkor: Data input-output synkron och asynkron. Exempel: Använda en väntetimer

En applikationsprogrammerare behöver inte tänka på saker som hur systemprogram fungerar med enhetsregister. Systemet döljer detaljer om arbete på låg nivå med enheter från applikationer. Skillnaden mellan att organisera I/O genom polling och avbrott återspeglas dock även på systemfunktionsnivån, i form av funktioner för synkron och asynkron I/O.

Utför en funktion synkron I/O innebär att starta en I/O-operation och vänta på att den operationen ska slutföras. Först efter att I/O är klar återgår funktionen till det anropande programmet.

Synchronous I/O är det mest välbekanta sättet för programmerare att arbeta med enheter. Standardrutiner för programmeringsspråksinmatning/utmatning fungerar på detta sätt.

Anropa en funktion asynkron I/O betyder endast att starta motsvarande operation. Efter detta återgår funktionen omedelbart till det anropande programmet utan att vänta på att operationen ska slutföras.

Tänk till exempel på asynkron datainmatning. Det är tydligt att programmet inte kan komma åt data förrän det är säkert att dess inmatning är klar. Men det är mycket möjligt att programmet kan göra annat arbete för nu, snarare än att stå stilla och vänta.

Förr eller senare måste programmet fortfarande börja arbeta med de inmatade uppgifterna, men se först till att den asynkrona operationen redan har slutförts. För detta ändamål tillhandahåller olika operativsystem verktyg som kan delas in i tre grupper.

· Väntar på att operationen ska slutföras. Det här är som "den andra halvan av en synkron operation." Programmet startade först operationen, utförde sedan några främmande åtgärder och väntar nu på att operationen ska slutföras, som med synkron input/output.

· Kontrollera att operationen är klar. I det här fallet väntar inte programmet, utan kontrollerar bara statusen för den asynkrona operationen. Om inmatningen/utmatningen ännu inte är klar, har programmet möjlighet att gå en tid.

· Tilldelning av färdigställandeförfarande. I det här fallet, när en asynkron operation startas, indikerar användarprogrammet för systemet adressen till användarproceduren eller funktionen som ska anropas av systemet efter att operationen är klar. Programmet i sig kanske inte längre är intresserad av förloppet för input/output; systemet kommer att påminna det om detta vid rätt tidpunkt genom att ringa specificerad funktion. Denna metod är den mest flexibla, eftersom användaren kan tillhandahålla alla åtgärder i slutförandeproceduren.

I en Windows-applikation är alla tre sätten att slutföra asynkrona operationer tillgängliga. UNIX har inga asynkrona I/O-funktioner, men samma asynkrona effekt kan uppnås på ett annat sätt, genom att köra en extra process.

Asynkron I/O kan förbättra prestandan i vissa fall och ge ytterligare funktionalitet. Utan sådana enklaste formen asynkron ingång, som "tangentbordsinmatning utan att vänta", många datorspel och simulatorer. Samtidigt är logiken i ett program som använder asynkrona operationer mer komplex än med synkrona operationer.

Vad är sambandet som nämnts ovan mellan synkrona/asynkrona operationer och metoderna för att organisera input/output som diskuterades i föregående stycke? Svara själv på den här frågan.

Asynkron I/O med flera trådar

Överlappande och utökade I/O gör att I/O kan utföras asynkront inom en enda tråd, även om operativsystemet skapar sina egna trådar för att stödja denna funktion. I en eller annan form används ofta metoder av denna typ i många tidiga operativsystem för att stödja begränsade former av att utföra asynkrona operationer på entrådiga system.

Windows tillhandahåller dock stöd för flera trådar, så det är möjligt att uppnå samma effekt genom att utföra synkrona I/O-operationer på flera, oberoende körande trådar. Dessa funktioner har tidigare demonstrerats med hjälp av flertrådade servrar och grepMT-programmet (kapitel 7). Dessutom ger trådar ett konceptuellt konsekvent och förmodligen mycket enklare sätt att utföra asynkrona I/O-operationer. Ett alternativ till metoderna som används i program 14.1 och 14.2 skulle vara att ge varje tråd sin egen filbeskrivning, så att varje tråd kan behandla var fjärde post synkront.

Detta sätt att använda trådar demonstreras i programmet atouMT, som inte ges i boken, men ingår i materialet som publiceras på webbplatsen. AtouMT-programmet kan inte bara köras under kontroll av någon Windows-versioner, men också enklare än någon av de två versionerna av asynkrona I/O-program, eftersom redovisning av resursanvändning i detta fall är mindre komplicerad. Varje tråd upprätthåller helt enkelt sina egna buffertar på sin egen stack och går igenom en sekvens av synkrona läs-, omvandlings- och skrivoperationer. Samtidigt ligger programprestationen på en ganska hög nivå.

Notera

Programmet atouMT.c, som finns på webbplatsen, innehåller kommentarer om flera möjliga fallgropar som kan vänta dig när du tillåter flera trådar att komma åt samma fil samtidigt. I synnerhet måste alla individuella filhandtag skapas med hjälp av CreateHandle-funktionen snarare än DuplicateHandle-funktionen.

Personligen föredrar jag att använda flertrådad filbehandling snarare än asynkron I/O. Trådar är lättare att programmera och ger bättre prestanda i de flesta fall.

Det finns två undantag från denna allmänna regel. Den första av dessa, som visats tidigare i det här kapitlet, gäller situationer där det kanske bara finns en utestående operation och en filbeskrivning kan användas för synkroniseringsändamål. Ett andra, viktigare undantag inträffar i fallet med asynkrona I/O-kompletteringsportar, vilket kommer att diskuteras i slutet av detta kapitel.

Från boken Låt oss bygga en kompilator! av Crenshaw Jack

Från boken Programmering i Prolog författaren Kloksin U.

Från boken The C# 2005 Programming Language and the .NET 2.0 Platform. av Troelsen Andrew

Från boken Informix Database Administrator's Guide. författare Kustov Viktor

Från boken Microsoft Visual C++ och MFC. Programmering för Windows 95 och Windows NT författare Frolov Alexander Vyacheslavovich

2.2.3.2 Asynkron I/O För att påskynda I/O-operationer använder servern sitt eget Asynkrona I/O (AIO)-paket eller Kernel Asynchronous I/O (KAIO)-paketet, om tillgängligt. Användar-I/O-förfrågningar behandlas asynkront,

Från boken Fundamentals of Object-Oriented Programming av Meyer Bertrand

I/O Som ni vet, operatörer<< и >> utföra ett skifte numeriskt värde vänster och höger med ett visst antal bitar. Programmen i vår bok använder också dessa uttalanden för att mata in information från tangentbordet och visa den på skärmen.

Från boken Systemprogrammering i Windows-miljö av Hart Johnson M

Indata och utdata Två KERNEL-biblioteksklasser tillhandahåller grundläggande inmatnings- och utdatafaciliteter: FILE och STD_FILES. Bland operationerna som definieras på ett objekt f av typen FILE finns följande: create f.make ("namn") -- Associerar f med en fil med namnet namn f.open_write -- Öppna f för att skriva f.open_read -- Öppna f för

Från boken Programmering i Ruby [Språkideologi, teori och tillämpningspraktik] av Fulton Hal

KAPITEL 14 Asynkrona I/O- och kompletteringsportar I/O-operationer är i sig långsammare än andra typer av bearbetning. Orsakerna till denna avmattning är följande faktorer: Förseningar på grund av tid för sökning

Från boken Programmering i Prolog för artificiell intelligens författaren Bratko Ivan

10.1.7. Enkel I/O Du är redan bekant med några av I/O-metoderna från Kernel-modulen; vi ringde dem utan att ange en uppringare. Dessa inkluderar gets och puts-funktionerna, samt print, printf och p (den senare anropar objektets inspekteringsmetod för att skriva ut det på ett sätt som vi kan förstå).

Från boken C Programming Language for a Personal Computer författaren Bochkov S. O.

Från boken Linux-programmering med exempel författare Robbins Arnold

Kapitel 6 Inmatning och utdata I det här kapitlet kommer vi att titta på några inbyggda faciliteter för att skriva data till och läsa data från en fil. Sådana verktyg kan också användas för att formatera programdataobjekt för att erhålla den önskade formen av deras externa representation.

Från boken Basics of Java Programming författaren Sukhov S.A.

Inmatning och utdata In- och utdatafunktionerna i standard C-biblioteket låter dig läsa data från filer eller ta emot dem från inmatningsenheter (som tangentbordet) och skriva data till filer eller mata ut den till olika enheter(till exempel till en skrivare.) Inmatnings-/utgångsfunktioner

Från boken QT 4: GUI-programmering i C++ av Blanchette Jasmine

4.4. Inmatning och utdata Alla Linux I/O-operationer utförs genom filbeskrivningar. Det här avsnittet introducerar filbeskrivningar, beskriver hur man skaffar och frigör dem och förklarar hur man kör med dem.

Från boken The Ideal Programmer. Hur man blir en mjukvaruutvecklingsproffs författare Martin Robert S.

Från författarens bok

Kapitel 12: I/O Nästan varje applikation kräver att du läser eller skriver filer eller utför andra I/O-operationer. Qt ger utmärkt I/O-stöd med QIODevice, en kraftfull abstraktion av "enheter" som kan läsa och skriva.

Från författarens bok

Input och Output Jag tycker också att det är mycket viktigt att mina resultat drivs av lämplig "input". Skrift programkod- kreativt arbete. Min kreativitet brukar vara som bäst när jag ställs inför en kreativ utmaning.

Uppgiften som utfärdade begäran om I/O-operationen placeras av arbetsledaren i tillståndet av väntan på slutförandet av den beställda operationen. När handledaren får ett meddelande från avslutningssektionen att operationen har slutförts sätter den uppgiften i redoläge och den fortsätter sitt arbete. Denna situation motsvarar synkron I/O. Synkron I/O är standard på de flesta operativsystem. För att öka hastigheten på applikationsexekveringen föreslogs att använda asynkron I/O vid behov.

Den enklaste versionen av asynkron utgång är den så kallade buffrade utgången till en extern enhet, där data från applikationen inte överförs direkt till I/O-enheten, utan till en speciell systembuffert. I det här fallet anses utmatningsoperationen för applikationen logiskt vara slutförd omedelbart, och uppgiften kanske inte väntar på att den faktiska processen att överföra data till enheten ska slutföras. Bearbeta verklig produktion Data från systembufferten hanteras av I/O-övervakaren. Naturligtvis är en speciell systemprocess i ledning av I/O-övervakaren ansvarig för att allokera en buffert från systemminnesområdet. Så för det aktuella fallet kommer utsignalen att vara asynkron om, för det första, I/O-begäran indikerade behovet av databuffring, och för det andra, om I/O-anordningen tillåter sådana asynkrona operationer och detta noteras i UCB. Du kan också organisera asynkron datainmatning. Men för att göra detta är det nödvändigt att inte bara tilldela ett minnesområde för tillfällig lagring av data som läses från enheten och att associera den tilldelade bufferten med uppgiften som beordrade operationen, utan också att dela upp begäran om I/O operation i två delar (i två förfrågningar). Den första begäran specificerar operationen för att läsa data, liknande vad som görs med synkron I/O. Men typen (koden) för begäran är annorlunda, och begäran specificerar minst en ytterligare parameter - namnet (koden) på systemobjektet som uppgiften tar emot som svar på begäran och som identifierar den tilldelade bufferten. Efter att ha fått namnet på bufferten (vi brukar kalla detta systemobjekt på detta sätt, även om olika operativsystem också använder andra termer för att beteckna det, till exempel klass), fortsätter uppgiften sitt arbete. Det är mycket viktigt att betona här att som ett resultat av en asynkron datainmatningsbegäran, placeras uppgiften inte i ett tillstånd av I/O-övervakaren för att vänta på att I/O-operationen ska slutföras, utan förblir snarare i ett pågående eller redo att köras. Efter en tid, efter att ha utfört den nödvändiga koden som definierats av programmeraren, skickar uppgiften en andra begäran för att slutföra I/O-operationen. I denna andra begäran till samma enhet, som naturligtvis har en annan kod (eller begäran namn), specificerar uppgiften namnet på systemobjektet (buffert för asynkron datainmatning) och, om dataläsningsoperationen lyckas, tar omedelbart emot det från systembufferten. Om data ännu inte har överförts fullständigt från den externa enheten till systembufferten, växlar I/O-övervakaren uppgiften till tillståndet att vänta på slutförandet av I/O-operationen, och då liknar allt normal synkron datainmatning.

Vanligtvis tillhandahålls asynkron I/O i de flestam, särskilt om operativsystemet stöder multitasking med en trådmekanism. Men om det inte finns någon explicit asynkron input/output, kan du implementera dess idéer själv genom att organisera en oberoende tråd för datautmatning.

I/O-hårdvara kan betraktas som en samling hårdvaruprocessorer, som kan arbeta parallellt i förhållande till varandra, såväl som i förhållande till den centrala processorn (processorerna). På sådana "processorer" den sk externa processer. Till exempel, för en extern enhet (inmatnings-/utmatningsenhet) kan den externa processen vara en uppsättning operationer som översätter skrivhuvudet, flyttar fram papperet en position, ändrar bläckfärgen eller skriver ut några tecken. Externa processer, med hjälp av in-/utgångshårdvara, interagerar både med varandra och med vanliga "mjukvaruprocesser" som körs på den centrala processorn. Ett viktigt faktum är att exekveringshastigheten för externa processer kommer att skilja sig avsevärt (ibland i en storleksordning eller mer) från exekveringshastigheten för konventionella (“ inre") processer. För normal drift måste externa och interna processer synkroniseras. För att jämna ut effekten av en stark hastighetsmissanpassning mellan interna och externa processer används den ovan nämnda buffringen. Vi kan alltså tala om ett system av parallellt interagerande processer (se kapitel 6).

Buffertar är en kritisk resurs i förhållande till interna (mjukvara) och externa processer, som under sin parallella utveckling interagerar informationsmässigt. Genom en buffert(ar) skickas data antingen från någon process till en adresserbar extern (datautmatningsoperation till en extern enhet), eller från en extern process överförs till någon mjukvaruprocess (dataläsoperation). Införandet av buffert som ett sätt för informationsinteraktion väcker problemet med att hantera dessa systembuffertar, vilket löses med hjälp av den övervakande delen av operativsystemet. I det här fallet har arbetsledaren i uppdrag att inte bara tilldela och frigöra buffertar i systemminnesområdet, utan också att synkronisera processer i enlighet med drifttillståndet för att fylla eller frigöra buffertar, samt att vänta på dem om det inte finns några lediga buffertar tillgängliga och ingångsbegäran/utgången kräver buffring. Vanligtvis använder I/O-övervakaren standardsynkroniseringsverktyg som används i ett givet operativsystem för att lösa de listade uppgifterna. Därför, om operativsystemet har utvecklat verktyg för att lösa problem med parallell exekvering av interagerande applikationer och uppgifter, implementerar det som regel också asynkron input/output.

synkron modell input/output. Read(2), write(2)-systemet anropar och deras analoger returnerar kontroll först efter att data redan har lästs eller skrivits. Detta resulterar ofta i att tråden blockeras.

Notera

I verkligheten är det inte så enkelt. read(2) måste vänta på att data fysiskt läses från enheten, men write(2) fungerar som standard i lazy-skrivläge: den återkommer efter att data har överförts till systembufferten, men vanligtvis före data överförs fysiskt till enheten. Detta förbättrar vanligtvis programmets observerade prestanda avsevärt och gör att minnet från data kan användas för andra ändamål omedelbart efter att write(2) returneras. Men försenad inspelning har också betydande nackdelar. Den viktigaste är att du kommer att lära dig om resultatet av en fysisk operation inte omedelbart genom returkoden för write(2) , utan bara en tid efter returen, vanligtvis genom returkoden för nästa write(2)-anrop. För vissa applikationer - transaktionsövervakare, många realtidsprogram, etc. - är detta oacceptabelt och de tvingas stänga av lat inspelning. Detta görs av flaggan O_SYNC, som kan ställas in när filen öppnas och ändras kl öppna fil genom att anropa fcntl(2) .

Synkronisering av individuella skrivningar kan säkerställas genom att anropa fsync(2) . För många applikationer som involverar flera enheter och/eller nätverksanslutningar synkron modell obekväm. Att arbeta i polling-läge är inte heller alltid acceptabelt. Faktum är att select(3C) och poll(2) anser att en filbeskrivning är redo att läsas först efter att data fysiskt dykt upp i dess buffert. Men vissa enheter börjar skicka data först efter att de uttryckligen uppmanas att göra det.

För vissa applikationer, särskilt realtidsapplikationer, är det också viktigt att veta det exakta ögonblicket när data börjar anlända. För sådana applikationer kan det också vara oacceptabelt att select(3C) och poll(2) överväger vanliga filer alltid redo att läsa och skriva. Verkligen, filsystem läsa från disk och även om det fungerar mycket snabbare än de flesta nätverkskopplingar, men fortfarande åtkomst till den är förknippad med vissa förseningar. För hårda realtidsapplikationer kan dessa förseningar vara oacceptabla – men utan en uttrycklig läsbegäran filsystem lämnar inte ut data!

För hårda realtidsapplikationer kan en annan aspekt av I/O-problemet vara betydande. Faktum är att hårda RT-applikationer har högre prioritet än kärnan, så de kör systemanrop - även icke-blockerande sådana! - kan leda till prioritetsinversion.

Lösningen på dessa problem har varit känd sedan länge och kallas asynkron input/output. I detta läge anropar I/O-systemet returkontroll omedelbart efter att en begäran har gjorts till enhetsdrivrutinen, vanligtvis även innan data har kopierats till systembufferten. Att bilda en begäran består av att placera en post (IRP, Input/Output Request Packet, input/output request-paket) i en kö. För att göra detta behöver du bara kort fånga mutexen som skyddar "svansen" på kön, så problemet med prioritetsinversion kan lätt övervinnas. För att ta reda på om samtalet har avslutats, och om det har avslutats, hur exakt, och om minnet som data lagrades i kan användas, tillhandahålls ett speciellt API (se fig. 8.1).


Ris. 8.1.

Asynkron modell var den huvudsakliga I/O-modellen i operativsystem som DEC RT-11, DEC RSX-11, VAX/VMS, OpenVMS. Nästan alla stöder denna modell i en eller annan form. OS i realtid. Unix-system har använt flera inkompatibla API:er för asynkron I/O sedan slutet av 1980-talet. 1993 antog ANSI/IEEE POSIX 1003.1b, som beskriver ett standardiserat API som vi kommer att utforska senare i det här avsnittet.

I Solaris 10 ingår asynkron I/O-funktionalitet i biblioteket libaio.so. För att bygga program som använder dessa funktioner måste du använda -laio-växeln. För att generera förfrågningar om asynkron I/O används funktionerna aio_read(3AIO), aio_write(3AIO) och lio_listio(3AIO).

Funktionerna aio_read(3AIO) och aio_write(3AIO) har en enda parameter, structaiocb *aiocbp. Aiocb-strukturen definieras i filen< aio.h> och innehåller följande fält:

  • int aio_fildes - filbeskrivning
  • off_t aio_offset - offset i filen som börjar från vilken skrivning eller läsning börjar
  • volatile void* aio_buf - en buffert i vilken data ska läsas eller i vilken data som ska skrivas ligger.
  • size_t aio_nbytes - buffertstorlek. Liksom traditionell read(2) , kan aio_read(3AIO) läsa mindre data än vad som efterfrågades, men kommer aldrig att läsa mer.
  • int aio_reqprio - begära prioritet
  • struct sigevent aio_sigevent - metod för att meddela att en begäran har slutförts (diskuteras senare i detta avsnitt)
  • int aio_lio_opcode - används inte för aio_read(3AIO) och aio_write(3AIO), används endast av lio_listio-funktionen.

Funktionen lio_listio(3AIO) låter dig generera flera I/O-förfrågningar med ett systemanrop. Denna funktion har fyra parametrar:

  • int-läge - kan ta värdena LIO_WAIT (funktionen väntar på att alla förfrågningar ska slutföras) och LIO_NOWAIT (funktionen returnerar kontroll direkt efter att alla förfrågningar har genererats).
  • struct aiocb *lista - en lista med pekare till aiocb-strukturer med beskrivningar av förfrågningar.

    Förfrågningar kan antingen läsas eller skrivas, detta bestäms av fältet aio_lio_opcode. Förfrågningar till en enskild deskriptor exekveras i den ordning som de är listade i listarrayen.

  • int nent - antal poster i listmatrisen.
  • struct sigevent *sig - ett sätt att meddela att alla förfrågningar har slutförts. Om mode==LIO_WAIT ignoreras denna parameter.

POSIX AIO-biblioteket erbjuder två sätt att meddela ett program att en begäran har slutförts, synkront och asynkront. Låt oss först titta på den synkrona metoden. Funktionen aio_return(3AIO) returnerar status för begäran. Om begäran redan har slutförts och slutförts framgångsrikt, returnerar den storleken på data som lästs eller skrivits i byte. Liksom traditionell read(2), returnerar aio_return(3AIO) 0 byte vid slutet av filen. Om begäran misslyckades eller ännu inte har slutförts, returneras -1 och errno ställs in. Om begäran ännu inte har slutförts är felkoden EINPROGRESS.

Funktionen aio_return(3AIO) är destruktiv; om anropas på en avslutad begäran kommer den att förstöra systemobjektet som lagrar information om statusen för begäran. Att anropa aio_return(3AIO) flera gånger på samma begäran är därför inte möjligt.

Funktionen aio_error(3AIO) returnerar felkoden som är associerad med begäran. Om begäran slutförs framgångsrikt returneras 0, om ett fel uppstår - en felkod, för ofullständiga förfrågningar - EINPROGRESS.

Funktionen aio_suspend(3AIO) blockerar en tråd tills en av dess specificerade asynkrona I/O-begäranden slutförs eller under en specificerad tidsperiod. Denna funktion har tre parametrar:

  • const struct aiocb *const lista- en rad pekare till frågebeskrivningar.
  • int nent - antal element i listmatrisen.
  • const struct tidsspec *timeout- Timeout exakt till nanosekunder (i själva verket exakt till upplösning systemtimer).

Funktionen returnerar 0 om minst en av operationerna i listan har slutförts. Om funktionen misslyckas returnerar den -1 och ställer in errno. Om funktionen tog timeout, returnerar den också -1 och errno==EINPROGRESS .

Ett exempel på användning av asynkron I/O med synkron statuskontroll av begäran ges i exempel 8.3.

Const char req="GET / HTTP/1.0\r\n\r\n"; int main() ( int s; statisk struktur aiocb readrq; statisk struktur aiocb *readrqv=(&readrq, NULL); /* Öppna sockeln […] */ memset(&readrq, 0, storlek på readrq); readrq.aio_fildes=s ; readrq.aio_buf=buf; readrq.aio_nbytes=storlek på buf; if (aio_read(&readrq)) ( /* ... */ ) write(s, req, (sizeof req)-1); while(1) ( aio_suspend (readrqv , 1, NULL); size=aio_return(&readrq); if (storlek>0) (skriv(1, buf, storlek); aio_read(&readrq); ) else if (size==0) ( break; ) else if (errno!=EINPROGRESS) (perror("läser från socket"); ) ) ) 8.3. Asynkron I/O med synkron kontroll av förfrågningsstatus. Koden förkortas, uttagsöppning och felhantering är undantagna från den.

Asynkron avisering av en ansökan om slutförande av operationer består av signalgenerering när operationen är klar. För att göra detta måste du göra lämpliga inställningar i fältet aio_sigevent i begärandeskriptorn. Fältet aio_sigevent är av typen struct sigevent . Denna struktur definieras i och innehåller följande fält:

  • int sigev_notify - meddelandeläge. Giltiga värden är SIGEV_NONE (skicka inte bekräftelser), SIGEV_SIGNAL (generera en signal när begäran slutförs) och SIGEV_THREAD (kör den angivna funktionen i en separat tråd när begäran är klar). Solaris 10 stöder också varningstypen SIGEV_PORT, som diskuteras i bilagan till detta kapitel.
  • int sigev_signo - numret på signalen som kommer att genereras när SIGEV_SIGNAL används.
  • union sigval sigev_value - parameter som kommer att skickas till signalhanteraren eller bearbetningsfunktionen. När det används för asynkron I/O är detta vanligtvis en pekare till begäran.

    När du använder SIGEV_PORT bör detta vara en port_event_t-pekarstruktur som innehåller portnumret och eventuellt ytterligare data.

  • void (*sigev_notify_function)(union sigval)är den funktion som kommer att anropas när SIGEV_THREAD används.
  • pthread_attr_t *sigev_notify_attributes- attribut för tråden där den kommer att lanseras
  • sigev_notify_function när du använder SIGEV_THREAD .

Inte alla libaio-implementeringar stöder SIGEV_THREAD-meddelandet. Vissa Unix-system använder den icke-standardiserade SIGEV_CALLBACK-varningen istället. Senare i denna föreläsning kommer vi att diskutera endast signalavisering.

Vissa applikationer använder SIGIO eller SIGPOLL som signalnummer (i Unix SVR4 är dessa samma signal). SIGUSR1 eller SIGUSR2 används också ofta; Detta är bekvämt eftersom det säkerställer att en liknande signal inte kommer att uppstå av en annan anledning.

Realtidsapplikationer använder också signalnummer som sträcker sig från SIGRTMIN till SIGRTMAX. Vissa implementeringar tilldelar ett speciellt signalnummer SIGAIO eller SIGASYNCIO för detta ändamål, men det finns ingen sådan signal i Solaris 10.

Innan du utför asynkrona förfrågningar som meddelas av en signal bör du naturligtvis installera en hanterare för denna signal. För avisering måste du använda signaler som behandlas i SA_SIGINFO-läget. Det är inte möjligt att installera en sådan hanterare med hjälp av signal(2) och sigset(2) systemanrop, du måste använda sigaction(2) . Installera hanterare med hjälp av sigaction

I/O-kontroll.

blockorienterad enheter och byte-orienterad

huvudtanken

Nyckel principen är enhetsoberoende

· Avbryt hantering,

· Enhetsdrivrutiner,

Det verkar uppenbart att en mängd olika avbrott är möjliga av en mängd olika anledningar. Därför förknippas ett nummer med ett avbrott - det så kallade avbrottsnumret.

Detta nummer motsvarar unikt en viss händelse. Systemet kan känna igen avbrott och, när de inträffar, startar en procedur som motsvarar avbrottsnumret.

Vissa avbrott (de första fem i numerisk ordning) är reserverade för användning central processor i händelse av några speciella händelser som ett försök att dividera med noll, spill, etc. (dessa är sanna interna avbrott J).

Hårdvaruavbrott inträffar alltid asynkront med avseende på program som körs. Dessutom kan flera avbrott inträffa samtidigt!

För att säkerställa att systemet inte blir förvirrat när man bestämmer vilket avbrott som ska användas först, finns det ett speciellt prioritetssystem. Varje avbrott tilldelas sin egen prioritet. Om flera avbrott inträffar samtidigt ger systemet prioritet till den som har högst prioritet, vilket skjuter upp behandlingen av de återstående avbrotten ett tag.

Prioritetssystemet är implementerat på två Intel 8259 (eller liknande) chips. Varje chip är en avbrottskontroller och tjänar upp till åtta prioriteringar. Chips kan kombineras (kaskadkopplas) för att öka antalet prioritetsnivåer i systemet.

Prioritetsnivåerna förkortas IRQ0 - IRQ15.


24. I/O-kontroll. Synkron och asynkron I/O.

En av OS:s huvudfunktioner är att hantera alla datorns in-/utdataenheter. OS måste skicka kommandon till enheter, avbryta avbrott och hantera fel; den måste också tillhandahålla ett gränssnitt mellan enheterna och resten av systemet. För utvecklingsändamål bör gränssnittet vara detsamma för alla enhetstyper (enhetsoberoende). Mer information om IV-kontroll, fråga 23.

Skyddsprinciper

Sedan UNIX OS från allra första början var tänkt som ett fleranvändaroperativsystem, har problemet med att tillåta åtkomst för olika användare till filer i filsystemet alltid varit relevant. Med åtkomstbehörighet menar vi systemåtgärder som tillåter eller nekar åtkomst given användare Till den här filen beroende på användarens åtkomsträttigheter och åtkomstbegränsningar för filen. Åtkomstbehörighetsschemat som används i UNIX OS är så enkelt och bekvämt och samtidigt så kraftfullt att det har blivit de facto standarden för moderna operativsystem (som inte utger sig för att vara system med flernivåsäkerhet).

Filskydd

Som är vanligt i ett operativsystem med flera användare upprätthåller UNIX en enhetlig åtkomstkontrollmekanism för filer och filsystemkataloger. Alla processer kan komma åt en fil om och endast om de åtkomsträttigheter som anges för filen matchar processens möjligheter.

Att skydda filer från obehörig åtkomst i UNIX bygger på tre fakta. För det första är varje process som skapar en fil (eller katalog) associerad med någon användaridentifierare som är unik i systemet (UID - Användaridentifierare), vilket ytterligare kan tolkas som identifieraren för ägaren av den nyskapade filen. För det andra har varje process som försöker få åtkomst till en fil ett par identifierare kopplade till sig - den aktuella användar- och gruppidentifierare. För det tredje är varje fil unikt associerad med dess deskriptor - i-nod.

Det sista faktumet är värt att uppehålla sig vid mer i detalj. Det är viktigt att förstå att filnamn och filer som sådana inte är samma sak. I synnerhet när det finns flera hårda länkar till samma fil, representerar flera filnamn faktiskt samma fil och är associerade med samma i-nod. Varje i-nod som används i ett filsystem motsvarar alltid en och endast en fil. I-noden innehåller en hel del olika information (det mesta är tillgängligt för användare via stat- och fstat-systemanrop), och bland denna information finns en del som gör att filsystemet kan utvärdera rätten för en given process att få tillgång till en given fil i önskat läge.

Generella principer skydden är desamma för alla befintliga versioner av systemet: i-node-informationen inkluderar UID och GID för den nuvarande ägaren av filen (direkt efter att filen har skapats, ställs identifierarna för dess nuvarande ägare till motsvarande giltiga identifierare av skaparprocessen, men kan senare ändras av chown- och chgrp-systemanropen). Dessutom lagrar filens i-nod en skala som indikerar vad användaren - dess ägare - kan göra med filen, vad användare som tillhör samma användargrupp som ägaren kan göra med filen och vad andra kan göra med filen. användare. Små implementeringsdetaljer i olika alternativ systemen varierar.

28. Hantera åtkomst till filer i Windows NT. Listor över åtkomsträttigheter.

Åtkomstkontrollsystemet i Windows NT kännetecknas av en hög grad av flexibilitet, vilket uppnås på grund av den stora variationen av åtkomstämnen och objekt, såväl som granulariteten i åtkomstoperationer.

Filåtkomstkontroll

För delade resurser i Windows NT används en gemensam objektmodell, som innehåller sådana säkerhetsegenskaper som en uppsättning tillåtna operationer, en ägaridentifierare och en åtkomstkontrolllista.

Objekt i Windows NT skapas för alla resurser när de är eller blir delade - filer, kataloger, enheter, minnessektioner, processer. Egenskaperna för objekt i Windows NT är uppdelade i två delar - en allmän del, vars sammansättning inte beror på typen av objekt, och en individuell del, bestäms av typen av objekt.
Alla objekt lagras i trädstrukturer hierarkiska strukturer, vars element är grenobjekt (kataloger) och bladobjekt (filer). För filsystemobjekt är detta relationsschema en direkt återspegling av hierarkin av kataloger och filer. För objekt av andra typer har det hierarkiska relationsdiagrammet sitt eget innehåll, till exempel för processer återspeglar det förälder-barn-relationer, och för enheter återspeglar det medlemskap i en viss typ av enhet och enhetens anslutning till andra enheter, för till exempel en SCSI-kontroller med diskar.

Kontroll av åtkomsträttigheter för objekt av alla slag utförs centralt med hjälp av säkerhetsreferensövervakaren som körs i privilegierat läge.

För system Windows säkerhet NT kännetecknas av närvaron av ett stort antal olika fördefinierade (inbyggda) åtkomstämnen - både enskilda användare och grupper. Så systemet har alltid sådana användare som Adininistrator, System och Guest, såväl som grupper Users, Adiniiiistrators, Account Operators, Server Operators, Everyone och andra. Poängen med dessa inbyggda användare och grupper är att de är utrustade med vissa rättigheter, vilket gör det lättare för administratören att skapa ett effektivt system för åtkomstkontroll. När du lägger till en ny användare kan administratören bara bestämma vilken eller vilka grupper som denna användare ska tilldelas. Naturligtvis kan en administratör skapa nya grupper, samt lägga till rättigheter till inbyggda grupper för att implementera sin egen säkerhetspolicy, men i många fall räcker det med inbyggda grupper.

Windows NT stöder tre klasser av åtkomstoperationer, som skiljer sig åt i typen av ämnen och objekt som är involverade i dessa operationer.

□ Behörigheter är en uppsättning operationer som kan definieras för ämnen av alla typer i relation till objekt av vilken typ som helst: filer, kataloger, skrivare, minnessektioner etc. Behörigheter i deras syfte motsvarar åtkomsträttigheter till filer och kataloger i QC UNIX .

□ Rättigheter (användarrättigheter) - definieras för subjekt av grupptypen att utföra vissa systemoperationer: ställa in systemtiden, arkivera filer, stänga av datorn, etc. Dessa operationer involverar ett speciellt åtkomstobjekt - operativsystemet som helhet .

Det är i första hand rättigheter, inte behörigheter, som skiljer en inbyggd användargrupp från en annan. Vissa rättigheter för en inbyggd grupp är också inbyggda - de kan inte tas bort från denna grupp. Andra rättigheter för den inbyggda gruppen kan tas bort (eller läggas till från den allmänna listan över rättigheter).

□ Användarförmågor bestäms för individuella användare att utföra åtgärder relaterade till bildandet av deras operativa miljö, till exempel att ändra sammansättningen av huvudprogrammets meny, möjligheten att använda menyalternativet Kör, etc. Genom att minska uppsättningen av funktioner ( som är tillgängliga för användaren som standard), kan administratören tvinga användaren att arbeta med den operativmiljö som administratören anser är mest lämplig och skyddar användaren från eventuella fel.

Rättigheterna och behörigheterna som ges till en grupp ges automatiskt till dess medlemmar, vilket gör att administratören kan behandla ett stort antal användare som en enhet av redovisningsinformation och minimera deras handlingar.

När en användare loggar in i systemet skapas en så kallad åtkomsttoken för denne, som inkluderar användar-ID och ID:n för alla grupper som användaren tillhör. Token innehåller också: en standardåtkomstkontrolllista (ACL), som består av behörigheter och gäller objekt som skapats av processen; lista över användarrättigheter för att utföra systemåtgärder.

Alla objekt, inklusive filer, trådar, händelser, till och med åtkomsttokens, förses med en säkerhetsdeskriptor när de skapas. Säkerhetsbeskrivningen innehåller en åtkomstkontrolllista - ACL.

Filbeskrivning- ett icke-negativt heltal som tilldelas av operativsystemet till en fil som öppnas av processen.

ACL(Engelsk) Åtkomstkontrolllista- åtkomstkontrolllista, uttalas "ekl" på engelska) - bestämmer vem eller vilka som kan komma åt ett specifikt objekt, och vilka operationer som denna person är tillåten eller förbjuden att utföra på objektet.

Tillträdeskontrollistor är grunden för selektiva passerkontrollsystem. ( Wiki)

Ägaren av ett objekt, vanligtvis användaren som skapade det, har selektiv kontroll över åtkomst till objektet och kan ändra objektets ACL för att tillåta eller förhindra andra från att komma åt objektet. Inbyggt Windows administratör NT, till skillnad från UNIX-superanvändaren, kanske inte har vissa behörigheter för att komma åt ett objekt. För att implementera denna funktion kan administratörs- och administratörsgrupp-ID:n inkluderas i ACL, precis som vanliga användar-ID:n. Administratören har dock fortfarande möjlighet att utföra alla operationer med alla objekt, eftersom han alltid kan bli ägare till objektet och sedan, som ägare, få hela uppsättningen med behörigheter. Administratören kan dock inte återlämna äganderätten till objektets tidigare ägare, så användaren kan alltid få reda på att administratören har arbetat med sin fil eller skrivare.

När en process begär en operation för att komma åt ett objekt i Windows NT, övergår kontrollen alltid till säkerhetsmonitorn, som jämför användar- och användargruppsidentifierare från åtkomsttoken med identifierare som lagras i objektets ACL-element. Till skillnad från UNIX kan Windows NT ACL-element innehålla både listor över tillåtna och listor över operationer som är förbjudna för en användare.

Windows NT definierar tydligt reglerna för vilka en ACL tilldelas ett nyskapat objekt. Om anropskoden, när du skapar ett objekt, uttryckligen anger alla åtkomsträttigheter till det nyskapade objektet, tilldelar säkerhetssystemet denna ACL till objektet.

Om anropskoden inte förser objektet med en ACL, och objektet har ett namn, gäller principen om tillståndsarv. Säkerhetssystemet tittar på ACL för objektkatalogen där namnet på det nya objektet är lagrat. Vissa av ACL-posterna i objektkatalogen kan markeras som ärvbara. Detta innebär att de kan tilldelas nya objekt skapade i den här katalogen.

I fallet där en process inte uttryckligen har specificerat en ACL för objektet som skapas, och katalogobjektet inte har ärvbara ACL-poster, används standard-ACL från processens åtkomsttoken.


29. Java programmeringsspråk. Java Virtual Machine. Java-teknik.

Javaär ett objektorienterat programmeringsspråk utvecklat av Sun Microsystems. Java-applikationer kompileras vanligtvis till anpassad bytekod så att de kan köras på vilken virtuell Java-maskin som helst (JVM), oavsett datorarkitektur. Java-program översätts till bytekod som exekveras virtuell maskin Java ( JVM) - ett program som bearbetar bytekod och sänder instruktioner till utrustningen som tolk, men med skillnaden att bytekod, till skillnad från text, bearbetas mycket snabbare.

Fördelen med denna metod för att köra program är det fullständiga oberoendet av bytekoden från operativ system och hårdvara, så att du kan köra Java-applikationer på vilken enhet som helst för vilken en motsvarande virtuell maskin finns. En annan viktig egenskap hos Java-tekniken är dess flexibla säkerhetssystem på grund av det faktum att programexekveringen styrs helt av den virtuella maskinen. Alla åtgärder som överskrider programmets fastställda behörigheter (till exempel ett försök att obehörigt komma åt data eller ansluta till en annan dator) orsakar ett omedelbart avbrott.

Ofta inkluderar nackdelarna med konceptet med den virtuella maskinen det faktum att exekvering av bytekod av en virtuell maskin kan minska prestandan för program och algoritmer implementerade i Java-språket.

Java Virtual Machine(förkortat som Java VM, JVM) - den virtuella Java-maskinen är huvuddelen av Java-runtime-systemet, den så kallade Java Runtime Environment (JRE). Java Virtual Machine tolkar och exekverar Java-bytekod som är förgenererad från källkoden för ett Java-program av Java-kompilatorn (javac). JVM kan också användas för att köra program skrivna på andra programmeringsspråk. Till exempel kan Ada-källkoden kompileras till Java-bytekod, som sedan kan exekveras av JVM.

JVM är en nyckelkomponent i Java-plattformen. Eftersom virtuella Java-maskiner är tillgängliga för många hårdvara och mjukvaruplattformar, Java kan betraktas både som mellanprogram och som en plattform i sig, därav principen "skriv en gång, kör var som helst". Genom att använda en enda bytekod över flera plattformar kan Java beskrivas som "kompilera en gång, kör var som helst."

Runtime miljö

Program som är avsedda att köras på JVM måste kompileras i ett standardiserat portabelt binärt format, som vanligtvis representeras som .class-filer. Ett program kan bestå av många klasser som finns i olika filer. För att göra det enklare att vara värd för stora program kan vissa .class-filer paketeras ihop till en så kallad .jar-fil (förkortning av Java Archive).

JVM kör .class- eller .jar-filer genom att emulera instruktioner skrivna för JVM genom att tolka eller använda en just-in-time (JIT) kompilator som HotSpot från Sun microsystems. Idag används JIT-kompilering i de flesta JVM:er för att uppnå högre hastighet.

Liksom de flesta virtuella maskiner har Java Virtual Machine en stack-orienterad arkitektur som liknar mikrokontroller och mikroprocessorer.

JVM, som är en instans av JRE (Java Runtime Environment), kommer till spel när Java-program körs. När exekveringen är klar raderas den här instansen av sopsamlaren. JIT är en del av Java Virtual Machine som används för att påskynda exekveringstiden för applikationer. JIT kompilerar samtidigt delar av bytekoden som har liknande funktionalitet och minskar därför den tid som krävs för kompilering.

j2se (java 2 standardutgåva) – standardbiblioteket inkluderar:

GUI, NET, databas...


30. .NET-plattform. Huvudtankar och bestämmelser. .NET programmeringsspråk.

.NET Framework - mjukvaruteknik från Microsoft, designad för att skapa vanliga program och webbapplikationer.

En av huvudidéerna med Microsoft .NET är interoperabiliteten mellan olika tjänster skrivna på olika språk. Till exempel kan en tjänst skriven i C++ för Microsoft .NET anropa en klassmetod från ett bibliotek skrivet i Delphi; i C# kan du skriva en klass som ärvd från en klass skriven i Visual Basic.NET, och ett undantag från en metod skriven i C# kan fångas upp och hanteras i Delphi. Varje bibliotek (sammansättning) i .NET har information om dess version, vilket gör att du kan eliminera eventuella konflikter mellan olika versioner församlingar.

Applikationer kan också utvecklas i en textredigerare och använda en konsolkompilator.

Liksom Java-teknik skapar .NET-utvecklingsmiljön bytekod för exekvering av en virtuell maskin. Inmatningsspråket för denna maskin i .NET kallas MSIL (Microsoft Intermediate Language), eller CIL (Common Intermediate Language, en senare version), eller helt enkelt IL.

Användningen av bytekod låter dig uppnå plattformsoberoende funktionalitet på kompilerad projektnivå (i .NET-termer: hopsättning), och inte bara på källtextnivån, som t.ex. i C. Innan monteringen startas i CLR-körtiden, konverteras bytekoden av JIT-kompilatorn som är inbyggd i miljön (just in time, on-the-fly kompilering) i maskinkoder för målprocessorn. Det är också möjligt att kompilera sammansättningen till inbyggd kod för den valda plattformen med hjälp av NGen.exe-verktyget som medföljer .NET Framework.

Under översättningsproceduren konverteras källkoden för programmet (skriven i SML, C#, Visual Basic, C++ eller något annat programmeringsspråk som stöds av .NET) av kompilatorn till en så kallad assembly och sparas som en dynamisk länkad biblioteksfil (Dynamiskt länkad). Bibliotek, DLL) eller körbar fil(Körbar, EXE).

Naturligtvis, för varje kompilator (vare sig det är en C#-språkkompilator, csc.exe eller Visual Basic, vbc.exe), utför runtime-miljön den nödvändiga mappningen av de typer som används i CTS-typer och programkoden till koden för " abstrakt maskin” .NET - MSIL (Microsoft Intermediate Language).

Så småningom mjukvaruprojekt bildas i form av en sammansättning - en självförsörjande komponent för distribution, replikering och återanvändning. Monteringen är identifierad digital signatur författare och ett unikt versionsnummer.

Inbyggda programmeringsspråk (ingår i .NET Framework):

C#; J#; VB.NET; JScript .NET; C++/CLI - en ny version C++ (Managed).


31. Funktionella komponenter i operativsystemet. Filhantering

Funktionella OS-komponenter:

Funktionerna i en fristående dators operativsystem grupperas vanligtvis antingen enligt de typer av lokala resurser som operativsystemet hanterar eller enligt specifika uppgifter som gäller alla resurser. Ibland kallas sådana grupper av funktioner för delsystem. De viktigaste resurshanteringsundersystemen är process-, minnes-, fil- och externa enhetshanteringsundersystemen, och de delsystem som är gemensamma för alla resurser är undersystemen användargränssnitt, dataskydd och administration.

Filhantering:

OS:s förmåga att "skydda" komplexiteten hos verklig hårdvara manifesteras mycket tydligt i ett av de viktigaste OS-undersystemen - filsystemet.

Filsystemet länkar lagringsmedia på ena sidan och ett API (applikationsprogrammeringsgränssnitt) för åtkomst till filer på den andra. När ett applikationsprogram kommer åt en fil har det ingen aning om hur informationen i en viss fil finns, inte heller vilken typ av fysisk media (CD, hårddisk, magnetband eller flashminne) den är inspelad på. Allt programmet känner till är filnamnet, dess storlek och attribut. Den tar emot dessa data från filsystemdrivrutinen. Det är filsystemet som avgör var och hur filen ska skrivas på fysiska medier (till exempel en hårddisk).

Ur operativsystemets synvinkel är hela disken en samling kluster som varierar i storlek från 512 byte och större. Filsystemdrivrutiner organiserar kluster i filer och kataloger (som faktiskt är filer som innehåller en lista med filer i den katalogen). Samma drivrutiner håller reda på vilka kluster som för närvarande används, vilka som är gratis och vilka som är markerade som felaktiga.

Filsystemet är dock inte nödvändigtvis direkt kopplat till det fysiska lagringsmediet. Det finns virtuella filsystem, såväl som nätverksfilsystem, som bara är ett sätt att komma åt filer som finns på en fjärrdator.

I det enklaste fallet lagras alla filer på en given disk i en katalog. Detta ennivåschema användes i CP/M och den första versionen av MS-DOS 1.0. Det hierarkiska filsystemet med kapslade kataloger dök först upp i Multics, sedan i UNIX.

Kataloger för olika enheter kan bilda flera separata träd, som i DOS/Windows, eller slås samman till ett träd som är gemensamt för alla diskar, som i UNIX-liknande systemÅh.

Faktum är att i DOS/Windows-system, såväl som i UNIX-liknande system, finns det en rotkatalog med underkataloger som heter "c:", "d:", etc. Hårddiskpartitioner är monterade i dessa kataloger. Det vill säga, c:\ är bara en länk till file:///c:/. Men till skillnad från UNIX-liknande filsystem är det i Windows förbjudet att skriva till rotkatalogen, liksom att se dess innehåll.

I UNIX finns det bara en rotkatalog, och alla andra filer och kataloger är kapslade under den. För att komma åt filer och kataloger på en disk måste du montera disken med kommandot mount. Till exempel, för att öppna filer på en CD, måste du enkelt säga till operativsystemet: "ta filsystemet på denna CD och visa det i /mnt/cdrom-katalogen." Alla filer och kataloger som finns på CD:n kommer att visas i denna /mnt/cdrom-katalog, som kallas monteringspunkten. På de flesta UNIX-liknande system flyttbara diskar(disketter och CD-skivor), flash-enheter och andra externa lagringsenheter är monterade i katalogen /mnt, /mount eller /media. Unix- och UNIX-liknande operativsystem tillåter också att diskar monteras automatiskt när operativsystemet startar.

Observera användningen av snedstreck i filen Windows-system, UNIX- och UNIX-liknande operativsystem (i Windows används omvänt snedstreck "\" och i UNIX- och UNIX-liknande operativsystem ett enkelt snedstreck "/")

Dessutom bör det noteras att systemet ovan låter dig montera inte bara filsystemen för fysiska enheter, utan även individuella kataloger (parametern --bind) eller t.ex. ISO-bild(loopalternativ). Tillägg som FUSE låter dig även montera till exempel en hel katalog på FTP och ett väldigt stort antal olika resurser.

En ännu mer komplex struktur används i NTFS och HFS. I dessa filsystem varje fil är en uppsättning attribut. Attribut inkluderar inte bara det traditionella skrivskyddade systemet, utan även filnamn, storlek och till och med innehåll. Så för NTFS och HFS är det som lagras i en fil bara ett av dess attribut.

Enligt denna logik kan en fil innehålla flera varianter av innehåll. Således kan flera versioner av samma dokument lagras i en fil, såväl som ytterligare data (filikon, program som är associerat med filen). Denna organisation är typisk för HFS på Macintosh.


32. Funktionella komponenter i operativsystemet. Processledning.

Processhantering:

Den viktigaste delen av operativsystemet, som direkt påverkar datorns funktion, är undersystemet för processkontroll. En process (eller med andra ord en uppgift) är en abstraktion som beskriver ett pågående program. För operativsystemet är en process en arbetsenhet, en begäran om att konsumera systemresurser.

I ett multitasking-system (multiprocess) kan en process vara i ett av tre huvudtillstånd:

RUNNING - det aktiva tillståndet för en process, under vilken processen har alla nödvändiga resurser och exekveras direkt av processorn;

VÄNTAR - det passiva tillståndet för en process, processen är blockerad, den kan inte exekveras av sina egna interna skäl, den väntar på att någon händelse ska inträffa, till exempel slutförandet av en I/O-operation, ta emot ett meddelande från en annan process, eller frigörandet av någon resurs som den behöver;

READY är också ett passivt tillstånd för processen, men i det här fallet är processen blockerad på grund av omständigheter utanför den: processen har alla resurser som krävs för den, den är redo att köras, men processorn är upptagen med att exekvera en annan process.

Under livscykel varje process går från ett tillstånd till ett annat i enlighet med processschemaläggningsalgoritmen implementerad i ett givet operativsystem.

CP/M standard

Skapandet av operativsystem för mikrodatorer började med OS SR/M. Den utvecklades 1974, varefter den installerades på många 8-bitarsmaskiner. Inom ramen för detta operativsystem skapades en betydande mängd programvara, inklusive översättare från BASIC, Pascal, C, Fortran, Cobol, Lisp, Ada och många andra, textspråk. De låter dig förbereda dokument mycket snabbare och mer bekvämt än att använda en skrivmaskin.

MSX standard

Denna standard bestämde inte bara operativsystemet utan också egenskaperna hos hårdvara för skoldatorer. Enligt MSX-standarden var bilen tvungen att ha Bagge en volym på minst 16 K, ett permanent minne på 32 K med en inbyggd BASIC-språktolk, en grafisk färgskärm med en upplösning på 256x192 pixlar och 16 färger, en trekanalig 8-oktavs ljudgenerator, en parallellport för att ansluta en skrivare och en styrenhet för att styra en extern enhet ansluten externt.

Operativsystemet för en sådan maskin måste ha följande egenskaper: erforderligt minne - inte mer än 16 K, kompatibilitet med CP/M på nivån för systemanrop, kompatibilitet med DOS i filformat på externa enheter baserad på disketter, stöd för översättare av språken BASIC, C, Fortran och Lisp.

Pi - system

Under den inledande utvecklingsperioden personliga datorer Operativsystemet USCD p-system skapades. Grunden för detta system var den så kallade P-maskinen - ett program som emulerar en hypotetisk universal dator. P-maskinen simulerar driften av processorn, minnet och externa enheter genom att exekvera speciella instruktioner som kallas P-kod. Programvarukomponenter Pi-system (inklusive kompilatorer) kompileras i P-kod, även applikationsprogram kompileras till P-kod. Alltså det huvudsakliga särdrag Systemet var minimalt beroende av funktionerna i PC-utrustning. Detta är vad som säkerställde portabiliteten av Pi-systemet till Olika typer bilar P-kodens kompakthet och den bekvämt implementerade personsökningsmekanismen gjorde det möjligt att köra relativt stora program på datorer med litet RAM-minne.

I/O-kontroll.

I/O-enheter är indelade i två typer: blockorienterad enheter och byte-orienterad enheter. Blockorienterade enheter lagrar information i block med fast storlek, som vart och ett har sin egen adress. Den vanligaste blockorienterade enheten är en disk. Byte-orienterade enheter är inte adresserbara och tillåter inte sökoperationer; de genererar eller förbrukar en sekvens av byte. Exempel är terminaler, linjeskrivare, nätverkskort. Den elektroniska komponenten kallas en enhetskontroller eller adapter. Operativsystemet hanterar styrenheten. Regulatorn utför enkla funktioner, övervakar och korrigerar fel. Varje styrenhet har flera register som används för att kommunicera med den centrala processorn. OS utför I/O genom att skriva kommandon till styrenhetens register. IBM PC-diskettkontrollern accepterar 15 kommandon som LÄS, SKRIV, SÖK, FORMATERA, etc. När kommandot accepteras lämnar processorn kontrollenheten och utför annat arbete. När kommandot är slutfört utfärdar styrenheten ett avbrott för att överföra kontrollen av processorn till operativsystemet, som måste kontrollera resultatet av operationen. Processorn erhåller anordningens resultat och status genom att läsa information från styrenhetens register.

huvudtanken organisation av I/O-mjukvara består i att dela upp den i flera nivåer, och de nedre nivåerna skyddar utrustningens egenskaper från de övre, och de ger användarvänligt gränssnitt för användare.

Nyckel principen är enhetsoberoende. Typen av program bör inte bero på om det läser data från en diskett eller från hårddisk. En annan viktig fråga för I/O-programvara är felhantering. Generellt sett bör fel hanteras så nära hårdvaran som möjligt. Om styrenheten upptäcker ett läsfel måste den försöka rätta till det. Om det misslyckas måste drivrutinen åtgärda felen. Och endast om den lägre nivån inte kan hantera felet, rapporterar den felet till den övre nivån.

En annan nyckelfråga är användningen av blockerande (synkrona) och icke-blockerande (asynkrona) överföringar. De flesta fysiska I/O-operationer utförs asynkront - processorn startar en överföring och går vidare till annat arbete tills ett avbrott inträffar. Det är nödvändigt att I/O-operationer är blockerande - efter READ-kommandot pausar programmet automatiskt tills data når programbufferten.

Det sista problemet är att vissa enheter är delade (diskar: flera användare som kommer åt disken samtidigt är inget problem), medan andra är dedikerade (skrivare: rader som skrivs ut av olika användare kan inte blandas).

För att lösa dessa problem är det lämpligt att dela upp I/O-mjukvaran i fyra lager (Figur 2.30):

· Avbryt hantering,

· Drivrutiner,

· Enhetsoberoende lager av operativsystemet,

· Anpassat mjukvarulager.

Begreppet hårdvaruavbrott och dess bearbetning.

Asynkrona eller externa (hårdvaru)avbrott är händelser som kommer från externa källor (t.ex. kringutrustning) och kan inträffa när som helst: en signal från en timer, nätverkskort eller hårddisk, trycka på tangentbordet, flytta musen; De kräver omedelbar reaktion (bearbetning).

Nästan alla in-/utgångssystem i en dator fungerar med avbrott. Närmare bestämt, när du trycker på tangenter eller klickar på en mus, genererar hårdvaran avbrott. Som svar på dem läser systemet följaktligen koden för den nedtryckta tangenten eller kommer ihåg koordinaterna för muspekaren. Avbrott genereras av diskkontrollern, adaptern lokalt nätverk, seriella portar, ljudadapter och andra enheter.