Hlavní navigace

Programování pod Linuxem pro všechny (22)

Jakub Matys 2. 7. 2004

Dnes se podíváme na synchronizaci procesů pomocí semaforů. Probereme zde alokaci a dealokaci semaforů, inicializaci a známé operace wait a post.

V minulém dílu jsem zmiňoval, že procesy musí synchronizovat přístup do sdílené paměťi. Využívají se pro to semafory procesů. Tyto semafory však pracují jiným způsobem než semafory pro vlákna, které jsou definovány jako čítače umožňující synchronizaci činnosti vláken. Semafory pro synchronizaci procesů se používají podobně jako segmenty sdílené paměťi. Semafory procesů můžete využívat v celých množinách (většinou však stačí jeden semafor).

Alokace a dealokace

Funkcemi pro alokaci a dealokaci semaforů jsou semget() asemctl(), které se používají podobně jako funkce pro sdílenou paměť – shmget() a shmctl(). Funkci semget() se předává klíč specifikující množinu semaforů, počet semaforů v množině a přístupová práva. Funkce vrací identifikátor množiny semaforů.

Semafory v systému existují i v případě, kdy všechny procesy, které je používaly, jsou již ukončeny. Poslední proces používající semafory je musí odstranit (počet semaforů je omezený). Využívá se k tomu funkce semctl(). Prvním argumentem je identifikátor semaforu, druhým počet semaforů v množině, třetím IPC_RMID a čtvrtým je hodnota union semun, která je ignorována. Odstranění semaforu probíhá bezprostředně!

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

/* Definovani unionu semun */
union semun{
  int val;
  struct semid_ds *buf;
  unsigned short int *array;
  struct seminfo *__buf;
};

/* Funkce ziska identifikator semaforu, nebo jej alokuje */

int binary_semaphore_allocation(key_t key, int sem_flags)
{
  return semget(key, 1, sem_flags);
}

/* Dealokace semaforu */

int binary_semaphore_deallocate(int semid)
{
  union semun ignored_argument;
  return semctl(semid, 1, IPC_RMID, ignored_argument);
} 

Inicializace semaforů

Inicializace je jiná operace než alokace. K inicializaci semaforu se používá funkce semctl(). Druhý argument je nulový, třetí obsahuje hodnotu SETALL. Pro čtvrtý argument musíte vytvořit objekt union semun a musíte použít ukazatel na jeho pole array. Každá hodnota je použita pro inicializaci jednoho semaforu v množině.

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

/* Definovani uinonu semun */
union semun{
  int val;
  struct semid_ds *buf;
  unsigned short int *array;
  struct seminfo *__buf;
};

/* Inicializace semaforu s hodnotou 1 */

int binary_semaphore_initialize(int semid)
{
  union semun argument;
  unsigned short values[1];
  values[0] = 1;
  argument.array = values;
  return semctl(semid, 0, SETALL, argument);
}

Operace wait a post

Každý semafor má nezápornou hodnotu a podporuje operace wait a post. Funkce semop() provede obě operace. Prvním parametrem je množina semaforů, druhým pole elementů struct sembuf, které specifikuje požadované operace, a třetím parametrem je délka tohoto pole.

Položky struktury struct sembuf:

  • sem_num – číslo semaforu v množině semaforů, pro které se má operace realizovat
  • sem_op – celé číslo specifikující operaci se semaforem. Pokud je sem_op kladné, je okamžitě přičteno k hodnotě semaforu. Je-li záporné, je jeho absolutní hodnota odečtena od hodnoty semaforu. Je-li po odečtení hodnota semaforu záporná, volání se zablokuje, dokud není hodnota semaforu tak velká jako absolutní hodnota sem_op. Pokud je hodnota sem_op nulová, zablokuje se volání, dokud není hodnota semaforu nula.
  • sem_flg – hodnota příznaku. Pokud chcete zabránit zablokování operace, používejte hodnotu IPC_NOWAIT. Pokud by byla operace již zablokovaná, funkce vrátí chybový návratový kód. Jestliže specifikujete hodnotu SEM_UNDO, systém automaticky vrátí operaci semaforu zpět v okamžiku, kdy proces skončí.
#include <sys/types.h>

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

/* Operace wait */

int binary_semaphore_wait(int semid)
{
  struct sembuf operations[1];
  /* Pouzij prvni(jediny) semafor */
  operations[0].sem_num = 0;
  /* Zmensi o 1 */
  operations[0].sem_op = -1;
  /* Nastaveni hodnoty SEM_NUDO */
  operations[0].sem_flg = SEM_UNDO;

  return semop(semid, operations, 1);
}

/* Operace post */

int binary_semaphore_post(int semid)
{
  struct sembuf operations[1];
  operations[0].sem_num = 0;
  operations[0].sem_op = 1;
  operations[0].sem_flg = SEM_UNDO;

  return semop(semid, operations, 1);
}

To by bylo pro dnešek vše. Příště se podíváme na mapovanou paměť, ta umožňuje různým procesům komunikovat prostřednictvím sdíleného souboru.

Našli jste v článku chybu?

3. 11. 2009 11:05

tonicek (neregistrovaný)

Do prvního řádku odstavce ‚Alokace a dealokace‘ se zjevně vloudila chybička;
místo:
semget() asemctl()
tam má být:
semget() a semctl()





27. 5. 2011 0:17

janmachala (neregistrovaný)

Možná by vůbec nebylo špatné přidat příklad synchronizovaného kódu pomocí těchto funkcí, třeba úlohu producent - konzument. Taky na místo toho říct, že inicializace je jiná než alokace, by bylo vhodnější vysvětlit v čem je jiná, resp. co přesně se děje v alokaci a co v inicializaci.

Podnikatel.cz: Platební brány a EET? Stále s otazníkem

Platební brány a EET? Stále s otazníkem

Vitalia.cz: Jak koupit Mikuláše a nenaletět

Jak koupit Mikuláše a nenaletět

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Vitalia.cz: Vláknina: Rozpustná, nebo nerozpustná?

Vláknina: Rozpustná, nebo nerozpustná?

Lupa.cz: E-shopy: jen sleva už nestačí

E-shopy: jen sleva už nestačí

Vitalia.cz: To není kašel! Správná diagnóza zachrání život

To není kašel! Správná diagnóza zachrání život

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Root.cz: Vypadl Google a rozbilo se toho hodně

Vypadl Google a rozbilo se toho hodně

Vitalia.cz: Říká amoleta - a myslí palačinka

Říká amoleta - a myslí palačinka

DigiZone.cz: Sony KD-55XD8005 s Android 6.0

Sony KD-55XD8005 s Android 6.0

Podnikatel.cz: Dárky v podnikání. Jak je uplatnit v daních?

Dárky v podnikání. Jak je uplatnit v daních?

120na80.cz: Pánové, pečujte o svoje přirození a prostatu

Pánové, pečujte o svoje přirození a prostatu

Vitalia.cz: Tesco: Chudá rodina si koupí levné polské kuře

Tesco: Chudá rodina si koupí levné polské kuře

Měšec.cz: Finančním poradcům hrozí vracení provizí

Finančním poradcům hrozí vracení provizí

DigiZone.cz: NG natáčí v Praze seriál o Einsteinovi

NG natáčí v Praze seriál o Einsteinovi

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Lupa.cz: Google měl výpadek, nejel Gmail ani YouTube

Google měl výpadek, nejel Gmail ani YouTube

DigiZone.cz: Další dva kanály nabídnou HbbTV

Další dva kanály nabídnou HbbTV

Podnikatel.cz: EET: Totálně nezvládli metodologii projektu

EET: Totálně nezvládli metodologii projektu

Lupa.cz: UX přestává pro firmy být magie

UX přestává pro firmy být magie