Reentrancy

Počítačový program jako celek nebo jeho samostatná procedura se nazývá reentrant , pokud  je navržen tak, že stejnou kopii programových instrukcí v paměti může sdílet několik uživatelů nebo procesů. Druhý uživatel zároveň může zavolat reentrantní kód dříve, než s ním první uživatel dokončí práci, a to by alespoň nemělo vést k chybě a při správné implementaci by to nemělo způsobit ztrátu výpočtů (tj. by nemělo být nutné spouštět již provedené fragmenty kódu) .  

Reentrancy úzce souvisí s bezpečností funkce ve vícevláknovém prostředí ( thread-safety ), jedná se však o odlišné koncepty. Zajištění opětovného vstupu je klíčové při programování multitaskingových systémů, zejména operačních systémů .

Pro zajištění opětovného vstupu je nutné splnit několik podmínek:

Obecně reentrancy vyžaduje, aby volající proces nebo funkce pokaždé předal volanému procesu všechna potřebná data. Tedy funkce, která závisí pouze na svých parametrech, nepoužívá globální ani statické proměnné a pouze volá reentrantní funkce, bude reentrantní. Pokud funkce používá globální nebo statické proměnné, musíte zajistit, aby si každý uživatel ponechal svou vlastní lokální kopii těchto proměnných.

Příklad

V následujícím úryvku kódu se funkce f() a g() znovu nevstupují.

int g_var = 1; int f() { g_var = g_var + 2; return g_var; } int g() { return f() + 2; }

Zde f() závisí na globální proměnné g_var , takže pokud dva procesy volají f() současně, výsledek je nepředvídatelný. Proto f() není reentrantní. Ale ani g() není reentrantní, protože používá nereentrantní funkci f() .

V následujícím úryvku kódu není funkce accum() také reentrantní.

int accum(int b) { statické int a = 0; ++a; return(a+b); }

Zde accum  je funkce, která akumuluje hodnotu a , za kterou je zodpovědná statická proměnná. Pokud je accum voláno různými procesy, výsledek bude také nepředvídatelný. Stejně jako v předchozím příkladu je a sdíleno všemi volajícími procesy.

Ke ztrátě opětovného vstupu může také dojít, když je stejná proměnná použita více než jednou ve výrazu.

#define SQR(x) ((x)*(x)) void func(void) { int x, y; x = SQR(y); }

V tomto případě makro SQR(x) nebude fungovat správně, pokud se změní při každém přístupu k argumentu.

Odkazy