logo

Starpprocesu komunikācija (IPC)

Process var būt divu veidu:

  • Neatkarīgs process.
  • Sadarbības process.

Neatkarīgu procesu neietekmē citu procesu izpilde, savukārt sadarbības procesu var ietekmēt citi izpildes procesi. Lai gan var domāt, ka tie procesi, kas darbojas neatkarīgi, darbosies ļoti efektīvi, patiesībā ir daudzas situācijas, kad kooperatīvo raksturu var izmantot, lai palielinātu skaitļošanas ātrumu, ērtības un modularitāti. Starpprocesu komunikācija (IPC) ir mehānisms, kas ļauj procesiem sazināties vienam ar otru un sinhronizēt to darbības. Komunikāciju starp šiem procesiem var uzskatīt par sadarbības metodi starp tiem. Procesi var sazināties viens ar otru, izmantojot abus:



  1. Koplietotā atmiņa
  2. Ziņas nodošana

1. attēlā parādīta saziņas pamatstruktūra starp procesiem, izmantojot koplietojamās atmiņas metodi un ziņojumu nosūtīšanas metodi.

Operētājsistēma var īstenot abas saziņas metodes. Vispirms mēs apspriedīsim saziņas kopīgās atmiņas metodes un pēc tam ziņojumu nodošanu. Saziņai starp procesiem, izmantojot koplietojamo atmiņu, procesiem ir jādala daži mainīgie, un tas pilnībā ir atkarīgs no tā, kā programmētājs to ieviesīs. Vienu veidu saziņai, izmantojot koplietojamo atmiņu, var iedomāties šādi: Pieņemsim, ka process1 un process2 tiek izpildīti vienlaicīgi un tie koplieto dažus resursus vai izmanto kādu informāciju no cita procesa. Process1 ģenerē informāciju par noteiktiem aprēķiniem vai izmantotajiem resursiem un saglabā to kā ierakstu koplietotajā atmiņā. Kad procesam2 ir jāizmanto koplietotā informācija, tas pārbaudīs koplietojamā atmiņā saglabāto ierakstu un ņems vērā procesa1 ģenerēto informāciju un attiecīgi rīkosies. Procesi var izmantot koplietojamo atmiņu, lai iegūtu informāciju kā ierakstu no cita procesa, kā arī lai piegādātu jebkuru specifisku informāciju citiem procesiem.
Apspriedīsim piemēru saziņai starp procesiem, izmantojot koplietojamās atmiņas metodi.



i) Koplietotās atmiņas metode

Piemēram: ražotāja un patērētāja problēma
Ir divi procesi: ražotājs un patērētājs. Ražotājs ražo dažas preces, un Patērētājs patērē šo preci. Abiem procesiem ir kopīga telpa vai atmiņas vieta, kas pazīstama kā buferis, kurā tiek glabāta ražotāja ražotā prece un no kuras Patērētājs vajadzības gadījumā patērē preci. Šai problēmai ir divas versijas: pirmā ir zināma kā neierobežota bufera problēma, kurā ražotājs var turpināt ražot vienumus, un bufera lielums nav ierobežots, otrā ir zināma kā ierobežotā bufera problēma. ko Ražotājs var saražot līdz noteiktam vienību skaitam, pirms tas sāk gaidīt, kad Patērētājs to patērēs. Mēs apspriedīsim ierobežotā bufera problēmu. Pirmkārt, ražotājam un patērētājam būs kopīga atmiņa, pēc tam ražotājs sāks ražot preces. Ja kopējais saražotās preces apjoms ir vienāds ar bufera lielumu, ražotājs gaidīs, līdz to patērēs Patērētājs. Tāpat patērētājs vispirms pārbaudīs preces pieejamību. Ja neviena prece nav pieejama, Patērētājs gaidīs, līdz Ražotājs to ražos. Ja preces ir pieejamas, Patērētājs tās patērēs. Pseidokods demonstrēšanai ir sniegts zemāk:
Koplietoti dati starp abiem procesiem

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

>

>

Ražotāja procesa kods

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

>

>

Patērētāja procesa kods

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

>

>

Iepriekš minētajā kodā ražotājs atsāks ražošanu, kad (free_index+1) mod buff max būs bezmaksas, jo, ja tas nav bezmaksas, tas nozīmē, ka joprojām ir preces, kuras patērētājs var patērēt, tāpēc tas nav nepieciešams. ražot vairāk. Tāpat, ja bezmaksas indekss un pilnais indekss norāda uz vienu un to pašu indeksu, tas nozīmē, ka nav lietojamu preču.

Kopējā C++ ieviešana:

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>diegi; pavedieni.emplace_back(producer); pavedieni.emplace_back(patērētājs); // Pagaidiet, līdz pavedieni beigsies (auto& pavediens : pavedieni) { thread.join(); } return 0; }>

>

>

tīģera un lauvas atšķirība

Ņemiet vērā, ka atomu klase tiek izmantota, lai nodrošinātu, ka koplietotie mainīgie free_index un full_index tiek atjaunināti atomiski. Mutex tiek izmantots, lai aizsargātu kritisko sadaļu, kurā tiek piekļūts koplietotajam buferim. Funkciju sleep_for izmanto, lai modelētu preču ražošanu un patēriņu.

ii) Ziņojumapmaiņas nodošanas metode

Tagad mēs sāksim diskusiju par komunikāciju starp procesiem, izmantojot ziņojumu nodošanu. Izmantojot šo metodi, procesi sazinās viens ar otru, neizmantojot nekādu koplietojamo atmiņu. Ja divi procesi p1 un p2 vēlas sazināties viens ar otru, tie rīkojas šādi:

  • Izveidojiet saziņas saiti (ja saite jau pastāv, tā nav jāizveido vēlreiz.)
  • Sāciet apmainīties ar ziņojumiem, izmantojot pamata primitīvus.
    Mums ir nepieciešami vismaz divi primitīvi:
    nosūtīt (ziņa, galamērķis) vai nosūtīt (ziņa)
    saņemt (ziņa, saimniekdators) vai saņemt (ziņa)

Ziņojuma lielums var būt fiksēta izmēra vai mainīga izmēra. Ja tas ir fiksēta izmēra, tas ir viegli OS dizainerim, bet sarežģīti programmētājam un ja tas ir mainīga izmēra, tad programmētājam tas ir viegli, bet OS dizainerim sarežģīti. Standarta ziņojumam var būt divas daļas: galvene un pamatteksts.
The galvenes daļa tiek izmantots ziņojuma veida, mērķa ID, avota ID, ziņojuma garuma un vadības informācijas glabāšanai. Vadības informācija satur informāciju, piemēram, kā rīkoties, ja bufera vieta ir beigusies, kārtas numurs, prioritāte. Parasti ziņojums tiek nosūtīts, izmantojot FIFO stilu.

Ziņojums tiek nosūtīts caur saziņas saiti.
Tiešās un netiešās komunikācijas saite
Tagad mēs sāksim diskusiju par komunikācijas saišu ieviešanas metodēm. Ieviešot saiti, ir daži jautājumi, kas jāpatur prātā, piemēram:

  1. Kā tiek izveidotas saites?
  2. Vai saiti var saistīt ar vairāk nekā diviem procesiem?
  3. Cik saišu var būt starp katru saziņas procesu pāri?
  4. Kāda ir saites ietilpība? Vai ziņojuma lielums, ko var ievietot saitē, ir fiksēts vai mainīgs?
  5. Vai saite ir vienvirziena vai divvirzienu?

Saitei ir noteikta ietilpība, kas nosaka to ziņojumu skaitu, kas tajā var īslaicīgi atrasties un kuriem katrai saitei ir saistīta rinda, kas var būt ar nulles ietilpību, ierobežotu ietilpību vai neierobežotu ietilpību. Nulles jaudas gadījumā sūtītājs gaida, līdz saņēmējs informē sūtītāju, ka ir saņēmis ziņojumu. Gadījumos, kad jauda nav nulles, process nezina, vai ziņojums ir saņemts vai nav saņemts pēc nosūtīšanas darbības. Šim nolūkam sūtītājam ir skaidri jāsazinās ar saņēmēju. Saites ieviešana ir atkarīga no situācijas, tā var būt vai nu tieša saziņas saite, vai netieša komunikācijas saite.
Tiešās saziņas saites tiek ieviesti, kad procesi saziņai izmanto konkrētu procesa identifikatoru, taču ir grūti noteikt sūtītāju pirms laika.
Piemēram, drukas serveris.
Netiešā komunikācija tiek veikta, izmantojot koplietojamo pastkasti (portu), kas sastāv no ziņojumu rindas. Sūtītājs saglabā ziņojumu pastkastē, un saņēmējs tos paņem.

Ziņojuma nodošana, apmainoties ar ziņojumiem.

Sinhronā un asinhronā ziņojumu nodošana:
Bloķēts process ir tāds, kas gaida kādu notikumu, piemēram, resursa pieejamību vai ievades/izvades darbības pabeigšanu. IPC ir iespējama starp procesiem vienā datorā, kā arī procesiem, kas darbojas citā datorā, t.i. tīklā/izplatītajā sistēmā. Abos gadījumos process var būt vai var nebūt bloķēts, sūtot ziņojumu vai mēģinot saņemt ziņojumu, tāpēc ziņojuma nodošana var būt bloķējoša vai nebloķējoša. Tiek apsvērta bloķēšana sinhroni un bloķējoša sūtīšana nozīmē, ka sūtītājs tiks bloķēts, līdz saņēmējs saņems ziņojumu. Līdzīgi, saņemšanas bloķēšana ir uztvērēja bloks, līdz ir pieejams ziņojums. Tiek uzskatīts par nebloķēšanu asinhrons un Nebloķējot sūtīšanu, sūtītājs nosūta ziņojumu un turpina. Līdzīgi, nebloķējot saņemšanu, saņēmējs saņem derīgu ziņojumu vai nulli. Pēc rūpīgas analīzes varam secināt, ka sūtītājam pēc ziņojuma nodošanas dabiskāk ir nebloķēt, jo var rasties nepieciešamība nosūtīt ziņojumu dažādiem procesiem. Tomēr sūtītājs sagaida apstiprinājumu no saņēmēja, ja sūtīšana neizdodas. Tāpat ir dabiskāk, ja saņēmējs pēc saņemšanas izdošanas bloķē, jo informācija no saņemtā ziņojuma var tikt izmantota turpmākai izpildei. Tajā pašā laikā, ja ziņojuma nosūtīšana joprojām neizdodas, saņēmējam būs jāgaida bezgalīgi. Tāpēc mēs apsveram arī citu ziņojumu nodošanas iespēju. Būtībā ir trīs vēlamās kombinācijas:

  • Sūtīšanas bloķēšana un saņemšanas bloķēšana
  • Nebloķējoša sūtīšana un nebloķējoša saņemšana
  • Nebloķējoša sūtīšana un bloķējoša saņemšana (pārsvarā tiek izmantota)

Tiešā ziņojuma pārsūtīšanas režīmā , Procesam, kas vēlas sazināties, ir skaidri jānorāda saziņas saņēmējs vai sūtītājs.
piem. sūtīt (p1, ziņa) nozīmē nosūtīt ziņojumu uz p1.
Līdzīgi, saņemt (p2, ziņa) nozīmē saņemt ziņojumu no p2.
Izmantojot šo saziņas metodi, saziņas saite tiek izveidota automātiski, kas var būt vienvirziena vai divvirzienu, bet vienu saiti var izmantot starp vienu sūtītāja un saņēmēja pāri, un vienam sūtītāja un saņēmēja pārim nedrīkst būt vairāk par vienu pāri. saites. Var tikt realizēta arī simetrija un asimetrija starp sūtīšanu un saņemšanu, t.i., vai nu abi procesi nosauks viens otru, lai nosūtītu un saņemtu ziņojumus, vai arī tikai sūtītājs nosauks adresātu ziņojuma nosūtīšanai, un nav nepieciešams, lai saņēmējs nosauktu sūtītāju. saņemot ziņojumu. Šīs saziņas metodes problēma ir tāda, ka, mainoties viena procesa nosaukumam, šī metode nedarbosies.
Netiešā ziņojuma pārsūtīšanas režīmā , procesi ziņojumu nosūtīšanai un saņemšanai izmanto pastkastes (sauktas arī par portiem). Katrai pastkastei ir unikāls ID, un procesi var sazināties tikai tad, ja tiem ir kopīga pastkaste. Saite izveidota tikai tad, ja procesiem ir kopīga pastkaste un vienu saiti var saistīt ar daudziem procesiem. Katrs procesu pāris var koplietot vairākas saziņas saites, un šīs saites var būt vienvirziena vai divvirzienu. Pieņemsim, ka divi procesi vēlas sazināties, izmantojot Netiešo ziņojumu pārsūtīšanu, nepieciešamās darbības ir: izveidot pastkasti, izmantot šo pastkasti ziņojumu sūtīšanai un saņemšanai, pēc tam pastkastes iznīcināšana. Izmantotie standarta primitīvie ir: Nosūtīt ziņu) kas nozīmē nosūtīt ziņojumu uz pastkasti A. Primitīvs ziņojuma saņemšanai arī darbojas tāpat, piem. saņemts (A, ziņojums) . Radās problēma ar šo pastkastes ieviešanu. Pieņemsim, ka ir vairāk nekā divi procesi, kas koplieto vienu pastkasti, un pieņemsim, ka process p1 nosūta ziņojumu uz pastkasti, kurš process būs saņēmējs? To var atrisināt, vai nu nosakot, ka tikai divi procesi var koplietot vienu pastkasti, vai arī nosakot, ka tikai vienam procesam ir atļauts izpildīt saņemšanu noteiktā laikā, vai arī atlasot jebkuru procesu nejauši un paziņojot sūtītājam par saņēmēju. Pastkasti var padarīt privātu vienam sūtītāja/saņēmēja pārim, kā arī to var koplietot vairākiem sūtītāju/saņēmēju pāriem. Ports ir tādas pastkastes ieviešana, kurai var būt vairāki sūtītāji un viens saņēmējs. To izmanto klienta/servera lietojumprogrammās (šajā gadījumā serveris ir uztvērējs). Ports pieder saņemšanas procesam, un to izveido OS pēc uztvērēja procesa pieprasījuma, un to var iznīcināt pēc tā paša uztvērēja procesora pieprasījuma, kad uztvērējs pārtrauc sevi. Noteikt, ka saņemšanu drīkst veikt tikai viens process, var izmantot, izmantojot savstarpējas izslēgšanas koncepciju. Mutex pastkaste tiek izveidots, ko koplieto n process. Sūtītājs nebloķē un nosūta ziņojumu. Pirmais process, kas izpilda saņemšanu, nonāks kritiskajā sadaļā, un visi pārējie procesi tiks bloķēti un gaidīs.
Tagad apspriedīsim ražotāja un patērētāja problēmu, izmantojot ziņojuma nodošanas koncepciju. Ražotājs ievieto sūtījumus (iekšējos ziņojumus) pastkastītē, un patērētājs var patērēt preci, ja pastkastē ir vismaz viens ziņojums. Kods ir norādīts zemāk:
Ražotāja kods

C




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

>

>

Patērētāja kods

C




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

>

>

IPC sistēmu piemēri

  1. Posix: izmanto koplietotās atmiņas metodi.
  2. Mach : izmanto ziņojumu nodošanu
  3. Windows XP: izmanto ziņojumu pārsūtīšanu, izmantojot vietējos procesuālos zvanus

Komunikācija klienta/servera arhitektūrā:
Ir dažādi mehānismi:

  • Caurule
  • Kontaktligzda
  • Remote procedural calls (RPC)

Iepriekš minētās trīs metodes tiks aplūkotas turpmākajos rakstos, jo tās visas ir diezgan konceptuālas un ir pelnījušas savus atsevišķus rakstus.
Atsauces:

  1. Operētājsistēmas koncepcijas, ko izstrādājuši Galvins et al.
  2. Ariel J. Frank, Bar-Ilan University lekciju piezīmes/ppt

Starpprocesu komunikācija (IPC) ir mehānisms, ar kura palīdzību procesi vai pavedieni var sazināties un apmainīties ar datiem savā starpā datorā vai tīklā. IPC ir svarīgs mūsdienu operētājsistēmu aspekts, jo tas ļauj dažādiem procesiem strādāt kopā un koplietot resursus, tādējādi palielinot efektivitāti un elastību.

IPC priekšrocības:

  1. Ļauj procesiem sazināties vienam ar otru un koplietot resursus, tādējādi palielinot efektivitāti un elastību.
  2. Atvieglo koordināciju starp vairākiem procesiem, tādējādi uzlabojot sistēmas vispārējo veiktspēju.
  3. Ļauj izveidot sadalītas sistēmas, kas var aptvert vairākus datorus vai tīklus.
  4. Var izmantot, lai ieviestu dažādus sinhronizācijas un sakaru protokolus, piemēram, semaforus, caurules un kontaktligzdas.

IPC trūkumi:

  1. Palielina sistēmas sarežģītību, padarot to grūtāk izstrādāt, ieviest un atkļūdot.
  2. Var ieviest drošības ievainojamības, jo procesi var piekļūt vai modificēt datus, kas pieder citiem procesiem.
  3. Nepieciešama rūpīga sistēmas resursu, piemēram, atmiņas un CPU laika, pārvaldība, lai nodrošinātu, ka IPC darbības nepasliktina kopējo sistēmas veiktspēju.
    Var izraisīt datu nekonsekvenci, ja vairāki procesi mēģina piekļūt vieniem un tiem pašiem datiem vai tos modificēt vienlaikus.
  4. Kopumā IPC priekšrocības atsver trūkumus, jo tas ir modernām operētājsistēmām nepieciešams mehānisms un ļauj procesiem strādāt kopā un koplietot resursus elastīgi un efektīvi. Tomēr rūpīgi jāprojektē un jāievieš IPC sistēmas, lai izvairītos no iespējamām drošības ievainojamībām un veiktspējas problēmām.

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