Az olvasó-író probléma a párhuzamos programozás egyik legfontosabb problémája . Így van megfogalmazva:
Van egy memóriaterület , amely olvasható és írható. Több szál fér hozzá, miközben annyi szál tud egyszerre olvasni, amennyit akar, de írni csak egy tud. Hogyan biztosítható ilyen hozzáférési mód?
Meg lehet boldogulni egy közönséges mutex -szel , de ez nem optimális - a számítógép memóriája általában úgy van kialakítva, hogy több szál szabadon tudja olvasni és írni (csak az a probléma, hogy nincs garancia arra, hogy feldolgozás közben a változó nem fog hirtelen megváltozni) . Ennek a problémának több lehetősége van, különböző és megoldási lehetőségek. Kinek adjunk elsőbbséget – az olvasót vagy az írót –, az a programozóra marad.
Amíg a memória nyitva van olvasásra, biztosítson korlátlan hozzáférést az olvasóknak. Az írók addig várhatnak, ameddig csak akarnak.
Amint megjelent legalább egy író, senki mást nem engedtek be. Az összes többi tétlen lehet.
Mintaoldat [1] :
Globális egész számok readcount=0, writecount=0; Globális mutexek mutex1, mutex2, w, r OLVASÓ bérlő mutex1.enter olvasási szám = olvasási szám + 1 if readcount=1 akkor w.enter mutex1.hagy r.hagyja ...olvasás... mutex1.enter olvasásszám = olvasási szám - 1 ha readcount = 0 akkor w.leave mutex1.hagy ÍRÓ mutex2.enter írásszám = írásszám + 1 if writecount=1 akkor r.enter mutex2.hagy w.enter ...mi írunk... w.hagyja mutex2.enter írásszám = írásszám - 1 ha írásszám = 0 akkor r.leave mutex2.hagyKerülje el az állásidőt. Más szóval: a többi szál cselekvésétől függetlenül az olvasónak vagy írónak véges időn belül át kell lépnie a korláton.
Más szóval, egyetlen szál (olvasó vagy író) sem várhat túl sokáig a zár megszerzésével; a zár rögzítési funkciójának egy idő után, ha a zárolás meghibásodik, vissza kell térnie a zárolás sikertelen jelzőjével , hogy a szál ne legyen tétlen, és más dolgokat tudjon végezni. Ez az idő gyakran nulla: a rögzítési funkció azonnal visszatér, ha a rögzítés jelenleg nem lehetséges.
Globális mutexek: no_writers, no_readers, counter_mutex Globális egész számok: nreaders=0 Helyi egész számok: előző, aktuális ÍRÓ: no_writers.enter no_readers.enter ... írás .... no_writers.leave no_readers.leave OLVASÓ: no_writers.enter counter_mutex.enter preve:= nreaders nreaders := nreaders + 1 ha előző = 0, akkor no_readers.enter counter_mutex.leave no_writers.leave ...olvasás... counter_mutex.enter nreaderst:= nreaders - 1; currente:= nreaders; ha aktuális = 0, akkor no_readers.leave counter_mutex.leave;C kód a gcc gcc -o rw -lpthread -lm rewr.c számára
#include <pthread.h> #include <stdio.h> #include <math.h> #include <stdlib.h> #include <szemafor.h> #define M 4 //WR száma #define N 3 //RE unsigned int iter száma ; //iteráció sem_t accessM , readresM , orderM ; //sem. aláíratlan int olvasók = 0 ; // Az erőforráshoz hozzáférő olvasók száma érvénytelen * olvasó ( érvénytelen * prem ) { int szám1 =* ( int * ) prm ; int i = 0 , r ; for ( i ; i < iter ; i ++ ) { if ( sem_wait ( & orderM ) == 0 ) printf ( "%d Reader %d queued__________W%d \n " , i , num1 , num1 ); // Emlékezz az érkezési sorrendünkre sem_wait ( & readresM ); // Az olvasószámlálót manipulálni fogjuk if ( olvasók == 0 ) // Ha jelenleg nincsenek olvasók (mi voltunk az elsők)... sem_wait ( & accessM ); // ...kizárólagos hozzáférést kér a forráshoz az olvasók olvasói számára ++ ; // Megjegyzendő, hogy van még egy olvasó sem_post ( & orderM ); // Érkezési sorrend kiadása szemafor (kiszolgáltunk) sem_post ( & readresM ); // Egyelőre befejeztük az olvasók számának elérését printf ( "%d Reader %d________________W%d működik \n " , i , num1 , num1 ); // Itt az olvasó tetszés szerint olvashatja a forrást r = 1 + rand () % 4 ; alvás ( r ); sem_wait ( & readresM ); // Manipulálni fogjuk az olvasókat ellenolvasók -- ; // Indulunk, eggyel kevesebb olvasó van if ( olvasók == 0 ) // Ha jelenleg nincs több olvasó... sem_post ( & accessM ); // ...kizárólagos hozzáférés engedélyezése az erőforráshoz sem_post ( & readresM ); // Egyelőre befejeztük az olvasók számának elérését } } érvénytelen * író ( érvénytelen * prem ) { int szám2 =* ( int * ) prm ; int j = 0 , r ; for ( j ; j < iter ; j ++ ) { if ( sem_wait ( & orderM ) == 0 ) printf ( "%d Writer %d queued__________P%d \n " , j , num2 , num2 ); // Ne feledje az érkezési sorrendünket sem_wait ( & accessM ); // Kizárólagos hozzáférés kérése az erőforráshoz sem_post ( & orderM ); // Érkezési sorrend felszabadítása szemafor (kiszolgáltunk) printf ( "%d író %d________________P%d \n " , j , szám2 , szám2 ); // Itt az író tetszés szerint módosíthatja az erőforrást r = 1 + rand () % 4 ; alvás ( r ); sem_post ( & accessM ); // Kizárólagos hozzáférés engedélyezése az erőforráshoz } } érvénytelen fő () { pthread_t threadRE [ N ]; pthread_t threadWR [ M ]; sem_init ( & accessM , 0 , 1 ); sem_init ( & readresM , 0 , 1 ); sem_init ( & orderM , 0 , 1 ); printf ( "Adja meg az iterációk számát: " ); scanf ( "%d" , & iter ); printf ( "Iter QUEUE/EXECUTION \n " ); int i ; for ( i = 0 ; i < M ; i ++ ) { pthread_create ( & ( threadWR [ i ]), NULL , író ,( void * ) & i ); } for ( i = 0 ; i < N ; i ++ ) { pthread_create ( & ( threadRE [ i ]), NULL , olvasó ,( void * ) & i ); } for ( i = 0 ; i < N ; i ++ ) { pthread_join ( threadRE [ i ], NULL ); } for ( i = 0 ; i < M ; i ++ ) { pthread_join ( threadWR [ i ], NULL ); } sem_destroy ( & accessM ); sem_destroy ( & readresM ); sem_destroy ( & orderM ); }Sok olvasó XOR one writer (XOR - exkluzív vagy ) gyakran tekintik ennek a probléma invariánsának . Ez nem igaz, hiszen az a helyzet is helytálló, amikor nincs se olvasó, se író.
Az invariánst a következő állítással fejezhetjük ki:
írók == 0 VAGY írók == 1 ÉS olvasók == 0ahol az írók az írók száma, az olvasók az olvasók száma.
Gyakran egy egyszerű memóriavédő mutex nem optimális. Például egy online játékban a játéktermek listája ritkán változik - amikor az egyik játékos úgy dönt, hogy új szobát nyit, például néhány másodpercenként. Egy másodperc alatt több tucatszor olvassa el, és nincs értelme ehhez az ügyfeleket sorba rakni .
Hasonló mechanizmusok (úgynevezett olvasási-írási zárolás ) számos programozási nyelvben és könyvtárban léteznek. Például.