Semafor predstavlja generički mehanizam kontrole pristupa. Može da se koristi za kontrolu pristupa fajlovima, deljenoj memoriji isl. Osnovne funkcionalnosti semafora su: njegovo postavljanje, provera ili čekanje dok se ne ispune uslovi i postavljanje (“test-and-set”).
Skup semafora je predstavljen strukturom semid_ds iz linux/sem.h (jedna semid_ds struktura za svaki skup semafora na sistemu).
U semid_ds strukturi postoji pokazivač na niz semafora (sem_base). Svaki član niza je struktura struct sem (linux/sem.h):
Sistemski poziv semget()
Pozivom funkcije semget() dobija se identifikator skupa semafora.
Povratna vrednost je identifikator skupa semafora ako je uspešno ili -1 i errno:
EACCESS (permission denied)
EEXIST (set exists, cannot create (IPC_EXCL))
EIDRM (set is marked for deletion)
ENOENT (set does not exist, no IPC_CREAT was used)
ENOMEM (Not enough memory to create new set)
ENOSPC (Maximum set limit exceeded)
Primer
Sistemski poziv semop()
Vrši operacije nad semaforima.
Povratna vrednost je 0 ako je uspešno izvedeno (sve operacije izvršene) ili -1 i errno:
E2BIG (The argument nsops is greater than SEMOPM, the maximum number of operations allowed per system call.)
EACCES (The calling process does not have the permissions required to perform the specified semaphore operations, and does not have the CAP_IPC_OWNER capability.)
EAGAIN (An operation could not proceed immediately and either IPC_NOWAIT was specified in sem_flg or the time limit specified in timeout expired.)
EFAULT (An address specified in either the sops or the timeout argument isn’t accessible.)
EFBIG (For some operation the value of sem_num is less than 0 or greater than or equal to the number of semaphores in the set.)
EIDRM (The semaphore set was removed.)
EINTR (While blocked in this system call, the thread caught a signal.)
EINVAL (The semaphore set doesn’t exist, or semid is less than zero, or nsops has a nonpositive value.)
ENOMEM (The sem_flg of some operation specified SEM_UNDO and the system does not have enough memory to allocate the undo structure.)
ERANGE (For some operation sem_op+semval is greater than SEMVMX, the implementation dependent maximum value for semval.)
Argument sops je pokazivač ka strukturi tipa sembuf (linux/sem.h).
Promenljiva sem_num je broj semafora u skupu kojim se manipuliše, sem_op je operacija koja se vrši nad semaforom. Ponašanje sistemskog poziva semop() zavisi od toga da li je sem_op nula, negativan ili pozitivan broj.
Negativan - Alocira resurse. Blokira pozivajući proces dok je vrednost semafora manja od apsolutne vrednosti sem_op (Sve dok se dovoljan broj resursa ne oslobodi da bi proces mogao da ih alocira). Ako je vrednost semafora veća ili jednaka vrednosti sem_op vrednost semafora se smanjuje za sem_op.
Pozitivan - Oslobađa resurse. Vrednost sem_op se dodaje na vrednost semafora.
Nula (0) - Ovaj proces se blokira dok semafor ne dostigne vrednost 0.
Promenljiva sem_flg se koristi da bi se dodatno modifikovali efekti poziva semop(). Najčešće korišćene opcije su:
IPC_NOWAIT - kojom poziv semop() vraća grešku EAGAIN ako se pojavi situacija koja bi normalno blokirala proces. Najčešće se koristi i slučajevima kada se samo proverava da li može da se alocira resurs.
SEM_UNDO - semop() pamti promene na semaforu. Kada program završi sa radom jezgro OS automatski vraća sve promene koje su markirane sa SEM_UNDO. Koristi se ako se očekuje da program može da se neočekivano završi (npr. SIGKILL signalom) a potrebno je osloboditi resurse.
Primer
Sistemski poziv semctl()
Vrši kontrolne operacije nad skupom semafora definisanim sa semid ili nad nekim semaforom skupa definisanim sa semnum.
Povratna vrednost je pozitivan ceo broj ili -1 i errno:
EACCESS (permission denied)
EFAULT (invalid address pointed to by arg argument)
EIDRM (semaphore set was removed)
EINVAL (set doesn’t exist, or semid is invalid)
EPERM (EUID has no privileges for cmd in arg)
ERANGE (semaphore value out of range)
Poslednji argument arg, ako je potreban, mora biti definisan na sledeći način.
Različita polja union semun se koriste zavisno od vrednosti cmd parametra poziva setctl(). Najznačajnije vrednosti cmd parametra mogu biti (za ostale man strane):
SETVAL - Postavlja vrednost na definisanom semaforu na vrednost val člana unije semun.
GETVAL - Vraća vrednost za zadati semafor.
SETALL - Postavlja vrednost svih semafora u skupu na vrednost iz niza na koji pokazuje pokazivac array unije semun. Ne koristi se parametar semnum poziva semctl().
GETALL - Vraća vrednost svih semafora u skupu i skladišti ih u niz na koji pokazuje pokazivač array unije semun. Vrednost semnum parametra se ne definiše.
IPC_RMID - Uklanja skup iz jezgra.
IPC_STAT - Preuzima semid_ds strukturu skupa i skladišti je na adresu buf argumenta semun unije.
IPC_SET - Postavlja vrednost ipc_perm člana semid_ds strukture za skup. Uzima vrednost iz buf argumenta semun unije.