Sunteți pe pagina 1din 4

Lucrarea 5

Lucrul cu procese n Linux


1. Introducere teoretic
2. Desfurarea lucrrii
2.1. Ce se ntmpl cnd executai o comand?
Atunci cnd executai un program n sistemul de operare Linux, acesta creaz un context special pentru
aceasta, context ce conine tot ce i trebuie sistemului de operare s l ruleze ca i cum ar fi singurul
program ce ruleaz n sistem.
Execuia programului se face n Linux la nivelul procesului. Procesul este deci o instan a unui
program , este execuia unei imagini(ansamblul elementelor ce constituie contextul de execuie al
procesului).
Elementele contextului de execuie sunt: codul surs , memoria folosit de program, directorul de lucru ,
fiierele care sunt deschise ct i poziii la care se lucreaz n acestea, limite ale resurselor, informaie
legat de controlul accesului la resurse i alte informaii de nivel inferior.
La fiecare rulare a unui program sistemul UNIX face o operaie de fork , avnd ca rezultat crearea unui
context de proces i execuia programului n acel context. n continuare vom detalia paii acestei proceduri:
1)Se aloc un loc n tabela de proces(lista proceselor ce ruleaz n sistem la un moment dat). UNIX
creaz impresia rulrii simultane a mai multor programe prin comutarea rapid ntre procesele active din
tabela de proces. Aceast alocare poate eua din urmtoarele motive:
a)

Ai depit limita stabilit a maximului de procese rulate simultan de un utilizator.

b) Sistemul a rmas fr locuri libere n tabela de proces.


c)

Sistemul a rms fr memorie liber i nu mai are loc de textul i datele unui nou proces.

2) Sistemul i asociaz procesului un identificator sau PID(Process IDentifier). Acest identificator poate
fi folosit pentru a controla procesul mai trziu.
3) Copiaz contextul procesului Printe, procesul care a solicitat apariia noului proces.
4) Returneaz noul PID(al procesului Fiu) procesului Printe. Acest lucru i permite procesului
printe s poat analiza i controla direct procesele fii.
Dupa ce fork-ul este complet, UNIX ruleaz programul. Una din diferenele fundamentale ntre UNIX i
multe alte sisteme de operare const n procedeul n doi pai de rulare a unui program. n primul pas se
creaz un nou proces identic cu procesul printe. n al doilea se execut un program diferit. Aceast
procedur permite cteva variaiuni interesante.
Procesele UNIX se pot afla n una din cele trei stri:
1) RUNNING n dou moduri : utilizator(dac procesul execut un program al acestuia) sau
nucleu(dac procesul execut o funcie sistem).
2) READY procesul are toate datele necesare i astepat s se elibereze procesorul.
3) WAITING procesul asteapt eliberarea unor resurse (spre exemplu terminarea unor operaii I/O).

Procedurile prezentate mai sus sunt realizate implicit de ctre sistemul de operare UNIX, n cele ce
urmeaz vom prezenta cteva dintre cele mai utilizate metode din limbajul C pentru crearea de procese
Fiu i realizarea comunicrii ntre acestea.

2.2.Funcii de gestiune de procese n sistemul UNIX din limbajul C


int fork() este funcia ce creaz un proces Fiu cnd este executat n procesul Printe. Returneaz
un ntreg care are urmtoarele semnificaii:
-

n Printe este PID ul procesului Fiu


n Fiu este 0
dac apare vreo eroare este 1 i este setat variabila global errno.

pid_t wait(int *state) este funcia de asteptare a proceselor Fiu. Ea produce suspendarea execuiei
procesului care o apeleaz pn la terminarea execuiei unuia dintre fii si. Este folosit pentru evitarea
cazurilor n care procesul printe poate termina execuia i elibera memoria, naintea proceselor fiu fapt ce
ar putea conduce la apariia unor procese zombie(procese rmase fr printe).
Funcia ntoarce: PID-ul procesului care i-a terminat execuia sau 1 n caz de eec(setndu-se variabila
de sistem errno).

pid_t waitpid(pid_t pid, int *status, int options) spre deosebire de funcia anterioar adaug ca
parametru PID-ul procesului care este ateptat.
pid_t getpid() returneaz PID-ul procesului n care a fost apelat.
pid_t getppid() returneaz PID-ul procesului printe al procesului n care a fost apelat.

2.3. Sistemul de Memorie Partajat V


Acest Sistem V IPC (Inter-Process Communication) este format dintr-o serie de apeluri de sistem ce
asigur cozi de mesaje, mecanism de semafoare i un mecanism al accesului concurent la o memorie
partajat.
Procedura de baz pentru crearea unui grup de procese ce vor accesa concurent un segment de memorie
partajat este:
1) Rularea programului pornete ca un singur proces.
2) n mod normal se dorete ca fiecrei execuii paralele a programului s i fie alocat un segment din
memoria partajat. Funcia folosit pentru crearea unui segment de memorie de dimensiune dorit
este shmget() . Funcia poate returna i identificatorul unui segment de memorie deja existent n
funcie de parametrii transmii. n ambele cazuri funcia returneaz fie ID-ul segmentului de
memorie partajat fie 1 n caz de eroare. Spre exemplu pentru a creea un segment de memorie
partajat de b octei, apelul ar arta n felul urmtor :
shmid = shmget(IPC_PRIVATE, b , (IPC_CREAT | 0666))
unde 0666 este un indicator al drepturilor de acces asupra acestuia(setate pe trei grupuri de cte trei bii
corespunztoare sistemului de drepturi de acces din UNIX).
3) Urmtorul pas este s atam acest segment de memorie acestui proces, prin adugarea lui n harta
de memorie virtual a procesului. Funcia shmat() care realizeaz acest lucru i permite
programatorului s specifice adresa virtual la care ar trebui s apar segmentul de memorie, totui
innd seama de constrngeri de paginare a memoriei virtuale putndu-se aloca doar multiplii ntregi
ai dimensiunii paginii de memorie virtual, dimensiune obinut cu ajutorul funciei getpagesize().

Din aceste considerente se prefer lansarea la latitudinea sistemului de operare a alegerii adresei din
memoria virtual(folosirea valorii implicite 0 ). n ambele cazuri funcia returneaz un pointer ctre
adresa de nceput a segmentului ataat la memoria virtual. Un exemplu:
shmptr = shmat(shmid , 0 , 0)
Observai c putei aloca din acest segment de memorie pentru toate variabilele voastre statice partajate
doar prin simpla declarare a acestora ca aparinnd unui tip de structur i decalndu-l pe shmptr ca fiind
un pointer ctre acel tip de structur.
4) Deoarece acest segment de memorie partajat trebuie distrus o dat ce ultimul proces care l-ar fi
accesat termin execuia sau se detaeaz de el, trebuie apelat funcia shmctl() pentru a pregti
aceast aciune implicit. Secvena de cod este urmtoarea :
shmctl(shmid, IPC_RMID, 0)
5) Se folosete funcia fork() standard de creare de noi procese din Linux, fiecare nou proces
motenind segmentul de memorie partajat al printelui.
6) O dat ce un proces a terminat lucrul cu un segment de memorie partajat trebuie s se detaeje de el
astfel :
shmdt(shmptr)
Exemplul urmtor de program C prezint calculul numrului Pi folosind memoria partajat:
#include
#include
#include
#include
#include
#include
#include
#include

<stdio.h>
<stdlib.h>
<unistd.h>
<sys/types.h>
<sys/stat.h>
<fcntl.h>
<sys/ipc.h>
<sys/shm.h>

volatile struct shared { double pi; int lock; } *shared;


inline extern int xchg(register int reg,
volatile int * volatile obj)
{
/* instruciune de interschimb atomic */
__asm__ __volatile__ ("xchgl %1,%0"
:"=r" (reg), "=m" (*obj)
:"r" (reg), "m" (*obj));
return(reg);
}
main(int argc, char **argv)
{
register double width, localsum;
register int intervals, i;
register int shmid;
register int iproc = 0;;
/* Alocarea memoriei partajate */
shmid = shmget(IPC_PRIVATE,
sizeof(struct shared),
(IPC_CREAT | 0600));

shared = ((volatile struct shared *) shmat(shmid, 0, 0));


shmctl(shmid, IPC_RMID, 0);
/* Iniializarea... */
shared->pi = 0.0;
shared->lock = 0;
/* crearea unui proces fiu */
if (!fork()) ++iproc;
/* aflarea nr. de intervale */
intervals = atoi(argv[1]);
width = 1.0 / intervals;
/* calculele aferente */
localsum = 0;
for (i=iproc; i<intervals; i+=2) {
register double x = (i + 0.5) * width;
localsum += 4.0 / (1.0 + x * x);
}
localsum *= width;
/* Atomic spin lock, add, unlock... */
while (xchg((iproc + 1), &(shared->lock))) ;
shared->pi += localsum;
shared->lock = 0;
/* terminarea procesului fiu */
if (iproc == 0) {
wait(NULL);
printf("Estimatul lui pi este %f\n", shared->pi);
}
return(0);
}

n acest exemplu s-a folosit instruciunea IA32 de interschimb atomic pentru implementarea
mecanismului de blocare.

S-ar putea să vă placă și