node52






WYWOŁANIE SYSTEMOWE: semop()






















Next: WYWOŁANIE SYSTEMOWE: semctl()
Up: Semafory
Previous: WYWOŁANIE SYSTEMOWE: semget()
  Contents





WYWOŁANIE SYSTEMOWE: semop()




WYWOŁANIE SYSTEMOWE: semop();
PROTOTYP: int semop ( int semid, struct sembuf *sops, unsigned nsops);
ZWRACA: 0 - sukces ( przeprowadzono wszystkie operacje )
-1 - błąd: errno = E2BIG ( nsops większy od maxymalnej liczby
dozwolonych operacji atomowych )
EACCESS ( brak prawa dostępu )
EAGAIN ( IPC_NOWAIT ustawione, nie można
przeprowadzić operacji )
EFAULT ( nieprawidłowy adres wskazywany przez
sops )
EIDRM ( zestaw został usunięty )
EINTR ( otrzymano sygnał w czasie spania )
EINVAL ( zestaw nie istnieje lub nieprawidłowy semid )
ENOMEM ( SEM_UNDO ustawione, brak pamięci aby utworzyć strukturę anulowania (undo) )
ERANGE ( wartość semoforu poza zakresem )
UWAGI:


Pierwszym argumentem dla semop() jest klucz ( w naszym przypadku zwrócony przez
semget). Drugi argument (sops) jest wskaźnikiem do tablicy operacji ,
które mają zostać przeprowadzone na grupie semaforów. Trzeci argument (nsops) jest
liczbą operacji w tablicy.


Argument sops wskazuje tablicę typu sembuf, który jest zdefiniowany
w linux/sem.h:



/* wywołanie systemowe semop bierze tablicę takich struktur */
struct sembuf {
ushort sem_num; /* index semafora w tablicy */
short sem_op; /* opercja */
short sem_flg; /* flagi oparacji */
};



sem_num



Numer semafora którym jesteś zainteresowany


sem_op



Operacja do wykonania ( dodatnia, ujemna lub zero )


sem_flg



Flagi operacji





Jeżeli sem_op jest ujemny jego wartość zostaje odjęta od semafora. Odpowiada to
używaniu zasobów kontrolowanych lub monitorowanych przez semafor. Jeżeli nie podano
IPC_NOWAIT proces wywołujący śpi do czasu aż wymagana liczba zasobów jest
dostępna ( inny proces zwolnił jakieś ).


Jeżeli sem_op jest dodatni jego wartość jest dodawana do semafora.
Odpowiada to zwolnieniu zasobów. Zasoby powinny być zawsze zwalniane jeżeli nie są
dłużej używane!


Jeżeli sem_op jest zerem proces będzie spał do czasu aż semafor będzie miał wartość zera.
Odpowiada to 100% użycia. Dobrym przykładem jest demon działający z prawami roota,
który będzie dynamicznie zmieniał rozmiar zbioru semaforów jeżeli ten będzie w 100%
użyty.


W celu wytłumaczenia wywołania semop przywołajmy nasz przykład z drukarkami.
Załużmy, iż mamy tylko jedną drukarkę, która potrafi drukować tylko jedną pracę.
Utworzymy zestaw tylko z jednym semaforem ( tylko jedna drukarka ) i zainicjujemy
go wartością jeden ( tylko jedna praca ).


Za każdym razem gdy chcemy wysłać pracę do drukarki musimy upewnić się czy
jest ona dostępna. Robimy to próbując otrzymać jedną jednostkę z semafora.
Załadujmy tablicę sembuf aby tego dokonać:



struct sembuf sem_lock = { 0, -1, IPC_NOWAIT };


Tak zainicjowana struktura wymusza dodanie -1 do semafora numer 0. Inaczej mówiąc
jedna jednostka zasobu zostanie użyta z semafora numer 0. Podaliśmy IPC_NOWAIT,
więc wywołanie natychmiast powróci lub zwróci błąd jeżeli ktoś używa naszą drukarkę.
Oto przykład użycia zainicjowanej struktury sembuf:



if((semop(sid, &sem_lock, 1) == -1)
perror("semop");


Trzeci argument (nsops) mówi, że wykonujemy tylko jedną operację ( mamy tylko
jedną strukturę sembuf w naszej tablicy ). Argument sid jest identyfikatorem
IPC naszego zestawu semaforów.


Po wydrukowaniu musimy oddać zasoby z powrotem do zestawu aby inni mogli
wydrukować swoje prace.



struct sembuf sem_unlock = { 0, 1, IPC_NOWAIT };


Taka struktura dyktuje dodanie 1 do semafora numer 0. Czyli: jedna jednostka zasobu
powraca do zestawu.













Next: WYWOŁANIE SYSTEMOWE: semctl()
Up: Semafory
Previous: WYWOŁANIE SYSTEMOWE: semget()
  Contents



2000-03-01








Wyszukiwarka

Podobne podstrony:
node52
node52 HII522RWHVRRAGFQK3I52YPEAMQ5EUCIKGGLWII
node52
node52
node52
node52 3BZUBEYPBGENVWN65TTR4I7HJJ3KAWUKU2SUXJA
node52 6YZURTVX63UAUJAGBSXOT2UVJQXJWXNJBW5LU6A

więcej podobnych podstron