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:
node52node52 HII522RWHVRRAGFQK3I52YPEAMQ5EUCIKGGLWIInode52node52node52node52 3BZUBEYPBGENVWN65TTR4I7HJJ3KAWUKU2SUXJAnode52 6YZURTVX63UAUJAGBSXOT2UVJQXJWXNJBW5LU6Awięcej podobnych podstron