logo

Meziprocesová komunikace (IPC)

Proces může být dvou typů:

  • Nezávislý proces.
  • Proces spolupráce.

Nezávislý proces není ovlivněn prováděním jiných procesů, zatímco spolupracující proces může být ovlivněn jinými prováděcími procesy. I když si lze myslet, že tyto procesy, které běží nezávisle, budou probíhat velmi efektivně, ve skutečnosti existuje mnoho situací, kdy lze kooperativní povahu využít ke zvýšení výpočetní rychlosti, pohodlí a modularity. Meziprocesová komunikace (IPC) je mechanismus, který umožňuje procesům vzájemně komunikovat a synchronizovat své akce. Komunikaci mezi těmito procesy lze vnímat jako způsob spolupráce mezi nimi. Procesy spolu mohou komunikovat prostřednictvím obou:



  1. Sdílená paměť
  2. Předávání zpráv

Obrázek 1 níže ukazuje základní strukturu komunikace mezi procesy prostřednictvím metody sdílené paměti a prostřednictvím metody předávání zpráv.

Operační systém může implementovat oba způsoby komunikace. Nejprve probereme způsoby komunikace se sdílenou pamětí a poté předávání zpráv. Komunikace mezi procesy pomocí sdílené paměti vyžaduje, aby procesy sdílely nějakou proměnnou a zcela záleží na tom, jak to programátor implementuje. Jeden způsob komunikace využívající sdílenou paměť si lze představit takto: Předpokládejme, že proces1 a proces2 se provádějí současně a sdílejí některé zdroje nebo používají některé informace z jiného procesu. Process1 generuje informace o určitých používaných výpočtech nebo zdrojích a uchovává je jako záznam ve sdílené paměti. Když proces2 potřebuje sdílené informace použít, zkontroluje záznam uložený ve sdílené paměti a vezme si na vědomí informace generované procesem1 a podle toho bude jednat. Procesy mohou využívat sdílenou paměť pro extrakci informací jako záznam z jiného procesu, stejně jako pro dodání jakýchkoli specifických informací jiným procesům.
Pojďme diskutovat o příkladu komunikace mezi procesy pomocí metody sdílené paměti.



i) Metoda sdílené paměti

Příklad: Problém výrobce-spotřebitel
Existují dva procesy: výrobce a spotřebitel. Výrobce vyrábí nějaké položky a spotřebitel je spotřebuje. Tyto dva procesy sdílejí společný prostor nebo paměťové místo známé jako vyrovnávací paměť, kde je uložena položka vyrobená výrobcem a ze které spotřebitel v případě potřeby položku spotřebuje. Existují dvě verze tohoto problému: první je známá jako problém s neomezenou vyrovnávací pamětí, ve kterém může Producent pokračovat ve výrobě položek a neexistuje žádné omezení velikosti vyrovnávací paměti, druhá je známá jako problém s omezenou vyrovnávací pamětí v které může výrobce vyrobit až do určitého počtu položek, než začne čekat na to, až je spotřebitel spotřebuje. Budeme diskutovat o problému omezené vyrovnávací paměti. Nejprve si výrobce a spotřebitel vydají společnou paměť, poté výrobce začne vyrábět položky. Pokud se celková vyrobená položka rovná velikosti vyrovnávací paměti, výrobce počká, až ji spotřebitel spotřebuje. Podobně si spotřebitel nejprve ověří dostupnost zboží. Pokud není k dispozici žádná položka, Spotřebitel počká, až ji Výrobce vyrobí. Pokud jsou položky k dispozici, spotřebitel je spotřebuje. Pseudokód k demonstraci je uveden níže:
Sdílená data mezi dvěma procesy

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

>

>

Procesní kód výrobce

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

>

>

Kodex spotřebitelského procesu

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

>

>

Ve výše uvedeném kódu výrobce začne znovu vyrábět, jakmile bude (free_index+1) mod buff max zdarma, protože pokud není zdarma, znamená to, že stále existují položky, které může spotřebitel spotřebovat, takže není potřeba. vyrábět více. Podobně, pokud volný index a úplný index ukazují na stejný index, znamená to, že neexistují žádné položky ke konzumaci.

Celková implementace C++:

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>>full_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>vlákna; threads.emplace_back(producer); threads.emplace_back(consumer); // Počkejte na dokončení vláken pro (auto& vlákno : vlákna) { thread.join(); } návrat 0; }>

>

>

číslo 'euler' v jazyce Java'

Všimněte si, že atomická třída se používá k zajištění toho, že sdílené proměnné free_index a full_index jsou aktualizovány atomicky. Mutex se používá k ochraně kritické sekce, kde je přístup ke sdílené vyrovnávací paměti. Funkce sleep_for se používá k simulaci výroby a spotřeby položek.

ii) Metoda předávání zpráv

Nyní zahájíme diskusi o komunikaci mezi procesy prostřednictvím předávání zpráv. Při této metodě spolu procesy komunikují bez použití jakéhokoli druhu sdílené paměti. Pokud spolu chtějí komunikovat dva procesy p1 a p2, postupují následovně:

  • Vytvořte komunikační spojení (pokud již propojení existuje, není třeba jej znovu navazovat.)
  • Začněte si vyměňovat zprávy pomocí základních primitiv.
    Potřebujeme alespoň dvě primitiva:
    poslat (zpráva, cíl) popř poslat (zpráva)
    dostávat (zpráva, hostitel) popř dostávat (zpráva)

Velikost zprávy může být pevné velikosti nebo proměnné velikosti. Pokud má pevnou velikost, je to snadné pro návrháře OS, ale komplikované pro programátora, a pokud má proměnnou velikost, je to snadné pro programátora, ale komplikované pro návrháře OS. Standardní zpráva může mít dvě části: hlavička a tělo.
The hlavičkový díl se používá pro uložení typu zprávy, id cíle, id zdroje, délky zprávy a řídicích informací. Řídicí informace obsahují informace jako co dělat, když dojde místo ve vyrovnávací paměti, pořadové číslo, priorita. Obecně je zpráva odesílána pomocí stylu FIFO.

Zpráva procházející komunikační linkou.
Přímé a nepřímé komunikační spojení
Nyní zahájíme diskusi o metodách implementace komunikačních spojení. Při implementaci odkazu je třeba mít na paměti několik otázek, jako například:

  1. Jak se vytvářejí odkazy?
  2. Může být odkaz spojen s více než dvěma procesy?
  3. Kolik vazeb může být mezi každou dvojicí komunikujících procesů?
  4. Jaká je kapacita odkazu? Je velikost zprávy, kterou odkaz pojme, pevná nebo proměnná?
  5. Je odkaz jednosměrný nebo obousměrný?

Spojení má určitou kapacitu, která určuje počet zpráv, které se v něm mohou dočasně nacházet, přičemž ke každému spoji je přiřazena fronta, která může mít nulovou kapacitu, omezenou kapacitu nebo neomezenou kapacitu. Při nulové kapacitě odesílatel čeká, dokud příjemce neoznámí odesílateli, že zprávu přijal. V případech s nenulovou kapacitou proces po operaci odeslání neví, zda byla zpráva přijata či nikoli. K tomu musí odesílatel komunikovat s příjemcem explicitně. Realizace spoje závisí na situaci, může se jednat buď o přímý komunikační spoj, nebo neřízený komunikační spoj.
Přímé komunikační odkazy jsou implementovány, když procesy používají pro komunikaci specifický identifikátor procesu, ale je těžké identifikovat odesílatele předem.
Například tiskový server.
Nepřímá komunikace se provádí přes sdílenou schránku (port), kterou tvoří fronta zpráv. Odesílatel si zprávu ponechá ve schránce a příjemce si ji vyzvedne.

Zpráva procházející výměnou zpráv.

Synchronní a asynchronní předávání zpráv:
Blokovaný proces je proces, který čeká na nějakou událost, jako je zpřístupnění zdroje nebo dokončení I/O operace. IPC je možné mezi procesy na stejném počítači i na procesech běžících na jiném počítači, tj. v síťovém/distribuovaném systému. V obou případech může nebo nemusí být proces zablokován při odesílání zprávy nebo při pokusu o přijetí zprávy, takže předávání zprávy může být blokující nebo neblokující. Uvažuje se o blokování synchronní a blokování odeslání znamená, že odesílatel bude zablokován, dokud nebude zpráva přijata příjemcem. Podobně, blokování příjmu má přijímač zablokovat, dokud není k dispozici zpráva. Zvažuje se neblokování asynchronní a Neblokující odeslání znamená, že odesílatel odešle zprávu a bude pokračovat. Podobně neblokující příjem způsobí, že příjemce obdrží platnou zprávu nebo hodnotu null. Po pečlivé analýze můžeme dospět k závěru, že pro odesílatele je přirozenější neblokovat po předání zprávy, protože může být potřeba poslat zprávu různým procesům. Odesílatel však očekává potvrzení od příjemce v případě, že se odeslání nezdaří. Podobně je přirozenější, aby se příjemce po vydání příjmu zablokoval, protože informace z přijaté zprávy mohou být použity pro další provádění. Současně, pokud odesílání zprávy nadále selhává, příjemce bude muset čekat neomezeně dlouho. Proto uvažujeme i o jiné možnosti předávání zpráv. V zásadě existují tři preferované kombinace:

  • Blokování odesílání a blokování příjmu
  • Neblokující odesílání a neblokující příjem
  • Neblokující odesílání a blokování příjmu (většinou používané)

V přímém předávání zpráv , Proces, který chce komunikovat, musí výslovně jmenovat příjemce nebo odesílatele komunikace.
např. odeslat (p1, zpráva) znamená poslat zprávu na p1.
Podobně, přijmout (p2, zpráva) znamená přijmout zprávu od p2.
Při tomto způsobu komunikace se automaticky naváže komunikační spojení, které může být jednosměrné nebo obousměrné, ale jeden spoj může být použit mezi jedním párem odesílatele a přijímače a jeden pár odesílatele a přijímače by neměl mít více než jeden pár. Odkazy. Lze také implementovat symetrii a asymetrii mezi odesíláním a přijímáním, tj. buď se oba procesy vzájemně pojmenují pro odesílání a přijímání zpráv, nebo pouze odesílatel pojmenuje příjemce pro odeslání zprávy a není potřeba, aby příjemce jmenoval odesílatele pro přijetí zprávy. Problémem tohoto způsobu komunikace je, že pokud se změní název jednoho procesu, tento způsob nebude fungovat.
V nepřímém předávání zpráv , procesy využívají poštovní schránky (také označované jako porty) pro odesílání a přijímání zpráv. Každá poštovní schránka má jedinečné ID a procesy mohou komunikovat pouze v případě, že sdílejí poštovní schránku. Odkaz se vytvoří pouze v případě, že procesy sdílejí společnou poštovní schránku a jeden odkaz může být spojen s mnoha procesy. Každá dvojice procesů může sdílet několik komunikačních spojů a tyto spoje mohou být jednosměrné nebo obousměrné. Předpokládejme, že dva procesy chtějí komunikovat prostřednictvím nepřímého předávání zpráv, požadované operace jsou: vytvořit poštovní schránku, použít tuto schránku k odesílání a přijímání zpráv a poté schránku zničit. Standardní použitá primitiva jsou: poslat zprávu) což znamená odeslat zprávu do schránky A. Stejným způsobem funguje i primitivum pro příjem zprávy, např. přijato (A, zpráva) . Došlo k problému s touto implementací poštovní schránky. Předpokládejme, že existuje více než dva procesy sdílející stejnou poštovní schránku a předpokládejme, že proces p1 posílá zprávu do poštovní schránky, který proces bude příjemce? To lze vyřešit buď vynucením, že pouze dva procesy mohou sdílet jednu poštovní schránku, nebo vynucením, že pouze jeden proces smí provádět příjem v daný čas, nebo náhodným výběrem libovolného procesu a oznámením odesílateli o příjemci. Schránku lze nastavit jako soukromou pro jeden pár odesílatel/příjemce a lze ji také sdílet mezi více páry odesílatel/příjemce. Port je implementace takové schránky, která může mít více odesílatelů a jednoho příjemce. Používá se v aplikacích klient/server (v tomto případě je serverem přijímač). Port je vlastněn přijímajícím procesem a vytvořen OS na žádost procesu přijímače a může být zničen buď na žádost stejného procesoru přijímače, když se přijímač sám ukončí. Vynucení toho, že pouze jeden proces smí provádět příjem, lze provést pomocí konceptu vzájemného vyloučení. Mutexová schránka je vytvořen, který je sdílen n procesem. Odesílatel je neblokující a zprávu odešle. První proces, který provede příjem, vstoupí do kritické sekce a všechny ostatní procesy budou blokovány a budou čekat.
Nyní pojďme diskutovat o problému producent-spotřebitel pomocí konceptu předávání zpráv. Výrobce umístí položky (uvnitř zpráv) do poštovní schránky a spotřebitel může položku konzumovat, pokud je ve schránce alespoň jedna zpráva. Kód je uveden níže:
Kód výrobce

C




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

>

>

Spotřebitelský zákoník

C




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

>

>

Příklady IPC systémů

  1. Posix : používá metodu sdílené paměti.
  2. Mach : používá předávání zpráv
  3. Windows XP: používá předávání zpráv pomocí místních procedurálních volání

Komunikace v architektuře klient/server:
Existují různé mechanismy:

  • Trubka
  • Zásuvka
  • Vzdálená procedurální volání (RPC)

Výše uvedené tři metody budou diskutovány v dalších článcích, protože všechny jsou zcela koncepční a zaslouží si vlastní samostatné články.
Reference:

  1. Koncepce operačního systému od Galvina a kol.
  2. Poznámky k přednáškám/ppt Ariela J. Franka, Bar-Ilan University

Meziprocesová komunikace (IPC) je mechanismus, jehož prostřednictvím mohou procesy nebo vlákna komunikovat a vyměňovat si data mezi sebou na počítači nebo v síti. IPC je důležitým aspektem moderních operačních systémů, protože umožňuje různým procesům spolupracovat a sdílet zdroje, což vede ke zvýšení efektivity a flexibility.

Výhody IPC:

  1. Umožňuje procesům vzájemně komunikovat a sdílet zdroje, což vede ke zvýšení efektivity a flexibility.
  2. Usnadňuje koordinaci mezi více procesy, což vede k lepšímu celkovému výkonu systému.
  3. Umožňuje vytváření distribuovaných systémů, které mohou zahrnovat více počítačů nebo sítí.
  4. Může být použit k implementaci různých synchronizačních a komunikačních protokolů, jako jsou semafory, roury a zásuvky.

Nevýhody IPC:

  1. Zvyšuje složitost systému, což ztěžuje návrh, implementaci a ladění.
  2. Může představovat slabá místa zabezpečení, protože procesy mohou mít přístup k datům patřícím jiným procesům nebo je upravovat.
  3. Vyžaduje pečlivou správu systémových prostředků, jako je paměť a čas CPU, aby bylo zajištěno, že operace IPC nesníží celkový výkon systému.
    Může vést k nekonzistentnosti dat, pokud se více procesů pokouší o přístup nebo úpravu stejných dat současně.
  4. Celkově výhody IPC převažují nad nevýhodami, protože je nezbytným mechanismem pro moderní operační systémy a umožňuje procesům spolupracovat a sdílet zdroje flexibilním a efektivním způsobem. Je však třeba dbát na pečlivé navrhování a implementaci systémů IPC, aby se předešlo potenciálním bezpečnostním chybám a problémům s výkonem.

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