Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Comunicatia prin PIPE
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 

 

Pipe-urile sunt canale de comunicatie intre procese, informatia trecind de la un proces la altul printr-un mecanism FIFO (COMMAND.COM implementeaza o astfel de tehnica). In DOS executia are loc secvential, in timp ce in UNIX executia are loc concurent, comunicatia fiind directa. Pipe-uri pot fi create si in shell-ul Unix, ca si in DOS, prin concatenarea mai multor comenzi pe aceeasi linie separate de "|". Prin program se pot crea legaturi circulare intre procese (bidirectional). Apelul SC(System Call) cu care se creeaza un pipe este

int pipe(pdescr); Valoarea returnata este 0 in caz de succes int pdescra2i; si -1 in caz de eroare.

Fiind un canal bidirectional de comunicatie in care se pot scrie date si se pot citi date, apelul trebuie sa intoarca 2 descriptori de fisier, astfel ca avem tabloul cu 2 elemente intregi care va contine la intoarcerea din SC cei 2 descriptori, primul pentru citire si al doilea pentru scriere. Programul poate folosi cei 2 descriptori ca cei pentru fisiere, asupra carora se pot aplica apelurile read, write, close, fcntl, fstat. Apelurile open si creat nu se folosesc pentru pipe, la fel lseek (datele se citesc in ordinea in care au fost scrise).

ÚAAAAAAAAAAA¿ ÚAAAAAAAAAAA¿ y7o20oz
³ Proces_1 ³ ³ Proces_2 ³
AAAAAAAAAAAAÙ AAAAAAAAAAAAÙ
³ write(pdescra1i,...) ³ read(pdescra0i,...)
-----------AAAAA¿---------------------ÚAAAAÙ----------------------- Kernel ³ ³
ÚAAAAAAAAAAAAAAAAAAAAAAAAAAA¿
³ ³ ³ ³ ³ pipe ³ ³ ³ ³
AAAAAAAAAAAAAAAAAAAAAAAAAAAAÙ

Descriptorii de pipe au o dimensiune redusa de memorie (cca. 4 Ko).
Astfel, daca se scriu mai multi octeti decit este liber, write se blocheaza pina cind cineva goleste pipe prin citire, write reluindu-se pina la terminare
(afara de setarea prin fcntl a comutatorului O_NDELAY). Un apel read se termina chiar daca nu a gasit toti octetii de care avea nevoie (valoare de retur=numarul de octeti cititi). In singurul caz ca pipe-ul este gol, read se blocheaza pina la sosirea unor date (exceptie tot cu O_NDELAY setat). Daca dorim sa semnalam procesului cu care comunicam ca s-a atins sfirsitul de fisier, trebuie sa inchidem canalul cu SC close. SC fstat returneaza numarul de octeti disponibili in pipe la un moment dat (este foarte dinamic). Fstat este util la testarea daca un descriptor de fisier corespunde sau nu unui pipe, testind daca numarul de legaturi este 0. Pipe foloseste acelasi mecanism de cache care se foloseste si pentru fisierele de pe discuri. Scrierea si citirea sint operatii atomice (scrierea este cu 512 octeti in general, citirea cu <=512).
In primul program acelasi proces scrie si citeste mai tirziu din pipe.
/*p1.c*/
#include <stdio.h>




void main()
A int pdescra2i; char buffera256i; int nr; char *mesaj="sir de caractere"; if(pipe(pdescr)==-1)
A perror("eroare deschidere pipe\n"); exit(1);
S strcpy(buffer,mesaj); if(write(pdescra1i,buffer,strlen(mesaj)+1)==-1)
A perror("eroare write pipe\n"); exit(1);
S switch(nr=read(pdescra0i,buffer,sizeof(buffer)))
A case -1: perror("eroare read pipe\n") exit(1); case 0: printf("Eroare EOF\n"); exit(1); default: printf("Am citit %d octeti : %s\n",nr,buffer);
S
S

Daca dimensiunea blocului de scris este mai mare decit dimensiunea pipe-ului, se poate produce deadlock (se poate totusi rezolva prin citirea unor octeti din pipe). Un pipe unidirectional nu poate duce niciodata la deadlock total.
Cind avem un pipe intre doua procese, cel care citeste trebuie sa fie un fiu al procesului care a deschis pipe-ul pentru a mosteni descriptorii de fisiere
(inclusiv al pipe-ului), sau ambele procese fiu al aceluiasi tata. Daca unul din procese doar scrie iar celalat doar citeste, atunci avem pipe unidirectional.
/*p2.c*/
#include <stdio.h>

void main ()
A int pdescra2i; char buffera250i; if(pipe(pdescr)==-1)
A perror("eroare deschidere pipe\n"); exit(1);
S switch(fork())
A case -1 : perror("eroare fork\n"); exit(1); case 0 : /* fiu */ if(close(pdescra1i)==-1)
A perror("eroare close pipe scriere\n"); exit(1);
S sprintf(buffer,"%d",pdescra0i); execlp("./p3","p3",buffer,NULL); perror("eroare execlp\n"); exit(1);
S if(close(pdescra0i==-1)
A perror("eroare close pipe citire\n"); exit(1);
S if(write(pdescra1i,"Hello !",7)==-1)
A perror("eroare write pipe\n"); exit(1);
S
S
S

/*p3.c*/
#include <stdio.h> void main(argc,argv) inr argc; char **argv;
A int fd,nr; char buffera256i; fd=atoi(argva1i);

switch(nr = read(fd,buffer,sizeof(buffer)));
A case -1; perror("eroare read\n"); exit(1); case 0; printf("Nu am atins sfirsitul fisierului pipe \n"); exit(1); default : printf("Am citit %d octeti %s \n",nr,buffer);
S
S

In primul proces dupa fork, in cazul ca ne gasim in fiu, canalul de scriere in pipe este inchis. Aceasta pentru ca cel de-al doilea proces nu va scrie niciodata in pipe si in acest caz este mai bine sa eliberam descriptorul de fisiere, care face parte dintr-o resursa limitata (20 de descriptori de proces).
Aceasta situatie este inainte de exec pentru ca dupa aceasta, desi fisierul ramine deschis, p3 nu stie care este acel descriptor. Programul p3 nu stie nici unde se gaseste descriptorul de citire, de acea acesta si este transmis ca parametru in linia de comanda (nu este cea mai buna metoda !). In procesul tata, la revenirea din fork, se inchide canalul de citire, pentru ca tatal nu va citi niciodata din pipe. De aceea, intre SC fork si exec se mai pot face unele prelucrari, care facute in alta parte ar insemna mult mai mult efort.
Pentru a opri blocarea lui write in cazul ca pipe este plin, putem folosi apelul fcntl:

#include <fcntl.h>

if(fcntl(fd,F_SETFL,O_NDELAY)<0) perror("eroare fcntl\n");

Astfel oprim blocarea daca fd este descriptorul fisierului de scrire din pipe.
Daca descriptorul de apel este cel de citire, read nu se va mai bloca cind canalul este gol, intorcind valoarea zero. (Atentie! read intoarce zero si la sfirsitul fisierului). Problema din programul p3 era ca descriptorul de fisier se transmite ca parametru in linia de comanda, ceea ce limiteaza foarte mult aplicabilitatea sistemului. Solutia mai buna ar reprezenta-o fisierele standard de intrare/iesire: trebuie aranjate in asa fel lucrurile incit programul p3 sa stie exact locul descriptorului de citire, fara ca acesta sa-i vina pe linia de comanda. Programele care respecta aceste reguli isi iau datele din stdin(0) si se scriu in stdout(1). Acest tip de programe sunt asa numitele filtru (more,pg,tee,sort). Din pacate la apelul pipe nu vom sti exact unde vor fi deschisi cei doi descriptori de fisier. Pentru rezolvarea acestei probleme s-a introdus SC dup, avind urmatoarea sintaxa:

int dup(fd); int fd;

Apelul face duplicarea unui descriptor de fisier, dupa apel putindu-se accesa fisierul deschis in fd, si prin descriptorul intors de dup. Particularitatea acestui apel, care este folositoare in situatia prezentata, este ca dup asigura ca descriptorul intors este cel cu numarul minim dintre cele neutilizate. Astfel daca inainte de dup am inchis descriptorul 0 (stdin), dup va intoarce cu siguranta 0, daca am inchis 1 si 0 este utilizat (in majoritatea cazurilor), dup va intoarce 1. Dup intoarce -1 in caz de eroare. In programul urmator se lanseaza doua procese interconectate printr-un pipe unidirectional (unul scrie altul citeste - asemanator cu mecanismul utilizat de shell pentru a lansa doua comenzi legate printr-un pipe).

/*p4.c*/

#include <stdio.h>

void main(argc,argv) int argc; char **argv;
A int pdescra2i; int status;

if(argc == 3) printf("Utilizarea unui pipe intre doua procese fiu\n"); else exit(1); if(pipe(pdescr)==-1)
A perror("eroare deschidere pipe\n"); exit(1);

S switch(fork(0)) :
A case -1 : perror("eroare fork 1\n"); exit(1); case 0 :
/* primul fiu */ close(pdescra0i); close(1); if(dup(pdescra1i)!=1)
A perror("eroare dup1\n"); exit(1);
S close(pdescra1i); execlp(argva1i,argva1i,NULL); perror("eroare execlp 1\n"); exit(1);
S switch(fork(0)) :
A case -1 : perror("eroare fork 2\n"); exit(1); case 0 :
/* al doilea fiu */ close(pdescra1i); close(0); if(dup(pdescra0i)!=0)
A perror("eroare dup2\n"); exit(1);
S close(pdescra0i); execlp(argva2i,argva2i,NULL); perror("eroare execlp 2\n"); exit(1);
S

/* in tata */ close(pdescra0i); close(pdescra1i);
wait(&status);
/* asteapta terminarea primului fiu */
wait(&status);
/* asteapta terminarea celui de al doilea fiu */
S

In cazul cind dorim crearea unui pipe bidirectional (poate duce la deadlock total), trebuie create doua pipe-uri (unul pentru citire/scrire, altul scriere/citire). Descriptorii de fisier blocati sunt tot doi pentru fiecare proces, ceilalti doi putind fi inclusi ca in exemplele anterioare.

FIFO

Un FIFO combina trasaturile unui pipe cu acelea ale unui fisier. Ca si fisierul, FIFO-ul are un nume, o pozitie in sistemul de fisiere si poate fi accesat de orice proces care are drepturi asupra lui. Spre deosebire de pipe-urile clasice, cu ajutorul unui FIFO pot comunica oricare doua procese indiferent de relatia lor de rudenie. Din momentul in care a fost deschis insa, FIFO se comporta ca pipe. Datele se pot citi in ordinea FIFO, apelurile de tip read/write fiind atomice, cu conditia sa nu depaseasca capacitatea FIFO-ului
(>=4 ko). Lseek nu are are efect iar datele nu mai pot fi scrise inapoi. Atunci cind un FIFO este deschis pentru citire, kernelul asteapta pina cind un alt proces deschide acelasi FIFO pentru scriere (se asteapta unul pe altul la deschiderea canalului de comunicatie, rendez-vous, sincronizat inaintea comunicatiei propiu-zise). La fel ca la pipe se poate folosi apelul fcntl pentru a seta flagul O_NDELAY. In acest caz deschiderea pentru citire returneaza imediat, fara sa astepte ca FIFO-ul sa fie deschis pentru scriere, in timp ce deschiderea pentru scriere returneaza eroare (kernelul nu poate garanta pastrarea permanenta a datelor care se inscriu in FIFO-ul care nu este citit imediat). In plus, la inchiderea canalului de comunicatie fara comunicarea tuturor datelor scrise, acestea se pierd fara a se indica eroare.
Flagul O_NDELAY afecteaza apelurile de citire/scriere ca la pipe-urile clasice.
Crearea unui FIFO se face cu mknod:

#include <sys/types.h>
#include <sys/stat.h> init res; char *path; res=mknod(path,S_IFIFO|0666,0);

res = 0 - in caz de succes res = 1 - in caz de eroare

Path reprezinta numele FIFO (la fel ca la fisiere) si 0666 drepturi de acces.

Mknod foloseste pentru crearea unor fisiere normale, a unor subdirectoare, sau a unor fisiere speciale, dar aceste facilitati sunt accesibile numai supervizorului. Parametrul S_IFIFO este accesibil oricarui user. Cu fstat putem prelua starea unui FIFO deschis anterior, iar cu stat starea unui FIFO nedeschis inca.

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

int res,fd; char *path; struct stat *sbuf ; res = fstat(fd,sbuf); // res=0 succes; res=1 eroare res = stat(path,sbuf);

Informatiile obtinute prin aceste apeluri : lungime (cite caractere sunt in FIFO), timpul/data de creare, actualizare, numarul de Inode, numarul de legaturi (links=0 pentru pipe clasic, acesta neexistind pe disc), uid, gid, etc. O prima aplicare a FIFO este de a implementa un pipe clasic. In locul SC vom deschide FIFO de doua ori, odata pentru scriere si odata pentru citire si apoi putem trata cei doi descriptori ca la pipe clasic. De fapt FIFO s-au introdus nu pentru a inlocui pipe ci mesajele.

/*p4*/
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>

#define MAXOPEN 7
#define MAXTRIES 3
#define NAPTIME 5
#define FALSE 0
#define TRUE 1

static char *fifoname(key) /*creeaza un nume de fisier temporar */ long key;
A static char fifoa20i; sprintf(fifo,"/temp/fifo%ld ",key); return fifo;
S

static int mkfifos(path) /* creeaza un FIFO */ char *path;
A return mknod(path,S_IFIFO|0666,0);
S

static int openfifo(key,flags) long key; int flags;
A static struct
A long key; int fd; int time;
SfifosaMAXOPENi;

static int clock ; int i,avail,oldest,fd,tries; char *fifo; extern int errno; avail=-1; /* caut_ un loc liber */ for(i=0;i<MAXOPEN;i++)
A if(fifosaii.key==key)
A fifosaii.time=clock; return fifosaii.fd;
S if(fifosaii.key==0 && avail==-1) avail=i;
S if(avail==-1) /* daca nu foloseste cel mai vechi */
A oldest=-1; for(i=0;i<MAXOPEN;i++) if(oldest==-1 || fifosaii.time < oldest) oldest=fifosaii.time; avail=i; if(close(afifosaavaili.fd)==-1) return -1;
S fifo=fifoname(key); if(mkfifos(fifo)== -1 && errno != EEXIT) return -1; for(tries=1;tries < MAXTRIES;tries++)
A if((fd=open(fifo,flags|O_NDELAY)) != -1) break; if(errno != ENXIO) return -1; sleep(NAPTIME);
S if(fd == -1)

A errno=ENXIO; return -1;
S if(fcntl(fd,F_SETFL,flags)== -1) /* reseteaza O_NDELAY */ return -1; fifosaavaili.key=key; fifosaavaili.fd=fd; fifosaavaili.time=clock; return fd;
S

int send(dstkey,buf,nbytes) /* trimite un mesaj */ long dstkey; char* buf; int nbytes;
A int fd; if ((fd=openfifo(dstkey,O_WRONLY)== -1) return FALSE; return write(fd,buf,nbytes) != -1;
S

int receive(srckey,buf,nbytes) /* primeste un mesaj */ long srckey; char* buf; int nbytes;
A int fd,nread; if((fd=openfifo(srckey,O_RDONLY))==-1) return FALSE;
while((nread=read(fd,buf,nbytes))==0) sleep(NAPTIME); return nread != -1 ;
S

void rmqueue(key) long key;
A int errno ; if(unlink(fifoname(key)) == -1 && errno != ENOENT) perror("eroare unlink\n");
S

/* Receive.c */

#include"mesaje.h"

void main()
A
MESSAGE m; setbuf(stdout,NULL);
while(receive(1000L,&m,sizeof(m))) printf("Received %d from %d \n ",m.number,m.pid); perror("eroare receive !\n"); exit(1);
S

/* Send.c */

#include"mesaje.h"

void main()
A
MESSAGE m; m.pid=getpid(); for(m.number = 1 ; m.member <= 4; m.number++)
A sleep(1); if(!send(1000L,&m,sizeof(m))) perror("eroare send !\n");
S
S

/* Mesaje.h */

typedef struct
A long unused; int pid; int number;
SMESSAGE;

Mesaje

Sub UNIX V exista 3 metode de comunicatie intre procese : mesaje, semafoare, memorie partajata. Implementarea acestor mecanisme este optionala, de aceea ele lipsesc din unele nuclee. Dar daca kernelul Unix le implementeaza, ele trebuie sa respecte o interfata cu aplicatiile, care este impusa.
Un rol cheie in comunicatii o au cheile. Ele ajuta la recunoasterea unui obiect de comunicatie interproces (coada de mesaje, semafor sau segment de memorie partajata). Pentru reprezentarea acestor chei se folosesc identificatori (asemenea descriptorilor de fisiere). Cu ajutorul identificatorilor, obiectele de comunicatie se pot folosi din mai multe aplicatii diferite. Tipul de date al identificatorului atasat acestor chei este dependent de implementare, dar el este evitat prin declararea lui de tipul key_t definit in
<sys/types.h> (pentru programe). Nu trebuie confundate cheile cu descriptorii de fisiere. Aceste chei trebuie alese cu grija pentru a evita efecte secundare nedorite (daca 2 procese independente folosesc aceeasi cheie pentru o coada de mesaje, se pierde informatia foarte greu de depistat). Comunicatia prin mesaje are loc dupa schema :

ÚAAAAAAAA¿ mesaj
³client 1³<AA¿ ÚAAAAAA¿ ÚAAAAAAA¿
AAAAAAAAAÙ ³ ÚAAAAAA¿ AAAAAAAÙ AAAAAAAAAAAAAAA AAAAAAAAÙ
AAA>³ ³ transmitatorÚAA¿ ÚAA¿ receptor
³server³ AAAAAAAAA> ³ ³ . . . ³ ³ AAAAAAA>
ÚAA>³ ³ AAAÙ AAAÙ
ÚAAAAAAAA¿ ³ AAAAAAAÙ AAAAAAAAAAAAAAA
³client 2³<AAÙ coada de mesaje
AAAAAAAAAÙ

Rolul principal ii revine cozii de mesaje. Unul sau mai multe procese transmit, introduc mesaje intr-o coada de mesaje, iar altele le extrag. Daca un proces extrage un mesaj din coada de mesaje, aceasta informatie este pierduta pentru ceilalti. Nu exista deocamdata un mecanism prin care un proces sa poata trimite un mesaj catre mai multe procese deodata (broadcast). Ordinea mesajelor in coada este stricta, mesajele putindu-se scoate doar in ordinea in care au fost trimise (o aplicatie poate folosi mai multe cozi de mesaje).
Mecanismul de comunicatie prin mesaje este implementat in nucleu.
Pentru aceasta, kernelul isi rezerva o zona tampon de memorie. Fiecare mesaj trimis trece prin kernel. Procesul care trimite mesajul stabileste pentru acesta o cheie de recunoastere. Aici apare o problema : daca un alt proces cunoaste cheia, el poate sa preia informatia din coada, chiar daca informatia nu-i fusese destinata, ea pierzindu-se (o solutie ar fi codificarea mesajelor).

Un mesaj se bazeaza pe o structura C care cuprinde un identificator si textul propriu-zis.

ÚAAAAAAAAAA¿ Identificatorul se foloseste pentru specificarea mesaj ³mtip³mtext³ tipului mesajului necesar la selectarea lui din
AAAAAAAAAAAÙ coada de mesaje si se reprezinta cu un long.

Informatia propriu-zisa este in cimpul text, are o lungime variabila si se declara de exemplu prin charai (structura unui mesaj trebuie sa inceapa cu un long, restul dupa necesitati = regula). Pentru a programa cu mesaje, trebuie incluse urmatoarele fisiere standard : <sys/types.h>, <sys/ipc.h>,
<sys/msg.h>. Apelul sistem folosit in lucrul cu mesagele la crearea si deschiderea unei cozi este msgget.

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

int id_coada,permisii; key_t cheie;
... id_coada=msgget(cheie,permisii);
...

A fost creata si deschisa o coada de mesaje in functie de parametrii specificati prin variabila permisii. Drept cheie se foloseste un identificator global de tipul key_t. Apelul returneaza un identificator al cozii de mesaje sub forma de intreg pozitiv in variabila id_coada (daca actiunea a avut succes).

Pentru cozile de mesaje se definesc drepturi de acces exact ca la lucrul cu fisiere, specificate in variabila permisii. Pentru aceasta sunt definite in
<sys/ipc.h> urmatoarele constante:

IPC_CREAT : cu aceasta se deschide o coada corespunzatoare cheii date, iar daca aceasta nu exista va fi creata. Daca aceasta constanta lipseste din apel, coada nu va fi creata si va fi deschisa doar daca exista.
IPC_EXCL: se foloseste impreuna cu IPC_CREAT, coada va fi creata si deschisa doar daca nu exista deja. Daca ea exista, se intoarce valoarea -1 de eroare (variabila globala errno va contine
EEXIST).

In afara de aceste constante, se dau valori normale de permisii corespunzatoare proprietarului, grupului si celorlalti. De exemplu, daca permisii=0660|IPC_CREAT, se deschide o coada de mesaje sau se creeaza daca nu exista, proprietarul si grupul sau avind drept de r,w. Dupa ce o coada de mesaje a fost creata se pot introduce mesaje in ea. Pentru aceasta exista apelul msgsnd.

#include <sys/types.h>
... int id_coada,marime,permisii,retur; struct min_sg A long mtip; char mtextaMSGSIZEi;
Smesaj;
... retur=msgsnd(id_coada,&mesaj,marime,permisii);

Id_coada este coada de mesaje cu care se lucreaza, marime specifica lungimea cimpului mtext al structurii. Prin permisii se poate specifica modul in care se face apelul. Daca permisii=0, apelul va astepta pina cind in coada de mesaje va fi loc pentru mesajul transmis. Daca se introduce constanta
NOWAIT, apelul va returna imediat, iar daca nu este loc pentru mesaje se va intoarce -1, iar in errno va fi depusa valoarea EAGAIN.
Pentru ca o comunicatie sa functioneze este nevoie de 2 procese. Cel de-al 2-lea proces trebuie sa extraga mesagele din coada, pentru aceasta existind apelul msgrcv.

#include <sys/types.h>
... int id_coada,marime,permisii,retur; struct min_sg A long mtip; char mtextaMSGSIZEi;
Smesaj; long mtip;
... retur=msgrcv(id_coada,&mesaj,marime,mtip,permi_i);

Va fi preluat din coada urmatorul mesaj de tip mtip si va fi depus in structura de date mesaj. Pentru mtip putem avea:

mtip= 0 primul mesaj din coada indiferent de tipul sau; mtip= n(pozitiv) primul mesaj de tipul n; mtip= -n(negativ) primul mesaj de tipul 1,2,...,n.

Prin variabila marime se transmite dimensiunea maxima a mesajului. Daca marimea reala a mesajului este mai mare decit marime, apelul va returna -1.
Daca mesajul este mai mic decit marime, apelul va returna valoarea lui exacta.
Daca permisii=0 (modul in care se face apelul), apelul va astepta pina la sosirea unui mesaj de tipul solicitat. Daca se introduce IPC_NOWAIT, apelul va intoarce valoarea de eroare -1, daca nu exista mesaj de tipul solicitat.
Variabila globala errno va contine valoarea EAGAIN. Daca permisii=MSG_NOERROR, un mesaj de lungime mai mare decit cel solicitat va fi trunchiat fara a solicita eroare. Pentru stergerea unei cozi de mesaje se foloseste msgctl.

retur=msgctl(id_coada,IPC_RMD,0);

Singurii care pot sterge o coada sunt proprietarii cozii & supervizorul.
Daca nu s-a putut sterge coada, valoarea de retur este -1.

In exemplul de mai jos este un exemplu de aplicatie client-server.
Programul client trimite serverului identificatorul sau de proces si apoi asteapta de la acesta un raspuns. Cind soseste raspunsul, clientul il tipareste si se opreste. Serverul asteapta mesaje de la clienti si le raspunde, transmitind propriul sau identificator de proces. Serverul se opreste la aparitia oricarui semnal.

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

#define CHEIE 0100 /* identificatorul cozii */

struct mesaj A long mtip; char mtexta256i;
S;

/* Client */
#include "mesaje.h" void main()
A struct mesaj mes; int id_coada,id_proces,*pint;
/* deschiderea cozii CHEIE */ id_coada=msgget(CHEIE,0666);
/* constructia mesajului */ mes.mtip=1; pint=(int *)mes.mtext;
*pint=id_proces;
/* transmiterea mesajului fara tratarea erorilor */ msgsnd(id_coada,&mes,256,id_proces,0);
/* tiparirea mesajului primit */ printf("\n Client: serverul este: %d\n",*(int *)mes.mtext);
S

/* Server */
#include "mesaj.h"

int id_coada; void main()
A int i,*pint; extern cleanup(); struct mesaj mes;
/* pentru tratarea semnalelor */ for(i=0; i<20; i++ ) signal(i, cleanup);
/* crearea cozii de mesaje */ id_coada=msgget(CHEIE,0666|IPC_CREAT);
/* receptarea mesajelor de la clienti si raspunsul la ele*/
while (1)A/* erorile nu sunt tratate */ msgrcv(id_coada,&mes,256,1,0);
/* listeaza identificatorul clientului */ pint=(int *)mes.mtext; printf("\n Server: mesajul este de la client: %d\n",*pint);
/* construirea mesajului de raspuns */ mes.mtip=*pint;
*pint=getpid();
/* transmiterea mesajului */ msgsnd(id_coada,&mes,sizeof(int),0);
S
S

/* rutina de stergere a cozii la primirea unui mesaj */ cleanup()
A msgctl(id_coada,IPC_RMD,0); exit();
S


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta