Provided by: manpages-pl-dev_20060617-1_all bug

NAZWA

       semop, semtimedop - operacje na semaforach

SKŁADNIA

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/sem.h>

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

       int  semtimedop(int  semid, struct sembuf *sops, unsigned nsops, struct
       timespec *timeout);

OPIS

       Semafor jest reprezentowany za pomocą anonimowej struktury zawierającej
       następujące pola:

           unsigned short  semval;   /* wartość semafora */
           unsigned short  semzcnt;  /* # oczekiwanie na  zero */
           unsigned short  semncnt;  /* # oczekiwanie na zwiększenie */
           pid_t           sempid;   /* proces, który wykonał ost. op. */

       Funkcja  semop  wykonuje  operacje  na  wybranych  semaforach z zestawu
       wskazywanego przez semid.  Każdy z nsops elementów tablicy  wskazywanej
       przez  parametr  sops  określa  operację,  która  ma  być  wykonana  na
       semaforze. Struktura struct sembuf zawiera następujące pola:

           unsigned short sem_num;        /* numer semafora */
           short sem_op;                  /* operacja na semaforze */
           short sem_flg;                 /* dodatkowe znaczniki operacji */

       W sem_flg  mogą  zostać  ustawione  znaczniki  operacji:  IPC_NOWAIT  i
       SEM_UNDO.   Jeśli  operacja  jest  opatrzona  znacznikiem  SEM_UNDO, to
       zostanie cofnięta w chwili, gdy proces zakończy działanie.

       Zestaw operacji zawartych w sops jest wykonywany  atomowo,  to  znaczy,
       operacje  są  wykonywane jednocześnie i tylko wtedy, gdy wszystkie mogą
       być jednocześnie wykonywane.  Zachowanie funkcji systemowej w sytuacji,
       gdy  nie  wszystkie  operacje  mogą być wykonane natychmiast, zależy od
       ustawienia znacznika IPC_NOWAIT w poszczególnych polach sem_flg, jak to
       opisano poniżej.

       Każda  z nich jest wykonywana na sem_num-tym semaforze w zestawie, przy
       czym pierwszy semafor ma numer  0.   Istnieją  trzy  rodzaje  operacji,
       rozróżniane na podstawie wartości sem_op.

       Jeśli  sem_op  jest  liczbą  dodatnią,  to  wartość  semafora  (semval)
       zostanie zwiększona o  tę  liczbę.  Ponadto,  jeśli  został  przekazany
       znacznik  SEM_UNDO,  wówczas system zaktualizuje licznik zmian (semadj)
       tego semafora dla procesu Operacja ta nigdy  nie  powoduje  wstrzymania
       procesu.  Proces  wywołujący  funkcję  musi  mieć  prawo do modyfikacji
       zestawu semaforów.

       Jeśli sem_op jest równe 0, proces musi mieć prawo  do  odczytu  zestawu
       semaforów.  Jest to operacja "oczekiwania na zero" (wait-for-zero): gdy
       semval ma wartość 0, operacja może być  kontynuowana  bezzwłocznie.   W
       przeciwnym   razie,   jeśli   w   sem_flg  przekazany  został  znacznik
       IPC_NOWAIT, wówczas funkcja systemowa zgłosi błąd,  zaś  zmienna  errno
       przyjmie  wartość  EAGAIN  (i  żadna  z  operacji  z  sops nie zostanie
       wykonana).  Jeśli proces  zostanie  wstrzymany  przez  system,  wówczas
       wartość  semzcnt  (liczby  procesów  oczekujących  na osiągnięcie przez
       semafor  wartości  zero)  zostanie  zwiększona  o  1.   Proces   będzie
       zawieszony  aż  do  chwili,  gdy  spełniony zostanie jeden z poniższych
       warunków:

       o      semval osiągnie wartość 0; wówczas wartość pola semzcnt zostanie
              zmniejszona o 1.

       o      Zestaw   semaforów   zostanie   usunięty:  system  zgłosi  błąd,
              przypisując zmiennej errno wartość EIDRM.

       o      Proces wywołujący funkcję  przechwyci  sygnał:  wartość  semzcnt
              zostanie   zmniejszona   o  1,  natomiast  system  zgłosi  błąd,
              przypisując zmiennej errno wartość EINTR.

       Jeśli sem_op ma wartość mniejszą od 0, to proces  musi  mieć  prawo  do
       modyfikacji  zestawu  semaforów.  Jeśli wówczas wartość semafora semval
       jest większa lub równa wartości bezwzględnej sem_op, to  operacja  może
       być   kontynuowana   bezzwłocznie:  wartość  semafora  semval  zostanie
       zmniejszona o wartość bezwzględną sem_op.   Ponadto,  jeśli  przekazano
       znacznik  SEM_UNDO,  wówczas system zaktualizuje licznik zmian semafora
       dla procesu (semadj).  Jeśli wartość bezwzględna  sem_op  jest  większa
       niż  semval,  a w sem_flg przekazano znacznik IPC_NOWAIT, system zgłosi
       błąd przypisując zmiennej errno wartość EAGAIN (i żadna z  operacji   z
       sops  nie  zostanie  wykonana).   W przeciwnym wypadku semncnt (licznik
       procesów oczekujących na zwiększenie wartości tego  semafora)  zostanie
       zwiększony o 1. Proces może być wznowiony w następujących sytuacjach:

       o      semval  osiągnie wartość większą lub równą wartości bezwzględnej
              sem_op; wtedy wartość semncnt  zostanie  zmniejszona  o  1,  zaś
              wartość  bezwzględna z sem_op zostanie odjęta od semval .  Jeśli
              przekazany został znacznik SEM_UNDO  ,  to  system  zaktualizuje
              licznik zmian semafora dla procesu (semadj).

       o      Zestaw  zostanie  usunięty  z  systemu: funkcja systemowa zgłosi
              błąd, przypisując zmiennej errno wartość EIDRM.

       o      Proces wywołujący funkcję  przechwyci  sygnał:  wartość  semncnt
              zostanie  zmniejszona  o  1,  natomiast funkcja systemowa zgłosi
              błąd, przypisując zmiennej errno wartość EINTR.

       Jeśli  operacja  zostanie  zakończona  pomyślnie,  to  wartości  sempid
       każdego  z semaforów wyszczególnionych w tablicy wskazywanej przez sops
       przypisany zostanie identyfikator procesu (PID), który  wywołał  semop.
       Ponadto,  polu  sem_otime  przypisany  zostanie aktualny czas.  Funkcja
       semtimedop zachowuje się tak samo jak funkcja semop, poza tym że w tych
       przypadkach  gdy  proces  wywołujący  by spał, czas trwania spania jest
       ograniczony przez czas określony w strukturze timespec, do której adres
       jest  przekazywany  w  parametrze  timeout.  Jeśli osiągnięto określony
       limit czasu, to wywołanie systemowe zwraca błąd,  ustawiając  errno  na
       EAGAIN  (i  żadna  z  operacji  w  sops  nie  jest wykonywana).  Jeżeli
       parametr timeout jest NULL, to semtimedop zachowuje się  dokładnie  tak
       samo jak semop.

WARTOŚĆ ZWRACANA

       Jeśli  operacja  zakończy  się pomyślnie, wówczas funkcja zwróci 0, a w
       przeciwnym  wypadku  zwróci  -1,   przypisując   zmiennej   errno   kod
       określający rodzaj błędu.

BŁĘDY

       Po   niepomyślnym   zakończeniu,   zmienna   errno   przyjmie  jedną  z
       następujących wartości:

       E2BIG  Wartość nsops  przekracza  SEMOPM,  maksymalną  liczbę  operacji
              wykonywanych w jednym wywołaniu.

       EACCES Proces  nie  ma  uprawnień  potrzebnych  do  wykonania  jednej z
              podanych operacji.

       EAGAIN Operacja opatrzona znacznikiem IPC_NOWAIT w sem_flg nie może być
              natychmiast   wykonana  lub  upłynął  limit  czasu  określony  w
              parametrze timeout.

       EFAULT Adres wskazywany przez sops jest niedostępny.

       EFBIG  Numer semafora sem_num, do którego odnosi się jedna z  operacji,
              jest  mniejszy  od  0 albo większy lub równy liczbie semaforów w
              zestawie.

       EIDRM  Zestaw został usunięty z systemu.

       EINTR  Podczas oczekiwania na  wykonanie  operacji  proces  przechwycił
              sygnał.

       EINVAL Zestaw semaforów nie istnieje lub wartość semid jest mniejsza od
              0 lub wartość nsops nie jest liczbą dodatnią.

       ENOMEM Brak pamięci na zapamiętanie  zmian  wywołanych  przez  operację
              (znacznik SEM_UNDO w sem_flg).

       ERANGE Dla  pewnej  operacji wartość sem_op+semval przekroczyła SEMVMX,
              zależną od implementacji maksymalną wartość semval.

UWAGI

       Struktury  sem_undo  nie  są  dziedziczone  poprzez  wywołania  funkcji
       systemowej  fork(2),  ale  są  dziedziczone  poprzez  wywołania funkcji
       systemowej execve(2).

       semop  nie  jest  nigdy  automatycznie  uruchamiana  ponownie  po   jej
       przerwaniu  przez  funkcję  obsługi  sygnału,  niezależnie  od ustawień
       znacznika SA_RESTART podczas tworzenia funkcji obsługi sygnału.

       semadj jest przypisaną procesowi liczbą  całkowitą,  która  stanowi  po
       prostu  (ujemny) licznik wszystkich operacji na semaforach wykonanych z
       podaniem znacznika SEM_UNDO.  Podczas bezpośredniego nadawania wartości
       semaforowi   za   pomocą  poleceń  SETVAL  lub  SETALL  dla  semctl(2),
       odpowiednie wartości semadj dla wszystkich procesów są zerowane.

       Wartości semval, sempid, semzcnt i semnct dla semafora  można  odczytać
       za pomocą odpowiednich wywołań semctl(2).

       Wywołania semop dotyczą następujące ograniczenia zasobów:

       SEMOPM Maksymalna  liczba  operacji,  które  mogą być wykonane w jednym
              wywołaniu semop: (32).

       SEMVMX Maksymalna dozwolona wartość  semval:  zależy  od  implementacji
              (32767).

       Implementacja  w  systemie Linux nie nakłada wewnętrznych ograniczeń na
       maksymalną  zmianę  wartości  semafora  podczas   zakończenia   procesu
       (SEMAEM), na ogólnosystemową liczbę struktur przechowujących informacje
       o zmianach stanu semaforów (SEMMNU),  ani  na  maksymalną  dla  procesu
       liczbę  struktur przechowujących informacje o zmianach stanu semaforów.

USTERKI

       Gdy proces kończy działanie, zestaw skojarzonych z nim struktur  semadj
       jest   wykorzystywany  do  cofnięcia  efektów  wszystkich  operacji  na
       semaforach, które ten proces wykonał z ustawionym znacznikiem SEM_UNDO.
       Wprowadza  to  trudność:  jeżeli  jedna (lub więcej) spośród tych zmian
       semaforów spowodowałby próbę  zmniejszenia  wartości  semafora  poniżej
       zera,  to co implementacja powinna uczynić?  Jednym z możliwych podejść
       do  tego  zadadnienia  mogło  by  być  zablokowanie  do   chwili,   gdy
       przeprowadzenie  wszystkich  zmian  semaforów  będzie możliwe.  Jest to
       jednakże  niepożądane,  gdyż  spowodowałoby   wymuszenie   zablokowania
       zakończenia  procesu  na  dowolnie  długi okres.  Inną możliwością jest
       zignorowanie wszystkich takich zmian semaforów  (nieco  analogiczne  do
       niepomyślnego  zakończenia,  gdy  dla operacji na semaforze podany jest
       znacznik IPC_NOWAIT).  Linux przyjął trzecie rozwiązanie:  zmniejszenie
       wartości  semafora  na  tyle,  na  ile jest to możliwe (tzn. do zera) i
       umożliwienie natychmiastowej kontynuacji kończenia działania procesu.

ZGODNE Z

       SVr4, SCID.  SVr4 dokumentuje dodatkowe kody błędów:  EINVAL,  EFBIG  i
       ENOSPC.

ZOBACZ TAKŻE

       ipc(5), semctl(2), semget(2), sigaction(2)