Jak bezpecne inicializovat semafor?

Pavel Kankovsky peak na argo.troja.mff.cuni.cz
Čtvrtek Prosinec 2 00:10:49 CET 2010


On Wed, 1 Dec 2010, d.petr wrote:

> Funkce semget, semop a semctl jsou mi snad jasné, ale vidím problém
> v počáteční inicializaci semaforu. Nikde jsem nenašel, že by se dal
> meziprocesový semafor vytvořit zároveň s inicializační hodnotou.
> A mezi vytvořením a inicializací jedním procesem už by mohl druhý
> proces začít semafor používat a inicializace by pak nedopadla dobře;

Není to jednoduché. Manuálová sice straší, že není garantovaná iniciální
hodnota semaforů a že portabilní program musí provést SETVAL. Kuriozní je,
že příklady na použití uváděné v POSIXu (byť nejsou normativní) jsou
napsané tak, že počítají s tím, že semafory jsou inicializované na nulu.

V podstatě existuje takový vychytralý způsob, jak to s velkou
pravděpodobností vyřešit. Předpokládejme, že každý (i neinicializovaný)  
semafor bude mít hodnotu 0 až MAX pro nějaké známé MAX (SEMVMX) a že
operace, která by jí nastavila mimo tento interval, vždy selže.

1. Vyrobím semget() na pole N+1 semaforů. (Čím větší N, tím menší
pravděpodobnost selhání celého postupu za předpokladu, že semafory mají
na začátku náhodné hodnoty.)

2. Přečtu jejich hodnoty pomocí semctl(GETALL). Pokud se hodnot aspoň
jednoho semaforu č. 0 až N-1 liší od MAX, pak provedu bez čekání semop(),
které č. 0 až N-1 zvětší na MAX a č. N upraví na 1. Pokud semop()
z jakéhokoli důvodu selže, pak krok 2 opakuju.

3. Pro zamčení provedu semop(), které o jedna zmenší semafor č. N.


On Wed, 1 Dec 2010, Frantisek Boranek wrote:

> Lze pouzit napr:
>  sem_t *hSemaphore = sem_open(name.c_str(), flags, mode, initValue);

To jsou to tzv. POSIXové semafory a ne System V. Ale použít jdou a
je to pravděpodobně mnohem lepší API (viz výše).

-- 
Pavel Kankovsky aka Peak                          / Jeremiah 9:21        \
"For death is come up into our MS Windows(tm)..." \ 21st century edition /




Další informace o konferenci Linux