top

Tutorial Linux - Semafoare

 
Creaza un subiect nou   Raspunde la subiect    Pagina de start a forumului Tutorials and Questions © -> Tutoriale de UNIX / LINUX
Autor Mesaj
Acoustic
Senior Manager
Senior Manager
Acoustic

Data inscrierii: 12/Oct/2007
Mesaje: 1141
Localitate: somewhere @ a PC

MesajTrimis: 03/02/2008 22:22    Titlul subiectului: Tutorial Linux - Semafoare Raspunde cu citat (quote)

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 întocmai 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 indiferent ce 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 numeroase 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 utilizate 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 necesită 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.
Sus
Vezi profilul utilizatorului Trimite mesaj privat Trimite un mesaj
Afiseaza mesajele pentru a le previzualiza:    Subiectul anterior : Subiectul urmator  
Creaza un subiect nou   Raspunde la subiect    Pagina de start a forumului Tutorials and Questions © -> Tutoriale de UNIX / LINUX Ora este GMT + 2 ore
Pagina 1 din 1

 
Mergi direct la:  
Nu puteti crea un subiect nou in acest forum
Nu puteti raspunde in subiectele acestui forum
Nu puteti modifica mesajele proprii din acest forum
Nu puteti sterge mesajele proprii din acest forum
Nu puteti vota in chestionarele din acest forum

Fa-ti si tu propriul forum GRATUIT, pe www.myforum.ro