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¶
Uwaga! To tłumaczenie może być nieaktualne!
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:
- •
- semval osiągnie wartość 0;
wówczas wartość pola semzcnt zostanie zmniejszona o
1.
- •
- Zestaw semaforów zostanie usunięty: system
zgłosi błąd, przypisując zmiennej errno
wartość EIDRM.
- •
- 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:
- •
- 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).
- •
- Zestaw zostanie usunięty z systemu: funkcja systemowa
zgłosi błąd, przypisując zmiennej errno
wartość EIDRM.
- •
- 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)
Powyższe tłumaczenie pochodzi z nieistniejącego już Projektu
Tłumaczenia Manuali i
może nie być aktualne. W razie
zauważenia różnic między powyższym opisem a
rzeczywistym zachowaniem opisywanego programu lub funkcji, prosimy o
zapoznanie się z oryginalną (angielską) wersją strony
podręcznika za pomocą polecenia:
- man --locale=C 2 semop
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.