2 paskaita

45
Nijolė Sarafinienė 1 2 paskaita 2006 m.

description

2 paskaita. 200 6 m. Komunikacija tarp procesų (IPC). Operacinė sistema vienu metu gali vykdyti eilę tarpusavyje konkuruojančių taikomųjų programų. - PowerPoint PPT Presentation

Transcript of 2 paskaita

Page 1: 2 paskaita

Nijolė Sarafinienė 1

2 paskaita 2006 m.

Page 2: 2 paskaita

Nijolė Sarafinienė 2

Komunikacija tarp procesų (IPC)• Operacinė sistema vienu metu gali vykdyti eilę tarpusavyje

konkuruojančių taikomųjų programų.• Taikomosios programos gali aptarnauti daug vartotojų užklausų

vienu metu, šios užklausos gali ateiti iš procesų, besisukančių kitame hoste.

• Tarp-procesinis bendravimas – tai bendravimas tarp procesų, kurie vykdomi tame pačiame ar skirtinguose hostuose. Šiems procesams reikia komunikuot tarpusavyje.

• Tarp-procesinis bendravimas remiasi eile programinių sąsajų, kurios leidžia programuotojui kurti ir valdyti tokiam bendravimui orientuotas programas.

• Programinė sąsaja, kuri palaiko komunikacijas tarp procesų, užtikrina galimybę šiems procesams komunikuoti tarpusavyje

• Sąsajų programuotojui programuot nereikia.

• Sąsaja gali būti realizuojama įvairiais būdais, kiekvienas iš jų turi savus privalumus bei trūkumus.

• Vienoje programoje gali būti panaudoti keli tarp-procesinės sąsajos metodai. 

Page 3: 2 paskaita

Nijolė Sarafinienė 3

Komunikacija tarp procesų

• Komunikacija galima nebūtinai tinkle.• Jei procesai sukasi tame pačiame kompiuteryje, jie

gali pasinaudoti tam tikromis operacinės sistemos paslaugomis.

vart procesas

Vart procesas

Op sist. branduolys

Vart procesas

Vart procesas

Op sist. branduolys

Op sist. branduolys

Page 4: 2 paskaita

Nijolė Sarafinienė 4

Galimi šie tarp-procesinės sąsajos realizavimo metodai UNIX

• “pipes” ir “named pipes” (vamzdžiai ir įvardyti vamzdžiai)

• pranešimų eilės• semaforai • bendrai naudojama atmintis• soketai

Page 5: 2 paskaita

Nijolė Sarafinienė 5

Failai: I/O veiksmai, leidimaiI/O veiksmai vykdomi skaitant ar rašant tam tikrą duomenų bloką.Failai pradžioje yra atidaromi, baigus veiksmus yra uždaromi.Failo atidarymo metu yra grąžinamas failo deskriptorius, kuris yra sveikas skaičius.Šis skaičius – tai indeksas šio proceso atidarytų failų lentelėje

Veiksmai su failais vykdomi naudojant read, write funkcijas.#define SIZE 1024

char buf[SIZE]; src = open(infile, O_RDONLY); dst = creat(outfile, 0777);

while ((nread = read(src, buf, SIZE)) != 0) write(dst, buf, nread); Leidimų sistema UNIX:-rwxrwxrwx

-rw-r--r-- 1 os other 9 Jan 24 13:55 infile

Page 6: 2 paskaita

Nijolė Sarafinienė 6

Vamzdžiai

• Vamzdis yra naudojamas baitų srauto persiuntimui viena kryptimi.

• Vamzdis yra sukuriamas naudojant komandą “pipe”, kuri grąžina dviejų sveikų skaičių masyvą.

• Šie skaičiai – tai du failų deskriptoriai, kurie gali būti naudojami vykdant read, write veiksmus.

Page 7: 2 paskaita

Nijolė Sarafinienė 7

Vamzdžio sukūrimas: pipe() int pfd[2]; pipe(pfd);

write(pfd[1], buf, size); read(pfd[0], buf, SIZE);

read vykdomas iš šios pusės

write vykdomas šia kryptimi

Page 8: 2 paskaita

Nijolė Sarafinienė 8

fork() ir pipe()

Vienas procesas paprastai nenaudoja vamzdžio.Jis naudojamas kai du giminingi procesai nori komunikuoti vienos

krypties principu.Vamzdis turi būt sukuriamas prieš sudalant procesą.Procesas kuria naujus procesus- procesus vaikus naudodamas “fork”

kreipinį.Šie procesai galės keistis informacija naudodamiesi vamzdžiu.Prieš fork()

Page 9: 2 paskaita

Nijolė Sarafinienė 9

Po fork()

Page 10: 2 paskaita

Nijolė Sarafinienė 10

Gaunami du rašymo taškai ir du skaitymo taškai. Bet kuris iš procesų gali tiek rašyti į vamzdį, tiek iš jo skaityti.Tiksliam veiksmų nusakymui turi būti nutariama, kuris procesas rašys į

vamzdį, o kuris iš jo skaitys.Vienas iš procesų uždaro skaitymo tašką, kitas rašymo tašką

(deskriptorių).

Page 11: 2 paskaita

Nijolė Sarafinienė 11

Tarkim, tėvo procesas uždaro skaitymo deskriptorių.

Vaiko procesas uždaro rašymo deskriptorių.

Tėvas rašys į vamzdį, vaikas skaitys. Kai tėvas uždarys ir rašymo deskriptorių, vaiko procesas, bandydamas skaityti toliau, gaus EOF, tai žymės srauto pabaigą, taigi vaikas galės irgi uždaryti skaitymo deskriptorių

Page 12: 2 paskaita

Nijolė Sarafinienė 12

#include <stdio.h>#define SIZE 1024int main(int argc, char **argv){ int pfd[2]; int nread; int pid; char buf[SIZE]; if (pipe(pfd) == -1) { perror("pipe failed"); exit(1); } if ((pid = fork()) < 0) { perror("fork failed"); exit(2); }

if (pid == 0) { /* child */ close(pfd[1]); while ((nread = read(pfd[0], buf, SIZE)) != 0) printf("child read %s\n", buf); close(pfd[0]); } else { /* parent */ close(pfd[0]); strcpy(buf, "hello..."); /* include null terminator in write */ write(pfd[1], buf, strlen(buf)+1); close(pfd[1]); }

exit(0);}

Page 13: 2 paskaita

Nijolė Sarafinienė 13

Pipes -“vamzdžiai”• UNIX “pipe” mechanizmas naudojamas informacijos perdavimui

iš vieno proceso kitam. Duomenys siunčiami tik viena kryptimi. “pipe” perduoda vieno proceso išvedimą kitam procesui kaip įvedimo duomenis. Išvedami duomenys yra buferizuojami pakol įvedantis procesas juos paima. Procesai turi būt giminingi.

• UNIX shell’o (apvalkalo) atveju “pipe” mechanizmas nusakomas “|”.

• Programose “pipe” mechanizmas realizuojamas naudojant sisteminį kreipinį “pipe”.

• Norint sudaryti dviejų krypčių komunikacijas tarp procesų turi būti naudojami du vamzdžiai, po vieną kiekvienai krypčiai.

• Šio mechanizmo panaudojimą tarp-procesinei komunikacijai riboja tai, kad taip komunikuoti gali vaikų procesai, kurių tėvas bendras.

• Pipe atveju duomenų dydis negali būti didesnis nei 4,096 baitai.

Page 14: 2 paskaita

Nijolė Sarafinienė 14

Kas tas “pipe” mechanizmas? • Tai vienos krypties komunikavimo mechanizmas, vienas

jo galas yra atviras rašymui, kitas skaitymui. • Tėvas-vaikas turi sutarti kuria kryptim keliaus

informacija. Nors galima “pipe” naudoti siuntimui ir viena ir kita kryptim, tačiau tokia komunikacija yra komplikuota.

• Esant reikalui tėvas gali sukurti du “pipe” mechanizmus, juos naudojant atskira kryptimi.

• “pipe” – tai srautinio komunikavimo mechanizmas, t.y. visi siunčiami pranešimai sudedami iš eilės ir patikimai persiunčiami. Jei skaitant iš “pipe” pareikalaujamas tam tikras baitų kiekis, tai jis išskiriamas iš srauto – atėjęs jis gali būti per vieną ar kelis write() kreipinius.

Page 15: 2 paskaita

Nijolė Sarafinienė 15

UNIX shell naudoja pipePav: who | sort | lpr

write fd

who process

pipe

kernel

flow of data

write fd

read fd

sort process

read fd

lpr process

pipe

flow of data

Page 16: 2 paskaita

Nijolė Sarafinienė 16

dup pipe mechanizmas veikia, nes du procesai žino šio

vamzdžio abiejų taškų (rašymo ir skaitymo) failų deskriptorius.

Kiekvienas procesas turi standartinius deskriptorius: stdin (0), stdout (1) ir stderr (2).

Sekančių failų deskriptorių reikšmės priklauso nuo to, kiek yra atidarytų failų ir gali būti pavyzdžiui 3 ar 4.

Negiminingi procesai, net ir procesai, kurie keičia egzistuojantį procesą per exec f-jas nežino, kurie deskriptoriai priklauso vamzdžiui.

Page 17: 2 paskaita

Nijolė Sarafinienė 17

Pavyzdys:

Kuriamas vamzdis:``ls | wc'' Shelo procesas irgi turi sukurti vamzdį, o po to vykdyti fork

ir kurti kitą procesą.Turi veikti du procesai: ls ir wcTėvo procesas vykdant exec yra pakeičiamas “ls” procesu,Vaiko procesas, vykdant exec – “wc” procesuTarkim rašymo į vamzdį deskriptorius yra 4, o skaitymo 3.Komanda ls paprastai rašymui naudoja 1deskriptorių.Komanda wc paprastai skaito iš 0 deskriptoriausKaip visa tai suderinama?

Page 18: 2 paskaita

Nijolė Sarafinienė 18

pipe

pipe

pipe

sh

sh

sh sh

exec exec

ls | wc

ls

wc

Page 19: 2 paskaita

Nijolė Sarafinienė 19

Page 20: 2 paskaita

Nijolė Sarafinienė 20

Naudojama ``dup2(d1,d2)'' funkcija, kuri d1 reikšmę sutapatina su d2 reikšme.Tikslinga fd =3 pakeisti į 1, ir fd=4 pakeisti į 0.tada senos fd=3 ir fd=4 nenaudojamos.

Page 21: 2 paskaita

Nijolė Sarafinienė 21

Po dup2()

Page 22: 2 paskaita

Nijolė Sarafinienė 22

Programos pavyzdys

int main(void) { int pfd[2]; pipe(pfd); if (fork() == 0)

{ /* vaikas */close(pfd[1]); dup2(pfd[0], 0); close(pfd[0]); execlp("wc", "wc", (char *) 0); }

else { /* tevas */close(pfd[0]); dup2(pfd[1], 1); close(pfd[1]); execlp("ls", "ls", (char *) 0); } }

Page 23: 2 paskaita

Nijolė Sarafinienė 23

Įvardyti vamzdžiai

• Tai vamzdis su specifiniu vardu.

• Juo gali naudotis negiminingi procesai.

• Pranešimą, nusiųstą į šio tipo vamzdį gali skaityti bet koks autorizuotas procesas, kuris žino įvardyto vamzdžio vardą.

• Įvardyti vamzdžiai kartais vadinami FIFO, kadangi tie duomenys, kurie pirmi buvo įrašyti į vamzdį, pirmi ir bus nuskaityti.

Page 24: 2 paskaita

Nijolė Sarafinienė 24

FIFO

• FIFO (First in, First Out) mechanizmas yra panašus į pipe

• Srautas vienos krypties

• Pirmas įrašytas baitas ir skaityme bus pirmas

• Priešingai nei pipe, FIFO turi su juo susijusį vardą

• Sukuriama mknod sisteminiu kreipiniu (jis paprastai yra skiriamas supervartotojui ir naudojamas kuriant naują įrenginį , tačiau kiti vartotojai šiuo kreipiniu gali kurti FIFO).

int mknod (char *pathname, int mode, int dev);

ignoruojama FIFO atv

Page 25: 2 paskaita

Nijolė Sarafinienė 25

FIFO• Sukūrus FIFO, jis turi būti atidaromas skaitymui arba

rašymui…– Yra trys sisteminiai kreipiniai, tam kad sukurti FIFO ir atidaryti jį

skaitymui ir rašymui, kai tuo tarpu vienas pipe sisteminis kreipinys darė tą patį.

– Normaliai, FIFO atidarymas (open) vien skaitymui (read) be rašančių procesų, ar FIFO atidarymas rašymui be skaitančių procesų yra blokuojantys sisteminiai kreipiniai.

– O_NDELAY opcija yra naudojama blokavimui nuimti…

• Jei rašymo į FIFO ar PIPE dydis yra mažesnis nei FIFO ar pipe dydis(4,096 B), tai yra garantuojama, kad šis veiksmas yra nepertraukiamas ( atomic).

Rašymo ir skaitymo funkcijos nekinta: read, write

Page 26: 2 paskaita

Nijolė Sarafinienė 26

FIFO#include <sys/types.h>#include <sys/stat.h>#include <sys/errno.h>extern int errno;

#define FIFO1 “/tmp/fifo.1”#define FIFO2 “/tmp/fifo.2”#define PERMS 0666

main(){

int childpid, readfd, writefd;

if ( (mknod(FIFO1, S_IFIFO|PERMS, 0)<0) && (errno!=EEXIST) )err_sys (“Can’t create fifo 1: %s”, FIFO1);

if ( (mknod(FIFO2, S_IFIFO|PERMS, 0)<0) && (errno!=EEXIST) ) {

unlink (FIFO1);err_sys (“Can’t create fifo 2: %s”, FIFO2);

}

if ( (childpid=fork()) < 0 )sys_err (“can’t fork”);

Iš <sys/stat.h> specifikuojant FIFOKuri yra kuriama

Page 27: 2 paskaita

Nijolė Sarafinienė 27

FIFOelse if (childpid>0) { /* parent */

if ( (writefd = open(FIFO1, 1)) < 0 )err_sys (“Parent: can’t open write fifo”);

if ( (readfd = open(FIFO2, 0)) < 0 )err_sys (“Parent: can’t open read fifo”);

client (readfd, writefd);

while (wait((int *) 0) != childpid); /* wait for child

*/

close (readfd);close (writefd);

if (unlink(FIFO1) < 0)err_sys (“Parent: Can’t unlink %s”, FIFO1);

if (unlink(FIFO2) < 0)err_sys (“Parent: Can’t unlink %s”, FIFO2);

exit (0);

Page 28: 2 paskaita

Nijolė Sarafinienė 28

FIFO

} else { /* child */

if ( (readfd = open(FIFO1, 0)) < 0 )err_sys (“Parent: can’t open read fifo”);

if ( (writefd = open(FIFO2, 1)) < 0 )err_sys (“Parent: can’t open write fifo”);

server (readfd, writefd);

close (readfd);close (writefd);exit (0);

}

}

Page 29: 2 paskaita

Nijolė Sarafinienė 29

FIFO

• Siekiant išvengti mirties taško yra svarbi eilės tvarka, kuria yra vykdomi open kreipiniai kliento bei serverio dalyje!…– Arba galima pasinaudoti O_NDELAY alternatyva

• Naudojant FIFO, gali būti naudojamos dvi skirtingos programos/procesai, kurie nebūtinai eina iš vieno tėvo ir yra atsiradę per fork() kreipinį.

Page 30: 2 paskaita

Nijolė Sarafinienė 30

FIFO• Tiek pipe, tiek FIFO atveju siunčiami

duomenys yra interpretuojami kaip ištisinis baitų srautas, į jo struktūrą persiuntimo metu nėra kreipiamas dėmesys.– Skaitantis procesas, skaitydamas 100B, negali

pasakyti ar tie baitai įrašyti per vieną ar kelis write veiksmus, vieno – ar kelių procesų.

– Pačios aplikacijos turi susitarti dėl duomenų, kuriais yra keičiamasi struktūros.

Page 31: 2 paskaita

Nijolė Sarafinienė 31

System V IPC

• Pranešimų eilės• Semaforai• Dalinamasi atmintis

char *path

char projftok()

key_t key msgget()semget()shmget()

int id

int flag

Visais šiais atvejais pradžioje yra sugeneruojamas tarpprocesinio komunikavimo raktas, kurio tipas yrakey_t, ir kuris yra sukuriamas vienareikšmiškas, jei nurodomi tokie patys argumentai

#include <sys/types.h>#include <ipc.h>

key_t ftok (char *pathname, char proj);

Pathname yra nuoroda į failą, project ID dydžiu galima nurodyti vyriausią rakto (key) baitą ir naudoti sekančius baitus kaip eilės numerius.

Rakto reikšmė yra naudojama tiek veiksmuose su pranešimų eilėmis, tiek veiksmuose su semaforais, tiek su dalinamasi atmintimi.

Page 32: 2 paskaita

Nijolė Sarafinienė 32

Pranešimų eilė (Message queuing)

     Programavime procesai gali naudoti “message queueing” mechanizmą norėdami perduoti duomenis ar pasikeisti duomenimis per sistemos valdomas pranešimų eiles. Pranešimai gali būt įvairaus tipo , jie gali būt įvairiai panaudojami.

•Pranešimų eilė gali būti sukurta vieno proceso ir naudojama daugelio procesų, kurie skaito/rašo pranešimus.

•Pavyzdžiui serverio procesas gali skaityti ar rašyti pranešimus į pranešimų eilę, skirtą kliento procesui. Pranešimo tipas gali būti panaudojamas pranešimo surišimui su atitinkamu kliento procesu net jei visi pranešimai yra vienoje eilėje.

•Pranešimų eilę tvarko sistemos branduolys. Aplikacijų programos (jų procesai) sukuria pranešimų eiles ir siunčia į jas pranešimus arba gauna iš jų pranešimus naudodamos aplikacinių programų sąsają (API)

• UNIX sistemoje C kalbos f-ja msgget su įvairiais parametrais yra naudojama nusakant kokius veiksmus reikia atlikti, su kokia pranešimų eile ir ...

•Maksimalus pranešimo ilgis eilėje yra ribojamas operacinės sistemos ir paprastai jis yra <= 8,192 baitų.

Page 33: 2 paskaita

Nijolė Sarafinienė 33

Pranešimų eilės

• Kliento-serverio modelis naudojant dvi pranešimų eiles:

#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>

#include <sys/errno.h>extern int errno;

#define MKEY1 1234L#define MKEY2 2345L

#define PERMS 0666

Page 34: 2 paskaita

Nijolė Sarafinienė 34

Pranešimų eilės

• Serveris

main(){

int readid, writeid;

/* create message queues if required */

if ( (readid=msgget(MKEY1, PERMS|IPC_CREAT)) < 0 )err_sys (“Server: Can’t get message queue 1”);

if ( (writeid=msgget(MKEY2, PERMS|IPC_CREAT)) < 0 )err_sys (“Server: Can’t get message queue 2”);

server (readid, writeid);

exit(0);}

Page 35: 2 paskaita

Nijolė Sarafinienė 35

• Klientas

main(){

int readid, writeid;

/* open message queues, server must have already created them */

if ( (writeid=msgget(MKEY1, 0)) < 0 )err_sys (“Client: Can’t get message queue 1”);

if ( (readid=msgget(MKEY2, 0)) < 0 )err_sys (“Client: Can’t get message queue 2”);

client (readid, writeid);

/* delete message queues */if (msgctl(readid, IPC_RMID, (struct msqid_ds *)0)<0)

err_sys (“Client: Can’t RMID message queue 1”);if (msgctl(writeid, IPC_RMID, (struct msqid_ds *)0)<0)

err_sys (“Client: Can’t RMID message queue 2”);

exit(0);}

Page 36: 2 paskaita

Nijolė Sarafinienė 36

• Klientas ir serveris naudojasi sekančiomis funkcijomis: msgsnd-pranešimų siuntimas

• msgrcv- pranešimų priėmimas

msg_send (int id, Mesg *mesgptr){

if (msgsnd(id, (char *) &(mesgptr->mesg_type), mesgptr->mesg_len

, 0)!=0)err_sys (“msgsnd error”);

}

int msg_recv (int id, Mesg *mesgptr){

int n;

n = msgrcv(id, (char *) &(mesgptr->mesg_type), MAXMESGDATA , mesgptr->mesg_type,

0);if ( (mesgptr->mesg_len=0) < 0 )

err_sys (“msgrcv error”);

return (n); /* n to be 0 at the end of the file */}

Page 37: 2 paskaita

Nijolė Sarafinienė 37

semaforai• Jie naudojami siekiant išspręsti sinchronizacijos problemas. • Programuojant UNIX aplinkoje semaforai yra naudojami sprendžiant

sinchronizavimo bei koordinavimo problemas, kurios atsiranda kai keletas procesų varžosi dėl tų pačių operacinės sistemos resursų.

• Semaforai įgyja sveikas teigiamas arba lygias 0 reiksmes. Jie saugomi operacinės sistemos atmintyje,kiekvienas procesas gali juos patikrinti bei pakeisti. Priklausomai nuo to kokią semaforo reikšmę procesas randa, jis gali naudotis atitinkamu resursu arba resursas yra užimtas ir procesas turi palaukti kažkiek ir po to vėl bandyti tikrinti semaforo reikšmę.

• Semaforai pagrinde naudojami dviem tikslais:– dalantis bendra atminties erdve arba– dalantis priėjimu prie failų.

• Semaforai yra viena iš priemonių realizuojant tarp-procesines komunikacijas. C kalba turi atitinkamas funkcijas, skirtas veiksmams su semaforais.

Page 38: 2 paskaita

Nijolė Sarafinienė 38

Bendrai naudojama atmintis• Leidžiama keistis duomenimis naudojant tam išskirtą sritį. Semaforai

naudojami priėjimo prie šios srities reguliavimui.• bendrai naudojama atmintis – tai metodas, kuriuo naudodamiesi

programų procesai gali keistis duomenimis greičiau nei naudodami skaitymą/rašymą per operacinės sistemos servisus. Pavyzdžiui, klientinis procesas gali norėti perduoti duomenis serverio procesui, serverio procesas juos modifikuos ir grąžins kliento procesui.

•  Paprastai tai reikalauja, kad klientas rašytų į išvedimo failą (naudojamas operacinės sistemos buferis) ir serveris skaitytų šį failą iš buferio į savo darbinę sritį. Naudojant išskirtą bendro naudojimo sritį duomenys tampa tiesiogiai prieinamais abiems procesams

• Norint įdėti duomenis į bendrą sritį, klientinis procesas gauna priėjimą prie šios srities patikrindamas semaforo reikšmę, įrašo duomenis, bei suaktyvina semaforą pranešdamas serveriui ( kuris periodiškai tikrina šią atmintį ieškodamas įvedimo) , kad duomenys laukia. Serveris iš savo pusės, pakeitęs – modifikavęs duomenis įrašo juos atgal į bendrai naudojamą atmintį ir naudoja semaforą pranešdamas apie tai, kad duomenys yra paruošti.

Page 39: 2 paskaita

Nijolė Sarafinienė 39

Bendrai naudojama atmintis Bendrai naudojama atmintis – tai tam tikra atminties

dalis adresinėje erdvėje, kuri gali būti adresuojama iš dviejų ar daugiau procesų.

Jei vienas procesas padaro pakeitimus šioje atmintyje, tai tai atsispindi abiems procesams.

Pavyzdys:#include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, int size, int shmflg); char *shmat(int shmid, char *shmaddr, int shmflg);

int shmdt(char *shmaddr);

Page 40: 2 paskaita

Nijolė Sarafinienė 40

shmget yra naudojama sukuriant bendrai naudojamą atmintį.

Ši atmintis yra identifikuojama raktu, kuris yra sveikas skaičius ir dėl kurio susitaria visi procesai, kurie naudosis šiuo atminties gabalu.

Jie gali nustatyti tokios atminties dydį ir leidimus (pav: -rwx------).

shmat ima bendrai naudojamos atminties identifikatorių ir jį atvaizduoja į šio proceso adresinę erdvę, grąžindamas nuorodą į ją. Nuo to momento ši nuoroda gali būt naudojama kaip bet kuri nuoroda į atmintį.

shmdt atskiria šią sritį nuo proceso adresinės erdvės.

Page 41: 2 paskaita

Nijolė Sarafinienė 41

Example:This program forks, creates shared memory on one side and just uses it on the other. The creating side writes the alphabet into this and the other side reads it

#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>int main(void){ int shmid; char *shmPtr; int n; if (fork() == 0)

{ sleep(5); shmid = shmget(2041, 32, 0); if (shmid == -1) exit(1); shmPtr = shmat(shmid, 0, 0); if (shmPtr == (char *) -1) exit(2); for (n = 0; n < 26; n++) putchar(shmPtr[n]); putchar('\n'); } else { shmid = shmget(2041, 32, 0666 | IPC_CREAT); if (shmid == -1) exit(1);

shmPtr = shmat(shmid, 0, 0); if (shmPtr == (char *) -1) exit(2); for (n = 0; n < 26; n++) shmPtr[n] = 'a' + n; for (n = 0; n < 26; n++) putchar(shmPtr[n]); putchar('\n'); wait(NULL); shmdt(shmid); } exit(0);}

Page 42: 2 paskaita

Nijolė Sarafinienė 42

Soketai

• Šis metodas pagrinde naudojamas komunikacijų palaikymui tinkle.

• Palaikomas ryšys tarp serverio ir kliento aplikacijų.• Soketai yra apibrėžiami kaip galiniai komunikavimo

taškai.• Soketai yra sukuriami ir naudojami naudojant programines

užklausas – f-jas (API – aplikacijų programinė sąsaja).• Soketai gali būti naudojami komunikavimui palaikyti tarp

procesų, kurie sukasi ir tame pačiame kompiuteryje.

Page 43: 2 paskaita

Nijolė Sarafinienė 43

include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#define DATA1 "In Xanadu, did Kublai Khan . . .“#define DATA2 "A stately pleasure dome decree . . .“ main(){ int sockets[2], child; char buf[1024]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) < 0) { perror("opening stream socket pair"); exit(1); } if ((child = fork()) == -1) perror("fork"); else if (child) { /* This is the parent. */ close(sockets[0]); if (read(sockets[1], buf, 1024, 0) < 0) perror("reading stream message"); printf("-->%s\n", buf); if (write(sockets[1], DATA2, sizeof(DATA2)) < 0) perror("writing stream message"); close(sockets[1]); } else { /* This is the child. */ close(sockets[1]); if (write(sockets[0], DATA1, sizeof(DATA1)) < 0) perror("writing stream message"); if (read(sockets[0], buf, 1024, 0) < 0) perror("reading stream message"); printf("-->%s\n", buf); close(sockets[0]); }} Figure :Use of a socketpair

Page 44: 2 paskaita

Nijolė Sarafinienė 44

socketpair()

• Galima gauti porą surištų galinio komunikavimo taškų dvipusei srautinei komunikacijai pasinaudojus kvietinį

• socketpair(). • socketų pora yra tiesiog “pipe” mechanizmo

išplėtimas• Jas galima naudoti tik UNIX domene. The UNIX

domenas naudoja įprastus UNIX kelių vardus soketų įvardijimui.

Page 45: 2 paskaita

Nijolė Sarafinienė 45