Az író-olvasó zár vagy megosztott-kizáró zár a számítástudományban egy szinkronizációs primitív, ami megoldja az egyik író-olvasó problémát. A zár megengedi több olvasó együttes hozzáférését, de az író kizárólagos hozzáférést igényel; így az adatot egyszerre többen is olvashatják, de csak egy írhatja. Ennek használatára példa egy adatszerkezet a memóriában, ami nem frissíthető atomi módon, és érvénytelen, amíg az írás nincs kész.

Általában feltételváltozókkal, mutexekkel vagy szemaforokkal szabályozza a hozzáférést.

Néhány zár lehetővé teszi a változtatást az író és az olvasó zár között.

Prioritás A zár tervezhető úgy, hogy különböző prioritást adjon az író és az olvasó szálaknak. Lehetnek priorizáltak az olvasók, vagy az írók, de lehet az is, hogy nincs prioritás.

Ha nincs prioritás, akkor nincs garancia az írók vagy az olvasók hozzáférésére. Bizonyos helyzetekben (ritka hozzáférés) előnyös lehet, mert hatékonyabb.

Az olvasók priorizálása maximalizálja a konkurenciát, de az írók kiéheztetéséhez vezethet. Ez ugyanis azt jelenti, hogy az olvasók folyamatosan zárolva tarthatják az objektumot, hiszen egyszerre többen tudnak olvasni. Így amikor egy olvasó végez, lehet még olvasó, aki zárolva tartja az objektumot. Ha A és B olvassa éppen az objektumot, és A végez, akkor jöhet egy C, ami szintén megszerzi az olvasó lockot. Ha B végez, jöhet egy D, és így tovább. Az eddig leírt mód szerint a prioritás gyenge, de lehet erős is, amikor írás után bármelyik blokkoló olvasó megszerezi a zárat a következőben.

Az írók priorizálása azt jelenti, hogy ha egy író benyújtja igényét, akkor újabb olvasók nem szerezhetik meg a zárat, és ha minden olvasó befejezte az olvasást, akkor jön az író. Ennek az az előnye, hogy az írók nem lesznek kiéheztetve, hátránya pedig, hogy kisebb konkurenciát enged meg. A zár megszerzése és elengedése is nehezebb, mert két mutexet kell használni. Ezt néha író-elfogult zárnak is nevezik. Java readers–writer lock implementation offers a "fair" mode

Megvalósítás Az író-olvasó zárat többféleképpen is meg lehet valósítani, és visszavezetni más szinkronizációs primitívekre, amelyekről feltételezhető, hogy léteznek. Két mutexszel Raynal megmutatta, hogy hogyan lehet két mutex és egy számláló felhasználásával elkészíteni az író-olvasó zárat. A számlálót b jelöli, ez számolja, hány olvasó van. Az egyik mutex r, ezt csak az olvasók használják, ez védi b-t, a másik g, ezt mindenki használja, és ez biztosítja az írók kizárólagos hozzáférését. Ez azt feltételezi, hogy ha egy szál megszerzett egy mutexet, akkor egy másik szál kioldhatja. A megvalósítás az írókat részesíti előnyben. Pszeudokód:

Begin Read

Lock . Increment . If , lock . Unlock .

End Read

Lock . Decrement . If , unlock . Unlock .

Begin Write

Lock .

End Write

Unlock .

Egy feltételes változóval és egy mutexszel A minta megvalósítható egy feltételes változóval és egy mutexszel is, ami használ egy egész számlálót és egy bool flaget is. Az olvasó zárolás a következő:

Input: mutex , condition variable , integer (number of readers waiting), flag (writer waiting). Lock (blocking). While :

Increment . Unlock .

Hasonló az író zárolás is:

Input: mutex , condition variable , integer (number of readers waiting), flag (writer waiting). Lock (blocking). While ( or ):

Set to . Unlock .

Mindkettőnek megvan az inverz művelete is. Az olvasó zár elengedéséhez fogni kell az m mutexet, és csökkenteni kell r-t, és jelezni c-ben, ha r nullává vált. Ekkor a c-re várakozó szálak közül valamelyik megszerezheti a zárat. Az író zár elengedéséhez fogni kell az m mutexet, a w-t hamisra kell állítani, és jelezni c-ben.

Alternatívák Az olvasás-másolás-frissítés (RCU) algoritmus egy másik megoldás az író-olvasó problémára, ami nem várakoztatja meg az olvasókat.

A Linux rendszermag egy speciális megoldást, a szekvenciális zárat használja, ami kevés írót feltételez.

Programnyelvi támogatás pthread_rwlock_t POSIX szabvány a hozzá tartozó műveletekkel a ReadWriteLock interfész és ReentrantReadWriteLock zár Java 5-től kezdve Microsoft System.Threading.ReaderWriterLockSlim a .NET nyelvei számára std::shared_mutex a C++17-hez a Boost programkönyvtárban a boost::shared_mutex és boost::upgrade_mutex SRWLock a Windows API-jában a Vistától kezdve sync.RWMutex a Go programozási nyelvhez Phase fair zár, ami váltogat az írók és az olvasók között std::sync::RwLock zár a Rustban a POCO programkönyvtárban a Poco::RWLock a txrwlock.ReadersWriterDeferredLock a Twistedben

Megjegyzések

Jegyzetek

Fordítás

Kategória:Programtervezési minták