| semget(2) | System Calls Manual | semget(2) |
semget - pobiera identyfikator zestawu semaforów Systemu V
Standardowa biblioteka C (libc, -lc)
#include <sys/sem.h>
int semget(key_t key, int nsems, int semflg);
Wywołanie systemowe semget() zwraca identyfikator zestawu semaforów Systemu V skojarzonego z parametrem key. Może służyć albo do pozyskania identyfikatora uprzednio utworzonego zestawu semaforów (gdy semflg wynosi zero, a key nie ma wartości IPC_PRIVATE) lub do utworzenia nowego zestawu.
Nowy zestaw składający się z nsems semaforów zostanie utworzony, jeśli parametr key będzie mieć wartość IPC_PRIVATE lub gdy zestaw semaforów skojarzony z key nie istnieje, a w parametrze semflg zostanie przekazany znacznik IPC_CREAT.
Jeśli w parametrze semflg podano zarówno IPC_CREAT, jak i IPC_EXCL oraz już istnieje zestaw semaforów o kluczu key, to semget() kończy się błędem, ustawiając errno na wartość EEXIST (działa to analogicznie do O_CREAT | O_EXCL w open(2)).
Podczas tworzenia, 9 najmniej znaczących bitów argumentu semflg określa prawa dostępu do zestawu semaforów (dla właściciela, grupy i innych). Bity te mają ten sam format i takie samo znaczenie, jak parametr mode wywołania open(2) (prawa uruchamiania nie są istotne dla semaforów, natomiast prawa zapisu oznaczają możliwość zmiany wartości semaforów).
Podczas tworzenia nowego zestawu semaforów semget() inicjuje związaną z zestawem semaforów strukturę semid_ds (patrz semctl(2)) w następujący sposób:
Parametr nsems może mieć wartość 0 (nie jest brany pod uwagę), jeśli nie będzie tworzony zestaw semaforów. W przeciwnym przypadku parametr nsems musi być większy od 0 i mniejszy lub równy maksymalnej liczbie semaforów w zestawie (SEMMSL).
Jeżeli zestaw semaforów już istnieje, to weryfikowane są uprawnienia.
W przypadku powodzenia, semget() zwraca identyfikator zestawu semaforów (liczbę nieujemną). W razie wystąpienia błędu zwracane jest -1 i ustawiane errno wskazując błąd.
POSIX.1-2008.
SVr4, POSIX.1-2001.
IPC_PRIVATE nie jest znacznikiem, ale szczególną wartością typu key_t. Jeśli wartość ta zostanie użyta jako parametr key, to system uwzględni jedynie 9 najniższych bitów parametru msgflg i (w razie powodzenia) utworzy nowy zestaw semaforów.
Wartości semaforów w nowo utworzonym zestawie są nieokreślone (POSIX.1-2001 jasno o tym mówi, choć POSIX.1-2008 określa, że przyszła wersja tego standardu może wymagać implementacji inicjującej semafory z wartością 0). Mimo że Linux, tak jak i wiele innych implementacji, nadaje im wartość początkową równą 0, to przenośne aplikacje nie powinny zależeć od tego zachowania i zamiast tego powinny wyraźnie inicjować semafory żądanymi wartościami.
Aby zainicjować semafory, należy na zestawie semaforów użyć operacji SETVAL lub SETALL wywołania semctl(2). W sytuacji gdy wiele procesów nie wie, który pierwszy zainicjuje zestaw semaforów, to aby uniknąć sytuacji wyścigu, można sprawdzić, czy pole sem_otime powiązanej struktury danych zwracanej przez operację IPC_STAT wywołania semctl(2) ma wartość niezerową.
Wywołania semget() dotyczą następujące ograniczenia zasobów związanych z zestawami semaforów:
Nazwa IPC_PRIVATE prawdopodobnie nie jest najszczęśliwsza. IPC_NEW w sposób bardziej przejrzysty odzwierciedlałoby rolę tej wartości.
Program pokazany niżej używa semget() do utworzenia nowego zestawu semaforów lub pozyskania identyfikatora zestawu istniejącego. Tworzy key do semget() za pomocą ftok(3). Pierwsze dwa argumenty wiersza poleceń są używane jako argumenty pathname i proj_id do ftok(3). Trzeci argument wiersza poleceń jest liczbą, określającą argument nsems do semget(). Opcje wiersza poleceń mogą posłużyć do określenia znaczników IPC_CREAT (-c) i IPC_EXCL (-x) do wywołania semget(). Użycie programu pokazano poniżej.
Najpierw tworzone są dwa pliki, które posłużą do wygenerowania kluczy za pomocą ftok(3), utworzenia dwóch zestawów semaforów za pomocą tych plików, a następnie wypisania zestawów używając ipcs(1):
$ touch mójklucz mójklucz2 $ ./t_semget -c mójklucz p 1 ID = 9 $ ./t_semget -c mójklucz2 p 2 ID = 10 $ ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x7004136d 9 mtk 600 1 0x70041368 10 mtk 600 2
Następnie demonstrujemy fakt, że gdy semctl(2) otrzymuje taki sam key (wygenerowany przez takie same argumenty do ftok(3)), zwraca identyfikator już istniejącego zestawu semaforów:
$ ./t_semget -c mójklucz p 1 ID = 9
Na końcu, demonstrujemy rodzaj kolizji, jaka może wystąpić gdy przekaże się ftok(3) różne argumenty pathname, które mają ten sam numer i-węzła.
$ ln mójklucz link $ ls -i1 link mójklucz 2233197 link 2233197 mójklucz $ ./t_semget link p 1 # Generuje taki sam klucz, jak 'mójklucz' ID = 9
/* t_semget.c
Na licencji GNU General Public License v2 lub późniejszej. */ #include <stdio.h> #include <stdlib.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> static void usage(const char *pname) {
fprintf(stderr, "Użycie: %s [-cx] ścieżka id-proj l-sem\n",
pname);
fprintf(stderr, " -c Używa znacznika IPC_CREAT\n");
fprintf(stderr, " -x Używa znacznika IPC_EXCL\n");
exit(EXIT_FAILURE); } int main(int argc, char *argv[]) {
int semid, nsems, flags, opt;
key_t key;
flags = 0;
while ((opt = getopt(argc, argv, "cx")) != -1) {
switch (opt) {
case 'c': flags |= IPC_CREAT; break;
case 'x': flags |= IPC_EXCL; break;
default: usage(argv[0]);
}
}
if (argc != optind + 3)
usage(argv[0]);
key = ftok(argv[optind], argv[optind + 1][0]);
if (key == -1) {
perror("ftok");
exit(EXIT_FAILURE);
}
nsems = atoi(argv[optind + 2]);
semid = semget(key, nsems, flags | 0600);
if (semid == -1) {
perror("semget");
exit(EXIT_FAILURE);
}
printf("ID = %d\n", semid);
exit(EXIT_SUCCESS); }
semctl(2), semop(2), ftok(3), capabilities(7), sem_overview(7), sysvipc(7)
Tłumaczenie niniejszej strony podręcznika: Rafał Lewczuk <R.Lewczuk@elka.pw.edu.p>, Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>, Robert Luberda <robert@debian.org> i Michał Kułach <michal.kulach@gmail.com>
Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe informacje o warunkach licencji można uzyskać zapoznając się z GNU General Public License w wersji 3 lub nowszej. Nie przyjmuje się ŻADNEJ ODPOWIEDZIALNOŚCI.
Błędy w tłumaczeniu strony podręcznika prosimy zgłaszać na adres listy dyskusyjnej manpages-pl-list@lists.sourceforge.net.
| 15 czerwca 2024 r. | Linux man-pages 6.9.1 |