Jump to content
hanibal

{linux}SemaFoare

Recommended Posts

Semafoarele sunt una dintre metodele de comunicare inter-proces , un mod de a semnala unui proces producerea unui eveniment in alt proces. Pentru a putea folosi semafoare trebuie incluse headerele sys/sem.h, sys/ipc.h si sys/types.h .

Pasii care trebuie urmati pentru a defini , initializa , folosi si , in final , distruge un semafor sunt urmatorii:

1) Definim o variabila de tip intreg;

int id_semafor;

2) Luam (sau cream) semaforul;

id_semafor=semget(IPC_PRIVATE, 1, 0777);

Prototipul functiei semget este urmatorul:

int semget(key_t key,int nsems,int semflg)

- functia intoarce identificatorul pentru grupul cu nsems semafoare asociat cheii key;

- daca cheia este IPC_PRIVATE sau cheia nu este IPC_PRIVATE dar semflg are setat bitul IPC_CREAT un nou grup de semafoare este creat;

- semflg contine de asemenea drepturile de acces asociate semaforului (in exemplul anterior , 0777);

- prezenta flagurilor IPC_CREAT si IPC_EXCL in semflg in acelasi timp va duce la esuarea apelului functiei semget;

In caz de succes functia intoarce un numar pozitiv care reprezinta id-ul semaforului si in caz de eroare -1

3) Daca este nou creat , vrem sa setam valoarea initiala a semaforului (de obicei este 1 , dar i se poate da orice valoare)

- pentru asta s-ar putea sa avem nevoie sa definim o structura (semun) astfel

#if defined(__GNU_LIBRARY) && !defined(_SEM_SEMUN_UNDEFINED)

//semun e deja definit

#else

//definim semun

typedef union

{

int val;

struct semid_ds *buf;

unsigned short *array;

struct seminfo *__buf;

} semun;

#endif

semun value;

value.val=1;

semctl(semidscr, 0, SETVAL, value);

Prototipul functiei semctl:

int semctl(int semid,int semnum,int cmd,union semun arg)

- functia executa operatia indicata de cmd asupra setului de semafoare indicat de semid , asupra semaforului semnum din set (primul are indicele 0) folosind arg pentru asta

- in cazul exemplului de mai sus , se seteaza valoarea din value la semaforul 0 din setul indicat de semafoul nou creat

- pentru mai multe informatii legate de parametrii functiei , man semctl

4) Vrem sa folosim semaforul ( de obicei pentru sincronizari intre procese)

- exista 2 operatii care se folosesc uzual asupra unui semafor pentru asta , si au numele consacrate:Down si up (sau U si V)

- down va incerca sa scada 1 din valoarea semaforului

- up va adauga 1 la valoarea semaforului

- uzual , daca un proces incearca sa faca down pe un semafor care are valoarea 0 , se va bloca acolo pana cand alt proces va face up pe acelasi semafor

ATENTIE:

- daca se folosesc threaduri , in momentul in care unul din threaduri face down pe un semafor cu valoarea 0 , intreg procesul se va bloca , adica TOATE THREADURILE pornite de acel proces

- pentru sincronizare intre threaduri vor trebui folosite mijloace dedicate;

Functiile down si up:

void down(int semid,short flags)

{

//scade valoarea 1 dintr-un semafor

char buf[64];

struct sembuf op;

//scad valoarea 1 din semafor

op.sem_num = 0;

op.sem_op = -1;

op.sem_flg = flags;

if(semop(semid, &op, 1)==-1)

{

//eroare

strcpy(buf,"Eroare la semop!n");

write(1,buf,strlen(buf));

exit(-1);

}

}

void up(int semid,short flags)

{

//adauga 1 la valoarea unui semafor

char buf[64];

struct sembuf op;

//adaug 1 la valoarea din semafor

op.sem_num = 0;

op.sem_op = 1;

op.sem_flg = flags;

if(semop(semid, &op, 1)==-1)

{

//eroare

strcpy(buf,"Eroare la semop!n");

write(1,buf,strlen(buf));

exit(-1);

}

}

Prototipul functiei semop:

int semop(int semid,struct sembuf *sops,unsigned nsops)

- nsops se foloseste pentru a specifica numarul de operatii care trebuiesc efectuate (in sops va trebui sa se gaseasca un vector)

- daca flags contine IPC_NOWAIT , procesul nu se va bloca daca valoarea din semaforul asupra caruia vrea sa faca operatia si apelul va intoarce -1

- daca flags contine IPC_UNDO , toate operatiile vor fi undone cand procesul se termina;

5) Dupa ce ne jucam cu semaforul , vrem sa-l distrugem

semctl(id_semafor, 0, IPC_RMID, NULL);

- apelam functia semctl cu parametrul cmd IPC_RMID

Semafoarele sunt resurse sistem , trebuie distruse cand nu mai sunt folosite , altfel vor continua sa ocupe resursele sistemului. Pentru a vedea toate resursele IPC care sunt active la un moment dat in sistem , puteti folosi comanda ipcs din consola. Resursele(semafoare,cozi de mesaje,memoria partajata) pot fi distruse si direct din consola cu comanda ipcrm. Folositi man ipcs si man ipcrm pentru mai multe detalii.

Autor Florin(itzone)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...