W celu utworzenia nowego zestawu semaforów, lub dostępu do istniejącego, używamy wywołania systemowego semget().
WYWOŁANIE SYSTEMOWE: semget();
PROTOTYP: int semget ( key_t key, int nsems, int semflg );
ZWRACA: indentyfikator IPC zestawu, jeżeli sukces
-1 - błąd: errno = EACCESS ( brak prawa dostępu )
EEXIST ( zestaw istnieje, nie można utworzyć (IPC_EXCL) )
EIDRM ( zestaw zaznaczony do usunięcia )
ENOENT ( zestaw nie istnieje, nie podano IPC_CREAT )
ENOMEM ( brak pamięci do utworzenia zestawu )
ENOSPC ( limit ilości zestawów przekroczony )
UWAGI:
Pierwszym argumentem dla semget() jest wartość klucza ( w naszym przypadku zwrócona przez ftok()). Wartość ta porównywana jest do istniejących kluczy. Teraz operacje otworzenia lub dostępu zależą od zawartości argumentu semflg:
Utwórz zestaw semaforów jeżeli jeszcze nie istnieje w jądrze.
Użyte z IPC_CREAT zwraca błąd jeżeli zestaw już isnieje.
Jeżeli używamy samego IPC_CREAT semget() zwraca identyfikator zestawu, który został utworzony lub identyfikator już istniejącego, który posiada podaną wartość klucza. Jeżeli podano również IPC_EXCL zostanie utworzony nowy zestaw lub wywołanie zwróci -1. Podanie tylko IPC_EXCL jest bezużyteczne, jednak w połączeniu z IPC_CREAT gwarantuje nam, iż nie używamy istniejącego semaforu.
Tak jak dla każdej innej formy IPC Systemu V możemy podać ósemkowe prawa dostępu, które zostaną z'OR'owane z umaską aby utworzyć prawa dostępu dla zestawu.
Argument nsems określa liczbę semaforów, które zostaną utworzone dla nowego zestawu. Reprezentuje to liczbę drukarek w naszym przykładzie. Maxymalna liczba semaforów jest zdefiniowana w linux/sem.h:
#define SEMMSL 32 /* <=512 maxymalna liczba semaforów dla id */
Zauważ, iż arument nsems jest ignorowany gdy otwieramy już instniejący zestaw.
Stwórzmy szkielet funkcji otwierającej lub tworzącej zestaw semaforów:
int open_semaphore_set( key_t keyval, int numsems )
{
int sid;
if ( ! numsems )
return(-1);
if((sid = semget( mykey, numsems, IPC_CREAT | 0660 )) == -1)
{
return(-1);
}
return(sid);
}
Zauważ, że używamy praw dostępu 0660. Nasza prosta funkcja zwraca identyfikator zestawu (int) lub -1, jeżeli coś nie poszło. Musimy jej podać wartość klucza, oraz liczbę semaforów, dla których mamy zająć miejsce, pod warunkiem, że tworzymy zestaw. W przykładzie zaprezentowanym pod koniec rozdziału używamy również flagę IPC_EXCL w celu sprawdzenia czy semafor istnieje.