Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Fisiere pipe - UNIX

linux



+ Font mai mare | - Font mai mic



Fisiere pipe - UNIX

Sunt fisiere de tip FIFO. Ele permit transferul de date intre procese, cat si sincronizarea executiei proceselor. Modul de implementare permite proceselor sa comunice fara a cunoaste care sunt procesele de la capatul celalalt al pipe-ului. Exista doua tipuri de pipe-uri:



pipe-uri numite;

pipe-uri nenumite (anonime).

Cele numite ocupa un loc in ierarhia sistemului de fisiere, se deschid ca orice fisier (folosind aplelul sistem open) si pot fi folosite in comun de procese in functie de permisiunile lor de acces la fisier. Cele nenumite sunt create cu apelul sistem pipe si nu pot fi folosite in comun decat de procesele descendente din procesul ce a creat pipe-ul. In figura 5.15, de exemplu, procesul B creeaza un pipe obisnuit si procesele D si E. Aceste procese vor putea accesa pipe-ul, dar A si C nu. Dupa ce a fost creat, un pipe se acceseaza folosind apelurile read, write si close.In continuare se vor prezenta pipe-urile nenumite.

Apelul sistem pipe

Sintaxa pentru crearea unui pipe este:

pipe (fdptr) ;

unde fdptr este un pointer catre un sir de doi intregi ce va contine descriptorii de fisier pentru citirea si scrierea pipe-ului. Deoarece nucleul implementeaza pipe-urile in sistemul de fisiere, acestea neexistand inaintea utilizarii lor, nucleul va asigna un inod si va aloca doi descriptori in tabela descriptorilor de fisiere utilizator (un descriptor pentru citirea din pipe si altul pentru scrierea in pipe) si intrarile corespunzatoare in tabela de fisiere. Utilizarea tabelei de fisiere face ca interfata apelurilor sistem pentru scriere si citire a pipe-urilor sa fie aceeasi cu cea pentru fisierele obisnuite. Astfel, procesele nu trebuie sa stie daca citesc/scriu un pipe sau un fisier obisnuit.

algoritm pipe

intrare: nici una

iesiri: descriptorul pentru citire

descriptorul pentru scriere

Figura 5.16. Algoritmul de creare a unui pipe nenumit

Algoritmul pentru crearea pipe-urilor nenumite este prezentat in figura 5.16. Folosind algoritmul ialloc, nucleul asigneaza un inod pentru un pipe dintr-un sistem de fisiere folosit ca dispozitiv pipe (pipe device). Un dispozitiv pipe este un sistem de fisiere din care nucleul aloca inoduri si blocuri de date pentru pipe-uri. Specificarea dispozitivului pipe se face de catre administratori la configurarea sistemului, si poate fi identic cu un alt sistem de fisiere. Atunci cand un pipe este activ, nucleul nu poate reasigna inodul si blocurile sale de date unui alt fisier.

Nucleul aloca apoi doua intrari in tabela de fisiere si actualizeaza informatiile din inodul aflat in memoria interna. Fiecare intrare in tabela de fisiere contine numarul de instante ale pipe-ului deschise pentru citire sau scriere (initial 1 pentru fiecare intrare in tabela de fisiere), iar contorul de referinta al inodului din memoria interna indica de cate ori pipe-ul a fost deschis (initial are valoarea 2). Valorile deplasamentului pentru citire si scriere sunt pastrate in inod, fapt ce permite accesul in mod FIFO la pipe. In cazul fisierelor regulate offsetul se pastreaza in tabela de fisiere. Utilizarea apelului lseek nu este permisa, ceea ce face imposibil accesul aleator la un pipe.

Deschiderea unui pipe numit

Un pipe numit este un fisier a carui semantica este asemanatoare cu cea a unui pipe nenumit. Diferenta intre ele este ca cel numit are o intrare in director si este accesat prin nume. Deschiderea unui pipe numit este la fel cu cea a fisierelor obisnuite, fiind astfel permisa comunicarea intre procese ce nu sunt inrudite. Pipe-urile numite exista in sistemul de fisiere si dupa incheierea utilizarii lor, pe cand cele nenumite sunt tranzitorii (cand nu mai sunt procese care utilizeaza pipe-ul, nucleul va elibera inodul alocat acestuia).

Algoritmul pentru deschiderea unui pipe numit este identic cu cel pentru deschiderea unui fisier obisnuit. Totusi, inaintea incheierii apelului sistem, nucleul incrementeaza contorul de citire sau cel de scriere din inod, indicand numarul proceselor ce au deschis pipe-ul numit pentru citire sau scriere. Un proces care deschide un pipe numit pentru citire va astepta pana cand un alt proces va deschide acest pipe pentru scriere, si invers. La deschiderea unui pipe numit (pentru citire sau scriere), nucleul trezeste toate procesele care asteptau acest lucru.

Daca un proces deschide un pipe numit pentru citire si exista un proces care sa scrie in acesta, atunci apelul open se incheie. Daca un proces deschide un pipe numit cu optiunea ano delaya(fara intarziere), apelul se va incheia fara ca procesul sa se puna in asteptare chiar daca nu exista un proces care sa scrie in acest pipe. In caz contrar procesul este blocat pana cand apare si procesul care sa scrie in pipe. Regulile sunt similare pentru un proces care deschide un pipe pentru scriere.

Citirea si scrierea pipe-urilor

Scrierea intr-un pipe se face la unul din capete, iar citirea de la celalalt capat. Dupa cum s-a mentionat anterior, procesele acceseaza datele din pipe in maniera FIFO, ceea ce insemna ca ordinea in care datele sunt scrise intr-un pipe este si ordinea in care vor fi citite din pipe.

Numarul de procese care scriu in pipe nu trebuie sa fie egal cu numarul de procese care citesc din acesta. Daca numarul proceselor care scriu sau citesc este mai mare decat 1, coordonarea utilizarii pipe-ului va trebui realizata prin alte mecanisme. Nucleul acceseaza datele unui pipe in acelasi fel cum acceseaza datele unui fisier obisnuit, cu diferenta ca pipe-urile utilizeaza pentru o mai mare eficienta doar blocuri directe, desi aceasta limiteaza cantitatea datelor ce pot fi stocate la un moment dat in pipe. Nucleul manipuleaza blocurile directe ale inodului ca o coada circulara si pastreaza intern pointerii de citire si scriere pentru a conserva modul de lucru FIFO (vezi figura 5.17). Nucleul nu scrie niciodata in pipe peste date care nu au fost citite.

Figura 5.17. Situatie posibila in utilizarea unui pipe.

Consideram in continuare patru situatii in care se poate executa citirea sau scrierea pipe-urilor:

scrierea intr-un pipe in care este spatiu suficient pentru datele ce vor fi scrise;

citirea dintr-un pipe in care sunt date suficiente;

scrierea intr-un pipe in care nu este spatiu suficient pentru datele ce vor fi scrise;

citirea dintr-un pipe care nu are date suficiente;

Notam:

Np = numarul de octeti ce se afla deja in pipe;

Nw= numarul de octeti ce vor fi scrisi in pipe;

Nr = numarul de octeti ce vor fi cititi din pipe;

Cp = capacitatea pipe-ului;

In primul caz (Np+Nw) £ Cp. Nucleul executa algoritmul de scriere pentru un fisier obisnuit, cu diferenta ca incrementeaza automat dimensiunea pipe-ului, deoarece cantitatea de date din pipe se mareste odata cu fiecare scriere. In cazul fisierelor obisnuite procesele incrementeaza dimensiunea fisierului numai cand se scriu date dupa sfarsitul fisierului. Daca urmatorul deplasament din pipe iese din zona blocurilor directe, nucleul stabileste valoarea acestuia in u area la 0 (inceputul pipe-ului). Cand un proces termina de scris date in pipe, nucleul actualizeaza pointerul de scriere din inodul fisierului pipe, astfel incat urmatorul proces care va scrie in pipe sa o faca de unde a ramas procesul anterior. Apoi nucleul trezeste toate procesele care asteptau sa citeasca date din pipe.

Cand un proces citeste dintr-un pipe, el verifica daca pipe-ul este sau nu gol. Daca pipe-ul contine date (Nr £ Np), nucleul le citeste folosind algoritmul read pentru fisiere obisnuite. Dupa citirea fiecarui bloc, nucleul decrementeaza dimensiunea pipe-ului conform numarului de octeti cititi, si actualizeaza valoarea deplasamentului din u area (daca este necesar poate fi readusa la 0). Apoi sunt trezite toate procesele care sunt in asteptare si care doresc sa scrie in pipe si se reactualizeaza deplasamentul curent de citire in inod.

Daca un proces incearca sa citeasca dintr-un pipe mai multe date decat exista (Nr>Np), se citesc toate datele din pipe, iar cand acesta devine gol procesul se pune in asteptare pana cand va fi trezit de un alt proces care scrie in pipe. In cazul in care procesul a deschis pipe-ul cu optiunea ano delaya, citirea se va incheia fara ca procesul sa se puna in asteptare.

Daca un proces scrie in pipe mai multe date, iar pipe-ul nu le poate pastra pe toate, nucleul il pune asteptare pana cand un alt proces va citi date din pipe. O exceptie o constituie cazul in care cantitatea de date ce trebuie scrise depaseste capacitatea pipe-ului (Nw>Cp). In aceasta situatie nucleul va scrie date in pipe pana acesta se umple, dupa care pune procesul in asteptare pana cand in pipe va fi suficient spatiu disponibil. In acest caz exista posibilitatea ca datele scrise de proces in pipe sa nu fie contigue daca un alt proces scrie in pipe inainte ca procesul initial sa-si reia executia.

Studiind implementarea pipe-urilor reiese ca interfata este asemanatoare celei pentru fisiere obisnuite, dar implementarea difera deoarece nucleul pastreaza deplasamentul de citire si scriere in inod si nu in tabela de fisiere. Aceste valori trebuie pastrate in inod pentru pipe-urile numite astfel incat procesele sa le poata folosi in comun. Ele nu pot fi pastrate in tabela de fisiere pentru ca la fiecare deschidere se aloca o noua intrare in tabela.

Solutia adoptata nu ar fi neaparat necesara in cazul pipe-urilor nenumite (procesele utilizeaza in comun pipe-ul folosind intrari comune in tabela de fisiere) , insa s-a optat pentru ea deoarece codul este mai simplu.

Inchiderea pipe-urilor

La inchiderea unui pipe, un proces urmeaza aceeasi procedura ca si la inchiderea unui fisier obisnuit, exceptand faptul ca nucleul executa unele prelucrari speciale inainte de a elibera inodul pipe-ului. Astfel, el decrementeaza contorul corespunzator numarului de procese care scriu sau citesc din pipe. Daca numarul proceselor care scriu in pipe este 0 si sunt procese care astepta sa citeasca date din pipe, nucleul le trezeste, iar ele vor incheia operatia de citire fara a citi date. Daca numarul proceselor care citesc a scazut la 0 si sunt procese care asteapta sa scrie, nucleul le trezeste si le trimite un semnal ce indica o conditie de eroare.

Desi in cazul pipe-urilor numite exista posibilitatea de a apare noi procese redactor sau cititor, nucleul le trateaza in aceeasi maniera ca pe cele nenumite. Cand nici un proces cititor sau redactor nu mai acceseaza pipe-ul, nucleul elibereaza toate blocurile sale de date si actualizeaza inodul pentru a indica ca pipe-ul este gol. Cand nucleul elibereaza inodul unui pipe obisnuit, el elibereaza si copia disc pentru a fi reasignata.

Exemple

char string[ ]= 'hello';

main()

}

Figura 5.18 Scrierea si citirea unui pipe

In figura 5.18 este prezentat un program care ilustreaza modul de functionare al unui pipe. Procesul creeaza un pipe si intra intr-un ciclu infinit scriind in pipe cuvantul 'hello' si pe care-l citeste dupa aceea. Nucleul nu stie si nici nu este interesat sa stie daca un acelasi proces scrie si citeste pipe-ul.

Un proces care executa programul din figura 5.19 creeaza un nod(pipe numit) "fifo" in care scrie sau citeste intr-un ciclu infinit functie de numarul de parametri cu care a fost apelat. Datorita permisiunilor cu care a fost creat pipe-ul, pot participa la comunicarea prin intermediul acestuia si alti utilizatori.

#include <fnctl.h>

char string[ ] = 'hello'

int argc;

char *argv[ ];

main(argc,argv)

Figura 5.19 Scrierea si citirea dintr-un pipe numit



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 1628
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved