logo

Inter Process Communication (IPC)

En proces kan være af to typer:

  • Uafhængig proces.
  • Samarbejdsproces.

En uafhængig proces påvirkes ikke af udførelsen af ​​andre processer, mens en samarbejdsproces kan blive påvirket af andre eksekverende processer. Selvom man kan tro, at disse processer, som kører uafhængigt, vil udføres meget effektivt, er der i virkeligheden mange situationer, hvor den samarbejdsvillige natur kan bruges til at øge beregningshastigheden, bekvemmeligheden og modulariteten. Inter-process communication (IPC) er en mekanisme, der tillader processer at kommunikere med hinanden og synkronisere deres handlinger. Kommunikationen mellem disse processer kan ses som en metode til samarbejde mellem dem. Processer kan kommunikere med hinanden gennem begge:



  1. Delt hukommelse
  2. Besked passerer

Figur 1 nedenfor viser en grundlæggende struktur for kommunikation mellem processer via metoden med delt hukommelse og via metoden med meddelelsesoverførsel.

Et operativsystem kan implementere begge kommunikationsmetoder. Først vil vi diskutere de fælles hukommelsesmetoder til kommunikation og derefter meddelelsesoverførsel. Kommunikation mellem processer, der bruger delt hukommelse, kræver, at processer deler en eller anden variabel, og det afhænger helt af, hvordan programmøren vil implementere det. En måde at kommunikere på ved hjælp af delt hukommelse kan forestilles sådan: Antag, at proces1 og proces2 udføres samtidigt, og de deler nogle ressourcer eller bruger information fra en anden proces. Process1 genererer information om bestemte beregninger eller ressourcer, der bruges, og opbevarer det som en registrering i delt hukommelse. Når proces2 skal bruge den delte information, tjekker den registreringen, der er gemt i delt hukommelse, og noterer den information, der genereres af proces1, og handler derefter. Processer kan bruge delt hukommelse til at udtrække information som en registrering fra en anden proces samt til at levere specifik information til andre processer.
Lad os diskutere et eksempel på kommunikation mellem processer ved hjælp af metoden med delt hukommelse.



i) Delt hukommelsesmetode

Eks: Producent-Forbruger problem
Der er to processer: producent og forbruger. Producenten producerer nogle varer, og forbrugeren forbruger denne vare. De to processer deler et fælles rum eller hukommelsesplacering kendt som en buffer, hvor varen produceret af producenten opbevares, og hvorfra forbrugeren forbruger varen, hvis det er nødvendigt. Der er to versioner af dette problem: den første er kendt som det ubegrænsede bufferproblem, hvor producenten kan fortsætte med at producere genstande, og der er ingen grænse for størrelsen af ​​bufferen, den anden er kendt som det afgrænsede bufferproblem i som Producenten kan producere op til et vist antal varer, før den begynder at vente på, at Forbrugeren skal forbruge den. Vi vil diskutere det afgrænsede bufferproblem. Først vil producenten og forbrugeren dele en fælles hukommelse, derefter vil producenten begynde at producere varer. Hvis den samlede producerede vare er lig med bufferens størrelse, vil producenten vente med at få den forbrugt af Forbrugeren. På samme måde vil forbrugeren først tjekke, om varen er tilgængelig. Hvis ingen vare er tilgængelig, vil forbrugeren vente på, at producenten producerer den. Hvis der er varer til rådighed, vil forbrugeren forbruge dem. Pseudokoden, der skal demonstreres, er angivet nedenfor:
Delte data mellem de to processer

C






#define buff_max 25> #define mod %> >struct> item{> >// different member of the produced data> >// or consumed data> >---------> >}> > >// An array is needed for holding the items.> >// This is the shared place which will be> >// access by both process> >// item shared_buff [ buff_max ];> > >// Two variables which will keep track of> >// the indexes of the items produced by producer> >// and consumer The free index points to> >// the next free index. The full index points to> >// the first full index.> >int> free_index = 0;> >int> full_index = 0;> >

>

>

Producers proceskode

C




item nextProduced;> > >while>(1){> > >// check if there is no space> >// for production.> >// if so keep waiting.> >while>((free_index+1) mod buff_max == full_index);> > >shared_buff[free_index] = nextProduced;> >free_index = (free_index + 1) mod buff_max;> >}>

>

>

Kode for forbrugerproces

C




item nextConsumed;> > >while>(1){> > >// check if there is an available> >// item for consumption.> >// if not keep on waiting for> >// get them produced.> >while>((free_index == full_index);> > >nextConsumed = shared_buff[full_index];> >full_index = (full_index + 1) mod buff_max;> >}>

>

>

I ovenstående kode vil producenten begynde at producere igen, når (free_index+1) mod buff max vil være gratis, fordi hvis det ikke er gratis, indebærer dette, at der stadig er varer, der kan forbruges af forbrugeren, så der er ikke behov for det. at producere mere. På samme måde, hvis gratis indeks og fuldt indeks peger på det samme indeks, betyder det, at der ikke er nogen varer at forbruge.

Samlet C++ implementering:

C++




#include> #include> #include> #include> #define buff_max 25> #define mod %> struct> item {> >// different member of the produced data> >// or consumed data> >// ---------> };> // An array is needed for holding the items.> // This is the shared place which will be> // access by both process> // item shared_buff[buff_max];> // Two variables which will keep track of> // the indexes of the items produced by producer> // and consumer The free index points to> // the next free index. The full index points to> // the first full index.> std::atomic<>int>>free_index(0);> std::atomic<>int>>fuld_indeks(0);> std::mutex mtx;> void> producer() {> >item new_item;> >while> (>true>) {> >// Produce the item> >// ...> >std::this_thread::sleep_for(std::chrono::milliseconds(100));> >// Add the item to the buffer> >while> (((free_index + 1) mod buff_max) == full_index) {> >// Buffer is full, wait for consumer> >std::this_thread::sleep_for(std::chrono::milliseconds(100));> >}> >mtx.lock();> >// Add the item to the buffer> >// shared_buff[free_index] = new_item;> >free_index = (free_index + 1) mod buff_max;> >mtx.unlock();> >}> }> void> consumer() {> >item consumed_item;> >while> (>true>) {> >while> (free_index == full_index) {> >// Buffer is empty, wait for producer> >std::this_thread::sleep_for(std::chrono::milliseconds(100));> >}> >mtx.lock();> >// Consume the item from the buffer> >// consumed_item = shared_buff[full_index];> >full_index = (full_index + 1) mod buff_max;> >mtx.unlock();> >// Consume the item> >// ...> >std::this_thread::sleep_for(std::chrono::milliseconds(100));> >}> }> int> main() {> >// Create producer and consumer threads> >std::vectorthread>tråde; threads.emplace_back(producer); threads.emplace_back(forbruger); // Vent på, at tråde slutter for (auto& tråd : tråde) { thread.join(); } returner 0; }>

>

>

Spids vinkel

Bemærk, at atomklassen bruges til at sikre, at de delte variable free_index og full_index opdateres atomisk. Mutex'en bruges til at beskytte den kritiske sektion, hvor der er adgang til den delte buffer. Sleep_for-funktionen bruges til at simulere produktion og forbrug af varer.

ii) Fremgangsmåde for meddelelser

Nu vil vi starte vores diskussion af kommunikationen mellem processer via meddelelsesoverførsel. I denne metode kommunikerer processer med hinanden uden at bruge nogen form for delt hukommelse. Hvis to processer p1 og p2 ønsker at kommunikere med hinanden, fortsætter de som følger:

  • Etabler et kommunikationslink (hvis et link allerede eksisterer, er det ikke nødvendigt at etablere det igen).
  • Begynd at udveksle beskeder ved hjælp af grundlæggende primitiver.
    Vi har brug for mindst to primitiver:
    sende (besked, destination) eller sende (besked)
    modtage (besked, vært) eller modtage (besked)

Meddelelsesstørrelsen kan være af fast størrelse eller variabel størrelse. Hvis det er af fast størrelse, er det nemt for en OS-designer, men kompliceret for en programmør, og hvis det er af variabel størrelse, er det nemt for en programmør, men kompliceret for OS-designeren. En standardmeddelelse kan have to dele: header og brødtekst.
Det header del bruges til lagring af meddelelsestype, destinations-id, kilde-id, meddelelseslængde og kontrolinformation. Kontrolinformationen indeholder information som f.eks. hvad man skal gøre, hvis der løber tør for bufferplads, sekvensnummer, prioritet. Generelt sendes besked ved hjælp af FIFO-stil.

Besked passerer gennem kommunikationslink.
Direkte og indirekte kommunikationslink
Nu vil vi starte vores diskussion om metoderne til implementering af kommunikationslinks. Mens du implementerer linket, er der nogle spørgsmål, der skal huskes som:

  1. Hvordan etableres links?
  2. Kan et link forbindes med mere end to processer?
  3. Hvor mange links kan der være mellem hvert par af kommunikationsprocesser?
  4. Hvad er kapaciteten af ​​et link? Er størrelsen på en besked, som linket kan rumme, fast eller variabel?
  5. Er et link ensrettet eller tovejs?

Et link har en vis kapacitet, der bestemmer antallet af meddelelser, der midlertidigt kan opholde sig i det, for hvilket hvert link har en kø tilknyttet sig, som kan have nul kapacitet, begrænset kapacitet eller ubegrænset kapacitet. I nul kapacitet venter afsender, indtil modtageren informerer afsenderen om, at den har modtaget beskeden. I tilfælde uden kapacitet ved en proces ikke, om en meddelelse er blevet modtaget eller ej efter afsendelsesoperationen. Til dette skal afsenderen kommunikere eksplicit med modtageren. Implementering af linket afhænger af situationen, det kan enten være et direkte kommunikationslink eller et indirekte kommunikationslink.
Direkte kommunikationslinks implementeres, når processerne bruger en specifik procesidentifikator til kommunikationen, men det er svært at identificere afsenderen på forhånd.
For eksempel printserveren.
Indirekte kommunikation sker via en delt postkasse (port), som består af en kø af beskeder. Afsenderen gemmer beskeden i postkassen, og modtageren henter dem.

Besked passerer gennem udveksling af meddelelser.

Synkron og asynkron meddelelsesoverførsel:
En proces, der er blokeret, er en proces, der venter på en hændelse, såsom en ressource, der bliver tilgængelig, eller færdiggørelsen af ​​en I/O-operation. IPC er mulig mellem processerne på samme computer såvel som på processerne, der kører på forskellige computere, dvs. i netværks/distribueret system. I begge tilfælde kan processen blokeres eller ikke, mens du sender en besked eller forsøger at modtage en besked, så videregivelse af beskeder kan være blokerende eller ikke-blokerende. Blokering overvejes synkron og blokerer afsendelse betyder, at afsenderen vil blive blokeret, indtil beskeden er modtaget af modtageren. Tilsvarende blokerer modtagelse har modtageren blokeret, indtil en besked er tilgængelig. Ikke-blokering overvejes asynkron og Ikke-blokerende send har afsenderen sender beskeden og fortsætter. På samme måde har ikke-blokerende modtagelse modtageren modtager en gyldig besked eller null. Efter en omhyggelig analyse kan vi nå frem til, at det for en afsender er mere naturligt at være ikke-blokerende efter besked passerer, da der kan være behov for at sende beskeden til forskellige processer. Afsenderen forventer dog en kvittering fra modtageren, hvis afsendelsen mislykkes. Tilsvarende er det mere naturligt for en modtager at blokere efter at have afgivet modtagelsen, da informationen fra den modtagne meddelelse kan bruges til yderligere eksekvering. På samme tid, hvis beskeden bliver ved med at mislykkes, bliver modtageren nødt til at vente på ubestemt tid. Derfor overvejer vi også den anden mulighed for at sende beskeder. Der er grundlæggende tre foretrukne kombinationer:

  • Blokering af send og blokering af modtagelse
  • Ikke-blokerende send og ikke-blokerende modtagelse
  • Ikke-blokerende send og blokerende modtagelse (mest brugt)

I Direkte besked passerer , Den proces, der ønsker at kommunikere, skal udtrykkeligt navngive modtageren eller afsenderen af ​​kommunikationen.
f.eks. send(p1, besked) betyder at sende beskeden til p1.
Tilsvarende modtage (p2, besked) betyder at modtage beskeden fra p2.
I denne kommunikationsmetode etableres kommunikationsforbindelsen automatisk, som enten kan være ensrettet eller tovejs, men en forbindelse kan bruges mellem et par afsender og modtager, og et par afsender og modtager bør ikke have mere end et par af afsender og modtagere. links. Symmetri og asymmetri mellem afsendelse og modtagelse kan også implementeres, dvs. enten vil begge processer navngive hinanden for at sende og modtage beskederne, eller kun afsenderen vil navngive modtageren for at sende beskeden, og der er ikke behov for, at modtageren navngiver afsenderen for at modtage beskeden. Problemet med denne kommunikationsmetode er, at hvis navnet på en proces ændres, vil denne metode ikke fungere.
I indirekte besked passerer , bruger processer postkasser (også kaldet porte) til at sende og modtage beskeder. Hver postkasse har et unikt id, og processer kan kun kommunikere, hvis de deler en postkasse. Link etableres kun, hvis processer deler en fælles postkasse, og et enkelt link kan knyttes til mange processer. Hvert par af processer kan dele flere kommunikationslinks, og disse links kan være ensrettet eller tovejs. Antag, at to processer ønsker at kommunikere gennem indirekte meddelelsesoverførsel, er de nødvendige handlinger: Opret en postkasse, brug denne postkasse til at sende og modtage meddelelser, og ødelæg derefter postkassen. De anvendte standardprimitiver er: Send en besked) hvilket betyder at sende beskeden til postkasse A. Det primitive for at modtage beskeden fungerer også på samme måde f.eks. modtaget (A, besked) . Der er et problem med denne postkasseimplementering. Antag, at der er mere end to processer, der deler den samme postkasse, og antag, at processen p1 sender en besked til postkassen, hvilken proces vil være modtageren? Dette kan løses ved enten at håndhæve, at kun to processer kan dele en enkelt postkasse eller håndhæve, at kun én proces har lov til at udføre modtagelsen på et givet tidspunkt eller vælge en hvilken som helst proces tilfældigt og underrette afsenderen om modtageren. En postkasse kan gøres privat for et enkelt afsender/modtager-par og kan også deles mellem flere afsender/modtager-par. Port er en implementering af en sådan postkasse, der kan have flere afsendere og en enkelt modtager. Det bruges i klient/server-applikationer (i dette tilfælde er serveren modtageren). Porten ejes af modtageprocessen og oprettes af OS på anmodning fra modtagerprocessen og kan enten ødelægges på anmodning fra den samme modtagerprocessor, når modtageren afslutter sig selv. Håndhævelse af, at kun én proces har tilladelse til at udføre modtagelsen, kan ske ved hjælp af konceptet gensidig udelukkelse. Mutex postkasse oprettes som deles af n proces. Afsenderen er ikke-blokerende og sender beskeden. Den første proces, der udfører modtagelsen, kommer ind i den kritiske sektion, og alle andre processer vil blokere og vente.
Lad os nu diskutere Producer-Consumer-problemet ved hjælp af budskabsoverførselskonceptet. Producenten placerer varer (inde i beskeder) i postkassen, og forbrugeren kan forbruge en vare, når der er mindst én besked i postkassen. Koden er angivet nedenfor:
Producer kode

C




void> Producer(>void>){> > >int> item;> >Message m;> > >while>(1){> > >receive(Consumer, &m);> >item = produce();> >build_message(&m , item ) ;> >send(Consumer, &m);> >}> >}>

>

>

Forbrugerkode

C




void> Consumer(>void>){> > >int> item;> >Message m;> > >while>(1){> > >receive(Producer, &m);> >item = extracted_item();> >send(Producer, &m);> >consume_item(item);> >}> >}>

>

>

Eksempler på IPC-systemer

  1. Posix: bruger delt hukommelsesmetode.
  2. Mach : bruger meddelelsesoverførsel
  3. Windows XP: bruger meddelelsesoverførsel ved hjælp af lokale procedurekald

Kommunikation i klient/serverarkitektur:
Der er forskellige mekanismer:

  • Rør
  • Stikkontakt
  • Remote Procedural Calls (RPC'er)

Ovenstående tre metoder vil blive diskuteret i senere artikler, da de alle er ret konceptuelle og fortjener deres egne separate artikler.
Referencer:

  1. Operativsystemkoncepter af Galvin et al.
  2. Lecture notes/ppt af Ariel J. Frank, Bar-Ilan University

Inter-process communication (IPC) er den mekanisme, hvorigennem processer eller tråde kan kommunikere og udveksle data med hinanden på en computer eller på tværs af et netværk. IPC er et vigtigt aspekt af moderne operativsystemer, da det gør det muligt for forskellige processer at arbejde sammen og dele ressourcer, hvilket fører til øget effektivitet og fleksibilitet.

Fordele ved IPC:

  1. Gør det muligt for processer at kommunikere med hinanden og dele ressourcer, hvilket fører til øget effektivitet og fleksibilitet.
  2. Letter koordinering mellem flere processer, hvilket fører til bedre overordnet systemydelse.
  3. Giver mulighed for oprettelse af distribuerede systemer, der kan spænde over flere computere eller netværk.
  4. Kan bruges til at implementere forskellige synkroniserings- og kommunikationsprotokoller, såsom semaforer, rør og sockets.

Ulemper ved IPC:

  1. Øger systemets kompleksitet, hvilket gør det sværere at designe, implementere og fejlfinde.
  2. Kan introducere sikkerhedssårbarheder, da processer muligvis kan få adgang til eller ændre data, der tilhører andre processer.
  3. Kræver omhyggelig styring af systemressourcer, såsom hukommelse og CPU-tid, for at sikre, at IPC-operationer ikke forringer systemets overordnede ydeevne.
    Kan føre til datainkonsistens, hvis flere processer forsøger at få adgang til eller ændre de samme data på samme tid.
  4. Samlet set opvejer fordelene ved IPC ulemperne, da det er en nødvendig mekanisme for moderne operativsystemer og gør det muligt for processer at arbejde sammen og dele ressourcer på en fleksibel og effektiv måde. Dog skal man sørge for at designe og implementere IPC-systemer omhyggeligt for at undgå potentielle sikkerhedssårbarheder og ydeevneproblemer.

Mere reference:
http://nptel.ac.in/courses/106108101/pdf/Lecture_Notes/Mod%207_LN.pdf
https://www.youtube.com/watch?v=lcRqHwIn5Dk