logo

Interprocescommunicatie (IPC)

Een proces kan uit twee typen bestaan:

  • Onafhankelijk proces.
  • Samenwerkend proces.

Een onafhankelijk proces wordt niet beïnvloed door de uitvoering van andere processen, terwijl een samenwerkend proces kan worden beïnvloed door andere uitvoerende processen. Hoewel je kunt denken dat deze processen, die onafhankelijk draaien, zeer efficiënt zullen worden uitgevoerd, zijn er in werkelijkheid veel situaties waarin de coöperatieve aard kan worden gebruikt om de rekensnelheid, het gemak en de modulariteit te vergroten. Inter-procescommunicatie (IPC) is een mechanisme waarmee processen met elkaar kunnen communiceren en hun acties kunnen synchroniseren. De communicatie tussen deze processen kan worden gezien als een manier van samenwerking tussen deze processen. Processen kunnen met elkaar communiceren via:



  1. Gedeelde herinnering
  2. Bericht overslaan

Figuur 1 hieronder toont een basisstructuur van de communicatie tussen processen via de gedeelde geheugenmethode en via de methode voor het doorgeven van berichten.

Een besturingssysteem kan beide communicatiemethoden implementeren. Eerst bespreken we de communicatiemethoden met gedeeld geheugen en vervolgens het doorgeven van berichten. Communicatie tussen processen die gebruik maken van gedeeld geheugen vereist dat processen een bepaalde variabele delen, en dit hangt volledig af van hoe de programmeur deze zal implementeren. Eén manier van communiceren met behulp van gedeeld geheugen kan als volgt worden voorgesteld: stel dat proces1 en proces2 tegelijkertijd worden uitgevoerd en dat ze bepaalde bronnen delen of informatie uit een ander proces gebruiken. Process1 genereert informatie over bepaalde berekeningen of bronnen die worden gebruikt en bewaart deze als een record in het gedeelde geheugen. Wanneer proces2 de gedeelde informatie moet gebruiken, zal het de record inchecken die is opgeslagen in het gedeelde geheugen, kennis nemen van de informatie die door proces1 wordt gegenereerd en dienovereenkomstig handelen. Processen kunnen gedeeld geheugen gebruiken voor het extraheren van informatie als record uit een ander proces en voor het leveren van specifieke informatie aan andere processen.
Laten we een voorbeeld bespreken van communicatie tussen processen met behulp van de gedeelde geheugenmethode.



i) Gedeelde geheugenmethode

Bijvoorbeeld: Producent-consumentprobleem
Er zijn twee processen: Producent en Consument. De producent produceert een aantal artikelen en de consument consumeert dat artikel. De twee processen delen een gemeenschappelijke ruimte of geheugenlocatie die bekend staat als een buffer, waar het door de Producent geproduceerde item wordt opgeslagen en van waaruit de Consument het item indien nodig consumeert. Er zijn twee versies van dit probleem: de eerste staat bekend als het onbegrensde bufferprobleem, waarbij de producent items kan blijven produceren en er geen limiet is aan de grootte van de buffer, de tweede staat bekend als het begrensde bufferprobleem. waarmee de Producent een bepaald aantal artikelen kan produceren voordat hij begint te wachten tot de Consument deze consumeert. We zullen het begrensde bufferprobleem bespreken. Eerst zullen de producent en de consument een gemeenschappelijk geheugen delen, daarna zal de producent artikelen gaan produceren. Als het totaal geproduceerde item gelijk is aan de omvang van de buffer, zal de producent wachten tot het door de consument wordt geconsumeerd. Op dezelfde manier zal de consument eerst controleren of het artikel beschikbaar is. Als er geen artikel beschikbaar is, wacht de consument tot de producent het produceert. Als er artikelen beschikbaar zijn, zal de consument deze consumeren. De pseudocode die moet worden gedemonstreerd, vindt u hieronder:
Gedeelde gegevens tussen de twee processen

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;> >

>

>

Procescode van de producent

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;> >}>

>

>

Consumentenprocescode

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;> >}>

>

>

In de bovenstaande code zal de Producent opnieuw beginnen met produceren wanneer de (free_index+1) mod buff max gratis zal zijn, want als deze niet gratis is, betekent dit dat er nog steeds items zijn die door de Consument kunnen worden geconsumeerd, dus dat is niet nodig om meer te produceren. Op dezelfde manier, als de vrije index en de volledige index naar dezelfde index verwijzen, betekent dit dat er geen items zijn om te consumeren.

Algemene C++-implementatie:

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>>vrije_index(0);> std::atomic<>int>>volledige_index(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>draden; threads.emplace_back(producent); threads.emplace_back(consument); // Wacht tot de threads klaar zijn voor (auto& thread: threads) { thread.join(); } retourneer 0; }>

>

>

Hoe kom ik erachter wat mijn monitorgrootte is?

Merk op dat de atomaire klasse wordt gebruikt om ervoor te zorgen dat de gedeelde variabelen free_index en full_index atomair worden bijgewerkt. De mutex wordt gebruikt om de kritieke sectie te beschermen waar toegang wordt verkregen tot de gedeelde buffer. De functie sleep_for wordt gebruikt om de productie en consumptie van artikelen te simuleren.

ii) Methode voor het doorgeven van berichten

Nu zullen we beginnen met onze bespreking van de communicatie tussen processen via het doorgeven van berichten. Bij deze methode communiceren processen met elkaar zonder gebruik te maken van enige vorm van gedeeld geheugen. Als twee processen p1 en p2 met elkaar willen communiceren, gaan ze als volgt te werk:

  • Breng een communicatieverbinding tot stand (als er al een verbinding bestaat, hoeft u deze niet opnieuw tot stand te brengen.)
  • Begin met het uitwisselen van berichten met behulp van basisprimitieven.
    We hebben minstens twee primitieven nodig:
    versturen (bericht, bestemming) of versturen (bericht)
    ontvangen (bericht, host) of ontvangen (bericht)

De berichtgrootte kan een vaste grootte of een variabele grootte hebben. Als het een vaste grootte heeft, is het gemakkelijk voor een OS-ontwerper, maar ingewikkeld voor een programmeur, en als het een variabele grootte heeft, is het gemakkelijk voor een programmeur, maar ingewikkeld voor de OS-ontwerper. Een standaardbericht kan uit twee delen bestaan: koptekst en body.
De kopgedeelte wordt gebruikt voor het opslaan van berichttype, bestemmings-ID, bron-ID, berichtlengte en besturingsinformatie. De besturingsinformatie bevat informatie zoals wat te doen als er onvoldoende bufferruimte is, volgnummer en prioriteit. Over het algemeen wordt een bericht verzonden in FIFO-stijl.

Bericht dat via de communicatielink passeert.
Directe en indirecte communicatielink
Nu zullen we onze discussie beginnen over de methoden voor het implementeren van communicatieverbindingen. Bij het implementeren van de link zijn er enkele vragen waarmee u rekening moet houden, zoals:

  1. Hoe komen koppelingen tot stand?
  2. Kan een koppeling aan meer dan twee processen worden gekoppeld?
  3. Hoeveel schakels kunnen er zijn tussen elk paar communicatieprocessen?
  4. Wat is de capaciteit van een link? Is de grootte van een bericht dat de link kan bevatten vast of variabel?
  5. Is een link unidirectioneel of bidirectioneel?

Een link heeft een bepaalde capaciteit die het aantal berichten bepaalt dat er tijdelijk in kan verblijven, waarvoor aan elke link een wachtrij is gekoppeld die een capaciteit van nul, een begrensde capaciteit of een onbegrensde capaciteit kan hebben. In nulcapaciteit wacht de zender totdat de ontvanger de zender laat weten dat hij het bericht heeft ontvangen. In gevallen waarbij de capaciteit niet nul is, weet een proces niet of een bericht is ontvangen of niet na de verzendbewerking. Hiervoor moet de zender expliciet met de ontvanger communiceren. De implementatie van de link is afhankelijk van de situatie. Het kan een directe communicatielink of een indirecte communicatielink zijn.
Directe communicatieverbindingen worden geïmplementeerd wanneer de processen een specifieke proces-ID voor de communicatie gebruiken, maar het moeilijk is om de afzender van tevoren te identificeren.
Bijvoorbeeld de printserver.
Indirecte communicatie gebeurt via een gedeelde mailbox (poort), die bestaat uit een wachtrij met berichten. De afzender bewaart het bericht in de mailbox en de ontvanger haalt het op.

Bericht dat doorkomt en de berichten uitwisselt.

Synchrone en asynchrone berichtoverdracht:
Een proces dat wordt geblokkeerd, is een proces dat wacht op een bepaalde gebeurtenis, zoals het beschikbaar komen van een bron of de voltooiing van een I/O-bewerking. IPC is mogelijk tussen de processen op dezelfde computer, maar ook tussen de processen die op verschillende computers draaien, dat wil zeggen in een netwerk/gedistribueerd systeem. In beide gevallen kan het proces wel of niet worden geblokkeerd tijdens het verzenden van een bericht of het proberen een bericht te ontvangen, zodat het doorgeven van berichten blokkerend of niet-blokkerend kan zijn. Blokkeren wordt overwogen synchroon En verzenden blokkeren betekent dat de afzender wordt geblokkeerd totdat het bericht door de ontvanger is ontvangen. Op dezelfde manier, ontvangst blokkeren heeft het ontvangerblok totdat er een bericht beschikbaar is. Er wordt rekening gehouden met niet-blokkering asynchroon en bij Niet-blokkerend verzenden verzendt de afzender het bericht en gaat verder. Op dezelfde manier zorgt niet-blokkerende ontvangst ervoor dat de ontvanger een geldig bericht of nul ontvangt. Na een zorgvuldige analyse kunnen we tot de conclusie komen dat het voor een afzender natuurlijker is om niet-blokkerend te zijn nadat het bericht is doorgegeven, omdat het nodig kan zijn om het bericht naar verschillende processen te sturen. De afzender verwacht echter een bevestiging van de ontvanger voor het geval de verzending mislukt. Op soortgelijke wijze is het natuurlijker dat een ontvanger blokkeert nadat hij de ontvangst heeft verzonden, omdat de informatie uit het ontvangen bericht kan worden gebruikt voor verdere uitvoering. Tegelijkertijd zal de ontvanger, als het verzenden van het bericht blijft mislukken, voor onbepaalde tijd moeten wachten. Daarom overwegen we ook de andere mogelijkheid van het doorgeven van berichten. Er zijn grofweg drie voorkeurscombinaties:

  • Verzenden blokkeren en ontvangen blokkeren
  • Niet-blokkerend verzenden en niet-blokkerend ontvangen
  • Niet-blokkerend verzenden en blokkerend ontvangen (meestal gebruikt)

Bij het doorgeven van directe berichten Het proces dat wil communiceren, moet expliciet de ontvanger of afzender van de communicatie noemen.
bijv. verzenden(p1, bericht) betekent dat u het bericht naar p1 stuurt.
Op dezelfde manier, ontvangen(p2, bericht) betekent om het bericht van p2 te ontvangen.
Bij deze communicatiemethode wordt de communicatieverbinding automatisch tot stand gebracht, wat unidirectioneel of bidirectioneel kan zijn, maar één verbinding kan worden gebruikt tussen één paar zender en ontvanger en één paar zender en ontvanger mag niet meer dan één paar hebben. koppelingen. Symmetrie en asymmetrie tussen zenden en ontvangen kan ook worden geïmplementeerd, d.w.z. beide processen zullen elkaar een naam geven voor het verzenden en ontvangen van de berichten, of alleen de afzender zal de ontvanger een naam geven voor het verzenden van het bericht en het is niet nodig dat de ontvanger de afzender een naam geeft. ontvangst van het bericht. Het probleem met deze communicatiemethode is dat als de naam van één proces verandert, deze methode niet zal werken.
Bij het doorgeven van indirecte berichten gebruiken processen mailboxen (ook wel poorten genoemd) voor het verzenden en ontvangen van berichten. Elke mailbox heeft een unieke ID en processen kunnen alleen communiceren als ze een mailbox delen. Er wordt alleen een koppeling tot stand gebracht als processen een gemeenschappelijke mailbox delen en een enkele koppeling aan veel processen kan worden gekoppeld. Elk paar processen kan meerdere communicatieverbindingen delen en deze verbindingen kunnen unidirectioneel of bidirectioneel zijn. Stel dat twee processen willen communiceren via het indirect doorgeven van berichten, dan zijn de vereiste handelingen: een mailbox aanmaken, deze mailbox gebruiken voor het verzenden en ontvangen van berichten en vervolgens de mailbox vernietigen. De standaard gebruikte primitieven zijn: stuur een bericht) wat betekent dat het bericht naar mailbox A moet worden verzonden. De primitief voor het ontvangen van het bericht werkt ook op dezelfde manier, b.v. ontvangen (A, bericht) . Er is een probleem met deze mailboximplementatie. Stel dat er meer dan twee processen zijn die dezelfde mailbox delen en stel dat het proces p1 een bericht naar de mailbox stuurt, welk proces zal dan de ontvanger zijn? Dit kan worden opgelost door af te dwingen dat slechts twee processen één mailbox kunnen delen, of door af te dwingen dat slechts één proces de ontvangst op een bepaald tijdstip mag uitvoeren, of door willekeurig een proces te selecteren en de afzender op de hoogte te stellen van de ontvanger. Een mailbox kan privé worden gemaakt voor één enkel zender/ontvanger-paar, maar kan ook worden gedeeld tussen meerdere zender/ontvanger-paren. Port is een implementatie van een dergelijke mailbox die meerdere afzenders en één enkele ontvanger kan hebben. Het wordt gebruikt in client/server-toepassingen (in dit geval is de server de ontvanger). De poort is eigendom van het ontvangende proces en is door OS aangemaakt op verzoek van het ontvangerproces en kan op verzoek van dezelfde ontvangerprocessor worden vernietigd wanneer de ontvanger zichzelf beëindigt. Het afdwingen dat slechts één proces de ontvangst mag uitvoeren, kan worden gedaan met behulp van het concept van wederzijdse uitsluiting. Mutex-mailbox wordt gemaakt en wordt gedeeld door n proces. De afzender is non-blocking en verzendt het bericht. Het eerste proces dat de ontvangst uitvoert, komt in de kritieke sectie terecht en alle andere processen blokkeren en wachten.
Laten we nu het producent-consumentprobleem bespreken met behulp van het concept voor het doorgeven van berichten. De producent plaatst artikelen (in berichten) in de brievenbus en de consument kan een artikel consumeren wanneer er minimaal één bericht in de brievenbus aanwezig is. De code staat hieronder:
Producentcode

C




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

>

>

Consumentencode

C




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

>

>

Voorbeelden van IPC-systemen

  1. Posix: maakt gebruik van de gedeelde geheugenmethode.
  2. Mach: gebruikt het doorgeven van berichten
  3. Windows XP: maakt gebruik van het doorgeven van berichten via lokale procedurele oproepen

Communicatie in client/server-architectuur:
Er zijn verschillende mechanismen:

  • Pijp
  • Stopcontact
  • Procedurele oproepen op afstand (RPC's)

De bovengenoemde drie methoden zullen in latere artikelen worden besproken, omdat ze allemaal behoorlijk conceptueel zijn en hun eigen afzonderlijke artikelen verdienen.
Referenties:

  1. Besturingssysteemconcepten door Galvin et al.
  2. Lezingsaantekeningen/ppt van Ariel J. Frank, Bar-Ilan University

Inter-procescommunicatie (IPC) is het mechanisme waarmee processen of threads met elkaar kunnen communiceren en gegevens kunnen uitwisselen op een computer of via een netwerk. IPC is een belangrijk aspect van moderne besturingssystemen, omdat het verschillende processen in staat stelt samen te werken en bronnen te delen, wat leidt tot verhoogde efficiëntie en flexibiliteit.

Voordelen van IPC:

  1. Zorgt ervoor dat processen met elkaar kunnen communiceren en middelen kunnen delen, wat leidt tot verhoogde efficiëntie en flexibiliteit.
  2. Vergemakkelijkt de coördinatie tussen meerdere processen, wat leidt tot betere algehele systeemprestaties.
  3. Maakt het mogelijk gedistribueerde systemen te creëren die meerdere computers of netwerken kunnen omvatten.
  4. Kan worden gebruikt om verschillende synchronisatie- en communicatieprotocollen te implementeren, zoals semaforen, pijpen en sockets.

Nadelen van IPC:

  1. Verhoogt de systeemcomplexiteit, waardoor het moeilijker wordt om te ontwerpen, implementeren en debuggen.
  2. Kan beveiligingsproblemen introduceren, omdat processen mogelijk toegang kunnen krijgen tot gegevens van andere processen of deze kunnen wijzigen.
  3. Vereist zorgvuldig beheer van systeembronnen, zoals geheugen en CPU-tijd, om ervoor te zorgen dat IPC-bewerkingen de algehele systeemprestaties niet verslechteren.
    Kan leiden tot gegevensinconsistenties als meerdere processen tegelijkertijd toegang proberen te krijgen tot dezelfde gegevens of deze willen wijzigen.
  4. Over het geheel genomen wegen de voordelen van IPC zwaarder dan de nadelen, omdat het een noodzakelijk mechanisme is voor moderne besturingssystemen en het mogelijk maakt dat processen op een flexibele en efficiënte manier samenwerken en bronnen delen. Er moet echter op worden gelet dat IPC-systemen zorgvuldig worden ontworpen en geïmplementeerd om potentiële beveiligingsproblemen en prestatieproblemen te voorkomen.

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