logo

Medprocesna komunikacija (IPC)

Postopek je lahko dveh vrst:

  • Neodvisen proces.
  • Postopek sodelovanja.

Izvajanje drugih procesov ne vpliva na neodvisen proces, medtem ko na sodelujoči proces lahko vplivajo drugi izvajalni procesi. Čeprav lahko mislimo, da se bodo ti procesi, ki tečejo neodvisno, izvajali zelo učinkovito, v resnici obstaja veliko situacij, ko je mogoče izkoristiti kooperativno naravo za povečanje računalniške hitrosti, priročnosti in modularnosti. Medprocesna komunikacija (IPC) je mehanizem, ki procesom omogoča medsebojno komunikacijo in sinhronizacijo njihovih dejanj. Komunikacijo med temi procesi lahko razumemo kot metodo sodelovanja med njimi. Procesi lahko med seboj komunicirajo prek obeh:



  1. Skupni pomnilnik
  2. Prenos sporočil

Slika 1 spodaj prikazuje osnovno strukturo komunikacije med procesi preko metode skupnega pomnilnika in preko metode posredovanja sporočil.

Operacijski sistem lahko izvaja obe metodi komunikacije. Najprej bomo razpravljali o načinih komunikacije v skupnem pomnilniku in nato o posredovanju sporočil. Komunikacija med procesi, ki uporabljajo skupni pomnilnik, zahteva, da procesi delijo neko spremenljivko, in popolnoma je odvisno od tega, kako jo bo programer implementiral. En način komunikacije z uporabo skupnega pomnilnika si lahko predstavljamo takole: Recimo, da se proces1 in proces2 izvajata hkrati in si delita nekaj virov ali uporabljata nekaj informacij iz drugega procesa. Process1 generira informacije o določenih izračunih ali uporabljenih virih in jih hrani kot zapis v skupnem pomnilniku. Ko mora proces2 uporabiti informacije v skupni rabi, bo preveril zapis, shranjen v pomnilniku v skupni rabi, upošteval informacije, ki jih ustvari proces1, in ustrezno ukrepal. Procesi lahko uporabljajo skupni pomnilnik za pridobivanje informacij kot zapisa iz drugega procesa, pa tudi za dostavo kakršnih koli specifičnih informacij drugim procesom.
Oglejmo si primer komunikacije med procesi z uporabo metode skupnega pomnilnika.



i) Metoda skupnega pomnilnika

Primer: Problem proizvajalec-potrošnik
Obstajata dva procesa: proizvajalec in potrošnik. Proizvajalec proizvede nekaj izdelkov, potrošnik pa ta izdelek porabi. Procesa si delita skupni prostor ali pomnilniško lokacijo, znano kot medpomnilnik, kjer je shranjen izdelek, ki ga je proizvedel proizvajalec, in iz katerega potrošnik porabi predmet, če je to potrebno. Obstajata dve različici tega problema: prva je znana kot problem neomejenega medpomnilnika, pri katerem lahko proizvajalec še naprej proizvaja elemente in ni omejitve glede velikosti medpomnilnika, druga pa je znana kot problem omejenega medpomnilnika v ki jih lahko proizvajalec proizvede do določenega števila artiklov, preden začne čakati, da jih potrošnik porabi. Razpravljali bomo o problemu omejenega medpomnilnika. Najprej si bosta proizvajalec in potrošnik delila skupni spomin, nato bo proizvajalec začel proizvajati predmete. Če je skupni proizvedeni izdelek enak velikosti medpomnilnika, bo proizvajalec čakal, da ga porabi potrošnik. Podobno bo potrošnik najprej preveril razpoložljivost artikla. Če artikel ni na voljo, bo potrošnik počakal, da ga proizvede proizvajalec. Če so predmeti na voljo, jih bo potrošnik porabil. Psevdokoda za prikaz je navedena spodaj:
Skupni podatki med obema procesoma

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

>

>

Koda postopka proizvajalca

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

>

>

Koda potrošniškega procesa

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

>

>

V zgornji kodi bo proizvajalec znova začel proizvajati, ko bo (free_index+1) mod buff max brezplačen, ker če ni brezplačen, to pomeni, da še vedno obstajajo predmeti, ki jih lahko porabi potrošnik, zato ni potrebe proizvesti več. Podobno, če prosti indeks in polni indeks kažeta na isti indeks, to pomeni, da ni elementov za porabo.

Celotna implementacija 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>niti; threads.emplace_back(proizvajalec); threads.emplace_back(potrošnik); // Počakajte, da se niti končajo za (auto& thread : threads) { thread.join(); } vrni 0; }>

>

>

pretvori niz v char java

Upoštevajte, da se atomski razred uporablja za zagotovitev, da sta spremenljivki v skupni rabi free_index in full_index posodobljeni atomsko. Mutex se uporablja za zaščito kritičnega odseka, kjer se dostopa do medpomnilnika v skupni rabi. Funkcija sleep_for se uporablja za simulacijo proizvodnje in porabe artiklov.

ii) Metoda posredovanja sporočil

Zdaj bomo začeli razpravo o komunikaciji med procesi prek posredovanja sporočil. Pri tej metodi procesi komunicirajo med seboj brez uporabe kakršnega koli skupnega pomnilnika. Če dva procesa p1 in p2 želita komunicirati drug z drugim, postopata takole:

  • Vzpostavite komunikacijsko povezavo (če povezava že obstaja, je ni treba ponovno vzpostaviti.)
  • Začnite izmenjevati sporočila z uporabo osnovnih primitivov.
    Potrebujemo vsaj dva primitiva:
    poslati (sporočilo, cilj) oz poslati (sporočilo)
    prejeti (sporočilo, gostitelj) oz prejeti (sporočilo)

Velikost sporočila je lahko fiksne ali spremenljive velikosti. Če je fiksne velikosti, je lahko za načrtovalca operacijskega sistema, a zapleteno za programerja, in če je spremenljive velikosti, je lahko za programerja, vendar zapleteno za načrtovalca OS. Standardno sporočilo ima lahko dva dela: glava in telo.
The del glave se uporablja za shranjevanje vrste sporočila, ID-ja cilja, ID-ja vira, dolžine sporočila in kontrolnih informacij. Kontrolne informacije vsebujejo informacije, na primer kaj storiti, če zmanjka prostora v medpomnilniku, zaporedno številko, prioriteto. Na splošno je sporočilo poslano v slogu FIFO.

Sporočilo, ki poteka prek komunikacijske povezave.
Neposredna in posredna komunikacijska povezava
Zdaj bomo začeli razpravo o metodah izvajanja komunikacijskih povezav. Pri izvajanju povezave je treba upoštevati nekaj vprašanj, kot so:

  1. Kako se vzpostavijo povezave?
  2. Ali je lahko povezava povezana z več kot dvema procesoma?
  3. Koliko povezav je lahko med vsakim parom komunikacijskih procesov?
  4. Kakšna je zmogljivost povezave? Ali je velikost sporočila, ki ga lahko sprejme povezava, fiksna ali spremenljiva?
  5. Ali je povezava enosmerna ali dvosmerna?

Povezava ima določeno zmogljivost, ki določa število sporočil, ki se lahko začasno nahajajo v njej, za katero ima vsaka povezava čakalno vrsto, ki je lahko z ničelno zmogljivostjo, omejeno zmogljivostjo ali neomejeno zmogljivostjo. Pri ničelni zmogljivosti pošiljatelj čaka, dokler prejemnik ne obvesti pošiljatelja, da je prejel sporočilo. V primerih z zmogljivostjo, ki ni ničelna, proces po operaciji pošiljanja ne ve, ali je bilo sporočilo prejeto ali ne. Za to mora pošiljatelj izrecno komunicirati s prejemnikom. Izvedba povezave je odvisna od situacije, lahko je direktna komunikacijska povezava ali posredno usmerjena komunikacijska povezava.
Neposredne komunikacijske povezave se izvajajo, ko procesi za komunikacijo uporabljajo poseben identifikator procesa, vendar je pošiljatelja težko identificirati vnaprej.
Na primer tiskalni strežnik.
Posredna komunikacija poteka prek skupnega poštnega predala (porta), ki je sestavljen iz čakalne vrste sporočil. Pošiljatelj hrani sporočilo v nabiralniku, prejemnik pa ga prevzame.

Prehod sporočila skozi izmenjavo sporočil.

Sinhrono in asinhrono posredovanje sporočil:
Proces, ki je blokiran, je tisti, ki čaka na nek dogodek, kot je vir, ki postane na voljo, ali dokončanje V/I operacije. IPC je možen med procesi na istem računalniku kot tudi med procesi, ki se izvajajo na drugem računalniku, tj. v omrežnem/razdeljenem sistemu. V obeh primerih je lahko proces med pošiljanjem sporočila ali poskusom prejema sporočila blokiran ali pa tudi ne, tako da je posredovanje sporočil lahko blokirajoče ali neblokirno. Blokada se upošteva sinhrono in blokira pošiljanje pomeni, da bo pošiljatelj blokiran, dokler prejemnik ne prejme sporočila. Podobno, blokiranje sprejema ima blok prejemnika, dokler ni na voljo sporočilo. Upošteva se neblokada asinhroni in pošiljanje brez blokiranja pošiljatelju pošlje sporočilo in nadaljuje. Podobno ima sprejemnik brez blokiranja veljavno ali ničelno sporočilo. Po natančni analizi lahko pridemo do zaključka, da je za pošiljatelja bolj naravno, da je po posredovanju sporočila neblokiran, saj se lahko pojavi potreba po pošiljanju sporočila različnim procesom. Vendar pa pošiljatelj pričakuje potrditev od prejemnika, če pošiljanje ne uspe. Podobno je bolj naravno, da prejemnik blokira po izdaji prejema, saj se informacije iz prejetega sporočila lahko uporabijo za nadaljnjo izvedbo. Obenem bo moral prejemnik čakati v nedogled, če bo pošiljanje sporočila kar naprej neuspešno. Zato razmišljamo tudi o drugi možnosti prenosa sporočil. V bistvu obstajajo tri prednostne kombinacije:

  • Blokiranje pošiljanja in blokiranje prejemanja
  • Neblokirajoče pošiljanje in neblokirajoče prejemanje
  • Neblokirajoče pošiljanje in blokiranje prejemanja (večinoma uporabljeno)

Pri neposrednem prenosu sporočil , Proces, ki želi komunicirati, mora izrecno poimenovati prejemnika ali pošiljatelja komunikacije.
npr. pošlji (p1, sporočilo) pomeni pošiljanje sporočila na p1.
Podobno, prejmi (p2, sporočilo) pomeni prejeti sporočilo od p2.
Pri tem načinu komuniciranja se samodejno vzpostavi komunikacijska povezava, ki je lahko enosmerna ali dvosmerna, vendar se lahko uporablja ena povezava med enim parom pošiljatelja in prejemnika, pri čemer en par pošiljatelj in prejemnik ne sme imeti več kot enega para povezave. Prav tako je mogoče implementirati simetrijo in asimetrijo med pošiljanjem in prejemanjem, tj. ali bosta oba procesa imenovala drug drugega za pošiljanje in prejemanje sporočil ali pa bo samo pošiljatelj imenoval prejemnika za pošiljanje sporočila in ni potrebe, da prejemnik imenuje pošiljatelja za prejemanje sporočila. Težava s to metodo komunikacije je, da če se ime enega procesa spremeni, ta metoda ne bo delovala.
Pri posrednem posredovanju sporočil , procesi uporabljajo poštne predale (imenovane tudi vrata) za pošiljanje in prejemanje sporočil. Vsak nabiralnik ima edinstven ID in procesi lahko komunicirajo le, če si delijo nabiralnik. Povezava je vzpostavljena le, če si procesi delijo skupni nabiralnik in je ena povezava lahko povezana z več procesi. Vsak par procesov lahko deli več komunikacijskih povezav in te povezave so lahko enosmerne ali dvosmerne. Recimo, da želita dva procesa komunicirati prek posrednega posredovanja sporočil, potrebne operacije so: ustvarite nabiralnik, uporabite ta nabiralnik za pošiljanje in prejemanje sporočil, nato pa uničite nabiralnik. Uporabljeni standardni primitivi so: poslati sporočilo) kar pomeni pošlji sporočilo v predal A. Na enak način deluje tudi primitiva za sprejem sporočila, npr. prejeto (A, sporočilo) . Pri tej implementaciji nabiralnika je težava. Recimo, da si več kot dva procesa delita isti nabiralnik in da proces p1 pošlje sporočilo v nabiralnik, kateri proces bo prejemnik? To je mogoče rešiti bodisi z uveljavljanjem, da si lahko samo dva procesa delita en nabiralnik, bodisi z uveljavljanjem, da je dovoljeno samo enemu procesu izvesti sprejem v določenem času, ali pa naključno izberete kateri koli proces in obvestite pošiljatelja o prejemniku. Nabiralnik lahko naredite zasebnega za en sam par pošiljatelj/prejemnik in ga lahko delite tudi med več pari pošiljatelj/prejemnik. Port je izvedba takega poštnega predala, ki ima lahko več pošiljateljev in enega prejemnika. Uporablja se v aplikacijah odjemalec/strežnik (v tem primeru je strežnik sprejemnik). Vrata so v lasti prejemnega procesa in jih ustvari OS na zahtevo prejemnega procesa in se lahko uničijo bodisi na zahtevo istega sprejemnega procesorja, ko se sprejemnik sam prekine. Uveljavitev, da je dovoljen samo en postopek za izvajanje sprejema, je mogoče izvesti s konceptom medsebojne izključitve. Poštni predal Mutex se ustvari, ki ga deli n proces. Pošiljatelj ne blokira in pošlje sporočilo. Prvi proces, ki izvede sprejem, bo vstopil v kritični razdelek, vsi drugi procesi pa bodo blokirani in čakali.
Zdaj pa razpravljajmo o problemu proizvajalec-potrošnik z uporabo koncepta posredovanja sporočil. Proizvajalec postavi predmete (znotraj sporočil) v nabiralnik, potrošnik pa lahko zaužije predmet, ko je v nabiralniku vsaj eno sporočilo. Koda je navedena spodaj:
Koda proizvajalca

C




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

>

>

Potrošniški kodeks

C




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

>

>

Primeri sistemov IPC

  1. Posix : uporablja metodo skupnega pomnilnika.
  2. Mach : uporablja posredovanje sporočil
  3. Windows XP : uporablja posredovanje sporočil z uporabo lokalnih postopkovnih klicev

Komunikacija v arhitekturi odjemalec/strežnik:
Obstajajo različni mehanizmi:

  • Cev
  • Vtičnica
  • Oddaljeni proceduralni klici (RPC)

O zgornjih treh metodah bomo razpravljali v naslednjih člankih, saj so vse precej konceptualne in si zaslužijo svoje ločene članke.
Reference:

  1. Koncepti operacijskega sistema Galvina et al.
  2. Zapiski predavanj/ppt Ariel J. Frank, Univerza Bar-Ilan

Medprocesna komunikacija (IPC) je mehanizem, prek katerega lahko procesi ali niti komunicirajo in izmenjujejo podatke med seboj v računalniku ali prek omrežja. IPC je pomemben vidik sodobnih operacijskih sistemov, saj omogoča, da različni procesi delujejo skupaj in si delijo vire, kar vodi do povečane učinkovitosti in prilagodljivosti.

Prednosti IPC:

  1. Omogoča procesom medsebojno komunikacijo in skupno rabo virov, kar vodi k večji učinkovitosti in prilagodljivosti.
  2. Omogoča koordinacijo med več procesi, kar vodi k boljši splošni zmogljivosti sistema.
  3. Omogoča ustvarjanje porazdeljenih sistemov, ki lahko zajemajo več računalnikov ali omrežij.
  4. Uporablja se lahko za implementacijo različnih sinhronizacijskih in komunikacijskih protokolov, kot so semaforji, cevi in ​​vtičnice.

Slabosti IPC:

  1. Poveča kompleksnost sistema, zaradi česar je težje načrtovati, izvajati in odpravljati napake.
  2. Lahko povzroči varnostne ranljivosti, saj lahko procesi dostopajo do podatkov, ki pripadajo drugim procesom, ali jih spreminjajo.
  3. Zahteva skrbno upravljanje sistemskih virov, kot sta pomnilnik in čas procesorja, da se zagotovi, da operacije IPC ne poslabšajo splošne zmogljivosti sistema.
    Lahko povzroči nedoslednosti podatkov, če več procesov poskuša dostopati do istih podatkov ali jih spreminjati hkrati.
  4. Na splošno so prednosti IPC večje od slabosti, saj je nujen mehanizem za sodobne operacijske sisteme in omogoča, da procesi delujejo skupaj in si delijo vire na prilagodljiv in učinkovit način. Vendar je treba skrbno načrtovati in izvajati sisteme IPC, da se izognemo morebitnim varnostnim ranljivostim in težavam z zmogljivostjo.

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