Prosessi voi olla kahden tyyppistä:
- Itsenäinen prosessi.
- Yhteistyöprosessi.
Muiden prosessien suorittaminen ei vaikuta itsenäiseen prosessiin, kun taas muut suorittavat prosessit voivat vaikuttaa yhteistyöprosessiin. Vaikka voidaan ajatella, että itsenäisesti toimivat prosessit toteutuvat erittäin tehokkaasti, todellisuudessa on monia tilanteita, joissa yhteistoiminnallista luonnetta voidaan hyödyntää laskennan nopeuden, mukavuuden ja modulaarisuuden lisäämiseksi. Prosessien välinen viestintä (IPC) on mekanismi, joka mahdollistaa prosessien kommunikoinnin toistensa kanssa ja toimintojensa synkronoinnin. Näiden prosessien välinen kommunikaatio voidaan nähdä niiden välisenä yhteistyömuotona. Prosessit voivat kommunikoida keskenään molempien kautta:
- Jaettu muisti
- Viestin välitys
Alla olevassa kuvassa 1 on esitetty prosessien välisen viestinnän perusrakenne jaetun muistin menetelmällä ja viestinvälitysmenetelmällä.
Käyttöjärjestelmä voi toteuttaa molemmat viestintätavat. Ensin keskustellaan jaetun muistin viestintämenetelmistä ja sitten viestien välittämisestä. Yhteydenpito prosessien välillä jaetun muistin avulla edellyttää prosessien jakamista jonkin muuttujan kanssa, ja se riippuu täysin siitä, kuinka ohjelmoija toteuttaa sen. Eräs tapa kommunikoida jaettua muistia käyttämällä voidaan kuvitella näin: Oletetaan, että prosessi1 ja prosessi2 suorittavat samanaikaisesti, ja ne jakavat resursseja tai käyttävät jotakin tietoa toisesta prosessista. Prosessi1 luo tietoa tietyistä käytetyistä laskelmista tai resursseista ja säilyttää sen tietueena jaettuun muistiin. Kun prosessi2 tarvitsee jaettua tietoa, se tarkistaa jaettuun muistiin tallennetun tietueen ja ottaa huomioon prosessin1 tuottamat tiedot ja toimii sen mukaisesti. Prosessit voivat käyttää jaettua muistia tiedon poimimiseen tietueina toisesta prosessista sekä minkä tahansa tietyn tiedon toimittamiseen muille prosesseille.
Keskustellaan esimerkistä prosessien välisestä viestinnästä jaetun muistin menetelmällä.

i) Jaetun muistin menetelmä
Esimerkiksi: tuottaja-kuluttaja-ongelma
On olemassa kaksi prosessia: tuottaja ja kuluttaja. Tuottaja valmistaa joitain tuotteita ja kuluttaja kuluttaa sen. Molemmilla prosesseilla on yhteinen tila tai muistipaikka, joka tunnetaan puskurina, johon Tuottajan tuottama tuote tallennetaan ja josta Kuluttaja tarvittaessa kuluttaa tuotteen. Tästä ongelmasta on kaksi versiota: ensimmäinen tunnetaan rajoittamattomana puskuriongelmana, jossa tuottaja voi jatkaa tuotteiden tuotantoa ja puskurin kokoa ei ole rajoitettu, toinen tunnetaan rajoittuneena puskuriongelmana. jonka Tuottaja voi tuottaa tietyn määrän tuotteita ennen kuin se alkaa odottaa kuluttajan kuluttavan sen. Keskustelemme rajoitetun puskurin ongelmasta. Ensin tuottaja ja kuluttaja jakavat yhteisen muistin, sitten tuottaja alkaa tuottaa tuotteita. Jos tuotettujen nimikkeiden kokonaismäärä on yhtä suuri kuin puskurin koko, tuottaja odottaa saavansa sen kuluttamaan Kuluttajan. Vastaavasti kuluttaja tarkistaa ensin tuotteen saatavuuden. Jos tuotetta ei ole saatavilla, Kuluttaja odottaa, että Tuottaja tuottaa sen. Jos tuotteita on saatavilla, Kuluttaja kuluttaa ne. Havainnollistava pseudokoodi on alla:
Jaettu data kahden prosessin välillä
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;> > |
>
>
Tuottajan prosessikoodi
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;> >}> |
>
>
Kuluttajaprosessikoodi
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;> >}> |
>
>
Yllä olevassa koodissa Tuottaja aloittaa tuotannon uudelleen, kun (free_index+1) mod buff max on ilmainen, koska jos se ei ole ilmainen, tämä tarkoittaa, että kuluttaja voi kuluttaa edelleen tuotteita, joten tarvetta ei ole. tuottaa enemmän. Vastaavasti, jos ilmainen indeksi ja täysi indeksi osoittavat samaan indeksiin, tämä tarkoittaa, että kuluttavia kohteita ei ole.
Yleinen C++-toteutus:
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>kierteet; threads.emplace_back(tuottaja); threads.emplace_back(kuluttaja); // Odota säikeiden päättymistä varten (auto& thread : threads) { thread.join(); } return 0; }> |
>
>
maailman paras hymy
Huomaa, että atomiluokkaa käytetään varmistamaan, että jaetut muuttujat free_index ja full_index päivitetään atomisesti. Mutexia käytetään suojaamaan kriittistä osaa, jossa jaettua puskuria käytetään. Sleep_for-funktiota käytetään tuotteiden tuotannon ja kulutuksen simulointiin.
ii) Viestinvälitysmenetelmä
Aloitamme nyt keskustelun prosessien välisestä kommunikaatiosta viestinvälityksen kautta. Tässä menetelmässä prosessit kommunikoivat keskenään ilman minkäänlaista jaettua muistia. Jos kaksi prosessia p1 ja p2 haluavat kommunikoida keskenään, ne etenevät seuraavasti:
- Luo viestintälinkki (jos linkki on jo olemassa, sitä ei tarvitse muodostaa uudelleen.)
- Aloita viestien vaihtaminen perusprimitiivien avulla.
Tarvitsemme vähintään kaksi primitiiviä:
– lähettää (viesti, kohde) tai lähettää (viesti)
– vastaanottaa (viesti, isäntä) tai vastaanottaa (viesti)

Viestin koko voi olla kiinteäkokoinen tai vaihtelevakokoinen. Jos se on kiinteän kokoinen, se on helppoa käyttöjärjestelmän suunnittelijalle, mutta monimutkaista ohjelmoijalle ja jos se on vaihtelevakokoinen, se on ohjelmoijalle helppoa, mutta käyttöjärjestelmän suunnittelijalle monimutkaista. Vakioviestissä voi olla kaksi osaa: otsikko ja runko.
The otsikko-osa käytetään viestityypin, kohdetunnuksen, lähdetunnuksen, viestin pituuden ja ohjaustietojen tallentamiseen. Ohjaustiedot sisältävät tietoja, kuten mitä tehdä, jos puskuritila loppuu, järjestysnumero, prioriteetti. Yleensä viesti lähetetään FIFO-tyylillä.
Viesti kulkee viestintälinkin kautta.
Suora ja epäsuora viestintälinkki
Nyt aloitamme keskustelumme viestintälinkkien toteuttamismenetelmistä. Kun otat käyttöön linkkiä, on joitakin kysymyksiä, jotka on pidettävä mielessä, kuten:
- Miten linkit muodostetaan?
- Voiko linkki liittyä useampaan kuin kahteen prosessiin?
- Kuinka monta linkkiä voi olla jokaisen viestintäprosessiparin välillä?
- Mikä on linkin kapasiteetti? Onko linkkiin mahtuvan viestin koko kiinteä vai muuttuva?
- Onko linkki yksi- vai kaksisuuntainen?
Linkillä on jonkin verran kapasiteettia, joka määrittää, kuinka monta viestiä siinä tilapäisesti voi olla ja joille jokaiseen linkkiin liittyy jono, jonka kapasiteetti voi olla nolla, rajoitettu kapasiteetti tai rajoittamaton kapasiteetti. Nollakapasiteetissa lähettäjä odottaa, kunnes vastaanottaja ilmoittaa lähettäjälle vastaanottaneensa viestin. Nollasta poikkeavissa tapauksissa prosessi ei tiedä, onko viesti vastaanotettu vai ei lähetystoiminnon jälkeen. Tätä varten lähettäjän on kommunikoitava vastaanottajan kanssa nimenomaisesti. Linkin toteutus riippuu tilanteesta, se voi olla joko suora tai epäsuora viestintälinkki.
Suorat viestintälinkit Toteutetaan, kun prosessit käyttävät tiettyä prosessitunnistetta viestintään, mutta lähettäjää on vaikea tunnistaa etukäteen.
Esimerkiksi tulostuspalvelin.
Epäsuora viestintä tehdään jaetun postilaatikon (portin) kautta, joka koostuu viestijonosta. Lähettäjä säilyttää viestin postilaatikossa ja vastaanottaja poimii ne.
Viesti kulkee viestien vaihdon kautta.
Synkroninen ja asynkroninen viestien välitys:
Estetty prosessi odottaa jotakin tapahtumaa, kuten resurssin vapautumista tai I/O-toiminnon valmistumista. IPC on mahdollista samassa tietokoneessa olevien prosessien välillä sekä eri tietokoneella toimivissa prosesseissa eli verkko-/hajautetussa järjestelmässä. Molemmissa tapauksissa prosessi voidaan estää tai olla estetty lähetettäessä viestiä tai yritettäessä vastaanottaa viestiä, joten viestin välitys voi olla estävää tai estävää. Esto harkitaan synkroninen ja lähetyksen esto tarkoittaa, että lähettäjä estetään, kunnes vastaanottaja vastaanottaa viestin. Samalla lailla, vastaanottamisen estäminen vastaanottaja estää, kunnes viesti on saatavilla. Ei-esto katsotaan asynkroninen ja Ei-estävä lähetys tarkoittaa, että lähettäjä lähettää viestin ja jatkaa. Vastaavasti Ei-estävä vastaanotto saa vastaanottajan vastaanottamaan kelvollisen viestin tai nollan. Huolellisen analyysin jälkeen voimme päätellä, että lähettäjälle on luonnollisempaa olla estoton viestin välityksen jälkeen, koska viesti voi olla tarpeen lähettää eri prosesseihin. Lähettäjä kuitenkin odottaa kuittauksen vastaanottajalta, jos lähetys epäonnistuu. Vastaavasti on luonnollisempaa, että vastaanottaja estää vastaanoton antamisen jälkeen, koska vastaanotetun viestin informaatiota voidaan käyttää jatkosuoritukseen. Samanaikaisesti, jos viestin lähetys epäonnistuu, vastaanottaja joutuu odottamaan loputtomasti. Siksi harkitsemme myös toista viestin välitysmahdollisuutta. Pohjimmiltaan on kolme suositeltua yhdistelmää:
- Lähetyksen estäminen ja vastaanottamisen esto
- Ei-esto lähetys ja Ei-esto vastaanotto
- Ei-esto lähetys ja esto vastaanotto (useimmiten käytetty)
Suorassa viestin välityksessä , Prosessin, joka haluaa kommunikoida, on nimettävä viestinnän vastaanottaja tai lähettäjä.
esim. lähetä (p1, viesti) tarkoittaa viestin lähettämistä p1:lle.
Samalla lailla, vastaanottaa (p2, viesti) tarkoittaa viestin vastaanottamista p2:lta.
Tässä viestintätavassa viestintäyhteys muodostetaan automaattisesti, joka voi olla joko yksi- tai kaksisuuntainen, mutta yhtä linkkiä voidaan käyttää yhden lähettäjän ja vastaanottajan parin välillä ja yhdellä lähettäjän ja vastaanottajan parilla ei saa olla enempää kuin yksi pari. linkkejä. Lähetyksen ja vastaanottamisen välinen symmetria ja epäsymmetria voidaan myös toteuttaa, eli joko molemmat prosessit nimeävät toisensa viestien lähettämistä ja vastaanottamista varten tai vain lähettäjä nimeää vastaanottajan viestin lähettämistä varten, eikä vastaanottajaa tarvitse nimetä lähettäjää. viestin vastaanottaminen. Tämän viestintätavan ongelmana on, että jos yhden prosessin nimi muuttuu, tämä menetelmä ei toimi.
Epäsuorassa viestin välityksessä , prosessit käyttävät postilaatikoita (kutsutaan myös portteiksi) viestien lähettämiseen ja vastaanottamiseen. Jokaisella postilaatikolla on yksilöllinen tunnus, ja prosessit voivat kommunikoida vain, jos niillä on yhteinen postilaatikko. Linkki muodostetaan vain, jos prosesseilla on yhteinen postilaatikko ja yksi linkki voidaan liittää useisiin prosesseihin. Kukin prosessipari voi jakaa useita viestintälinkkejä ja nämä linkit voivat olla yksi- tai kaksisuuntaisia. Oletetaan, että kaksi prosessia haluavat kommunikoida epäsuoran viestien välityksen kautta, vaadittavat toiminnot ovat: luo postilaatikko, käytä tätä postilaatikkoa viestien lähettämiseen ja vastaanottamiseen ja tuhoa sitten postilaatikko. Käytetyt perusprimitiivit ovat: Lähetä viesti) mikä tarkoittaa viestin lähettämistä postilaatikkoon A. Viestin vastaanottamisen primitiivi toimii myös samalla tavalla esim. vastaanotettu (A, viesti) . Tässä postilaatikon toteutuksessa on ongelma. Oletetaan, että useampi kuin kaksi prosessia jakavat saman postilaatikon ja oletetaan, että prosessi p1 lähettää viestin postilaatikkoon, mikä prosessi on vastaanottaja? Tämä voidaan ratkaista joko pakottamalla, että vain kaksi prosessia voi jakaa yhden postilaatikon, tai pakottamalla vain yksi prosessi suorittaa vastaanoton tiettynä ajankohtana tai valitsemalla mikä tahansa prosessi satunnaisesti ja ilmoittamalla lähettäjälle vastaanottajasta. Postilaatikko voidaan tehdä yksityiseksi yhdelle lähettäjä/vastaanottaja-parille, ja se voidaan myös jakaa useiden lähettäjä/vastaanottaja-parien kesken. Portti on sellaisen postilaatikon toteutus, jossa voi olla useita lähettäjiä ja yksi vastaanottaja. Sitä käytetään asiakas/palvelinsovelluksissa (tässä tapauksessa palvelin on vastaanotin). Portin omistaa vastaanottava prosessi ja käyttöjärjestelmä on luonut sen vastaanotinprosessin pyynnöstä ja se voidaan tuhota joko saman vastaanotinprosessorin pyynnöstä, kun vastaanotin lopettaa itsensä. Pakottaa, että vain yksi prosessi saa suorittaa vastaanoton, voidaan tehdä käyttämällä keskinäisen poissulkemisen käsitettä. Mutex postilaatikko luodaan, jonka jakaa n prosessi. Lähettäjä ei estä ja lähettää viestin. Ensimmäinen vastaanoton suorittava prosessi siirtyy kriittiseen osioon ja kaikki muut prosessit estävät ja odottavat.
Keskustellaan nyt tuottaja-kuluttaja -ongelmasta käyttämällä viestinvälityskonseptia. Tuottaja sijoittaa lähetykset (sisäviestit) postilaatikkoon ja kuluttaja voi kuluttaa lähetyksen, kun postilaatikossa on vähintään yksi viesti. Koodi annetaan alla:
Tuottajakoodi
C
void> Producer(>void>){> > >int> item;> >Message m;> > >while>(1){> > >receive(Consumer, &m);> >item = produce();> >build_message(&m , item ) ;> >send(Consumer, &m);> >}> >}> |
>
>
Kuluttajakoodi
C
void> Consumer(>void>){> > >int> item;> >Message m;> > >while>(1){> > >receive(Producer, &m);> >item = extracted_item();> >send(Producer, &m);> >consume_item(item);> >}> >}> |
>
>
Esimerkkejä IPC-järjestelmistä
- Posix: käyttää jaettua muistimenetelmää.
- Mach : käyttää viestin välitystä
- Windows XP : käyttää viestien välitystä paikallisten prosessikutsujen avulla
Viestintä asiakas/palvelin-arkkitehtuurissa:
On olemassa erilaisia mekanismeja:
- Putki
- Pistorasia
- Remote Procedural Calls (RPC:t)
Yllä olevia kolmea menetelmää käsitellään myöhemmissä artikkeleissa, koska ne kaikki ovat melko käsitteellisiä ja ansaitsevat omat erilliset artikkelinsa.
Viitteet:
- Käyttöjärjestelmäkonseptit, Galvin et ai.
- Luentomuistiinpanot/ppt: Ariel J. Frank, Bar-Ilan University
Prosessien välinen viestintä (IPC) on mekanismi, jonka kautta prosessit tai säikeet voivat viestiä ja vaihtaa tietoja keskenään tietokoneessa tai verkon yli. IPC on tärkeä osa nykyaikaisia käyttöjärjestelmiä, koska se mahdollistaa eri prosessien yhteistyön ja resurssien jakamisen, mikä lisää tehokkuutta ja joustavuutta.
IPC:n edut:
- Mahdollistaa prosessien kommunikoinnin toistensa kanssa ja resurssien jakamisen, mikä lisää tehokkuutta ja joustavuutta.
- Helpottaa useiden prosessien välistä koordinointia, mikä parantaa järjestelmän yleistä suorituskykyä.
- Mahdollistaa hajautettujen järjestelmien luomisen, jotka voivat kattaa useita tietokoneita tai verkkoja.
- Voidaan käyttää erilaisten synkronointi- ja viestintäprotokollien, kuten semaforien, putkien ja pistorasioiden toteuttamiseen.
IPC:n haitat:
- Lisää järjestelmän monimutkaisuutta ja vaikeuttaa suunnittelua, käyttöönottoa ja virheenkorjausta.
- Voi aiheuttaa tietoturva-aukkoja, koska prosessit voivat päästä käsiksi tai muokata muihin prosesseihin kuuluvia tietoja.
- Edellyttää järjestelmäresurssien, kuten muistin ja suorittimen ajan, huolellista hallintaa sen varmistamiseksi, että IPC-toiminnot eivät heikennä järjestelmän yleistä suorituskykyä.
Voi johtaa tietojen epäjohdonmukaisuuksiin, jos useat prosessit yrittävät käyttää tai muokata samoja tietoja samanaikaisesti. - Kaiken kaikkiaan IPC:n edut ovat haittoja suuremmat, sillä se on välttämätön mekanismi nykyaikaisille käyttöjärjestelmille ja mahdollistaa prosessien yhteistyön ja resurssien jakamisen joustavasti ja tehokkaasti. IPC-järjestelmien suunnittelua ja käyttöönottoa on kuitenkin huolehdittava mahdollisten tietoturva-aukkojen ja suorituskykyongelmien välttämiseksi.
Lisää viittauksia:
http://nptel.ac.in/courses/106108101/pdf/Lecture_Notes/Mod%207_LN.pdf
https://www.youtube.com/watch?v=lcRqHwIn5Dk