Readers & Writers problem - thread safe i python.

Permalänk
Medlem

Readers & Writers problem - thread safe i python.

Hej alla!

Jag har som uppgift i Python att göra ett program som har 3 readers och 2 writers där kraven är som följande:

  1. 1: Reader threads får använda samma minne samtidigt som varandra men aldrig samtidigt som en writer

  2. 2: En writer får aldrig använda minnet samtidigt som en annan writer.

  3. 3: När en reader ELLER writer använder minnet ska ett meddelande skrivas ut med informationen som finns i resursen.

  4. 4: Writer 1 sparar datumet i minnet

  5. 5: Writer 2 läser vad som finns i minnet och vänder på meddelandet.

Nu till problemet:

Jag har ett program, (jag är fullt medveten om att det är ful kod men jag tränar här), som gör detta men som inte är helt thread safe. Jag fick en flummig feedback i form av att programmet inte riktigt ordentligt kollar om det skrivna är skrivskyddat? Jag lyckas inte lista ut hur jag ska göra för att göra programmet helt thread safe, (vilket är ett krav.)

Alla tips uppskattas, även hur programmet kan förbättras.

kod:

from threading import Thread from threading import Lock import time resource = time.strftime("%c") lock = Lock() counter = 0 class WriterA(Thread): def run(self): while True: global lock global resource global counter if counter == 0: lock.acquire() counter == -4 resource = time.strftime("%c") print ("Writer A acquired the lock and the message is: %s. " %resource) counter = 0 lock.release() time.sleep(5) class WriterB(Thread): def run(self): while True: global lock global resource global counter if counter == 0: lock.acquire() counter == -5 resource = resource[::-1] print ("WriterB acquired the lock and the message is: %s. " %resource) counter = 0 lock.release() time.sleep(5) class Reader(Thread): def run(self): while True: global resource global counter if counter >= 0: counter = 1 print ("Reader acquired the resource and the message is: %s" %resource) counter -= 1 time.sleep(5) writerA = WriterA() writerB = WriterB() reader1 = Reader() reader2 = Reader() reader3 = Reader() writerA.start() writerB.start() reader1.start() reader2.start() reader3.start()

Vet inte varför koden inte ser rätt ut när jag skriver den här på Sweclockers.

La till code-taggar
Visa signatur

Gaming: RTX 2070 & 3770k
Studier: MacBook pro retina 13
Ljud: QH-1339 & ett par rackans smidiga AirPods
Telefon: iPhone 6s plus
Skärm: ASUS 27" ROG Swift PG279Q med sån där g-sync

Permalänk
Hedersmedlem

La till code-taggar, vilket saknades och därför koden såg konstig ut.

EDIT: Insåg också att tråden såklart passar bättre i programmerings-forumet.

EDIT2: Kan slänga in en fråga. Hur ser du till att and Reader inte läser samtidigt som en Writer skriver?

//Mod

Permalänk
Medlem

Nu kan jag inte bidra så mycket till uppgiften, men har exakt samma uppgift att göra, men har inte börjat ännu.
Får man fråga om det är Labb 5 i operativsystem på Miun?

Visa signatur
Permalänk
Datavetare

@MuLLvaD3n: grunden till att få till detta är att dels förstå vad ett "data race" är och hur det är applicerbart på ditt program.

Ett data race uppstår om

  • det finns minst två trådar som har något minne de delar

  • minst en av trådarna skriver till det delade minnet

  • minst en av trådarna läser eller skriver till det delade minnet utan att den operationen är synkroniserad

I detta fall är roten till att förstå uppgiften applicera ovan på programmet.

Så vilken minne har du som är delat mellan trådarna?

Det är detta

resource = time.strftime("%c") lock = Lock() counter = 0

För att nu korrekt lösa denna uppgift, se fundera hur access till counter och resource hanteras mellan trådar. Tips: lägg till en kommentar till alla delade variabler du kommer ha i dina framtida program, där ska det framgå hur access till den variabeln är synkroniserad.

Största felet som folk gör kring lås är att resonera som att de skyddar kodsektioner. Kod är i normalfallet "read-only" så det behöver inte skyddas, det som måste synkronisera är data.

Hint: skriver hela tiden "synkronisera" och inte att data bara kan läsas/skrivas när man håller ett lås... Finns fler än ett sätt att synkronisera access, men första steget kräver nästan alltid ett lås (när/om ni kommer till lock-less/wait-less algoritmer finns lite andra sätt men det är väldigt överkurs här).

Tänk också exakt på vad du vill att counter ska symbolisera, du har faktiskt både läsare och skrivare...

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem

@Yoshman: Hej! Jag vill bara uppdatera tråden med att säga tack för hjälpen. Jag har inte glömt av detta!

Jag har lyckats lösa problemet och det var mycket på grund av din hjälp, tack! Jag lägger upp lösningen här så fort jag har skickat in rapporten, (man skulle inte råka vilja fasta i urkund ).

Visa signatur

Gaming: RTX 2070 & 3770k
Studier: MacBook pro retina 13
Ljud: QH-1339 & ett par rackans smidiga AirPods
Telefon: iPhone 6s plus
Skärm: ASUS 27" ROG Swift PG279Q med sån där g-sync

Permalänk
Datavetare

Kul att det gick bra!

Vill du få din dator att rätta dina synkroniseringsmisstag kan du lära dig lite Rust

Till skillnad från alla programspråk jag känner till som tillåter trådar att dela tillstånd är det fullt möjligt att skapa data-race. Men är Rust konstruerat på ett sådant sätt att kompilatorn upptäcker alla fall som skulle leda till ett data-race, det är om något en killer-feature (data-race buggar är en av de absolut svåraste felet att hitta).

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

Permalänk
Medlem
Skrivet av Yoshman:

Kul att det gick bra!

Vill du få din dator att rätta dina synkroniseringsmisstag kan du lära dig lite Rust

Till skillnad från alla programspråk jag känner till som tillåter trådar att dela tillstånd är det fullt möjligt att skapa data-race. Men är Rust konstruerat på ett sådant sätt att kompilatorn upptäcker alla fall som skulle leda till ett data-race, det är om något en killer-feature (data-race buggar är en av de absolut svåraste felet att hitta).

Det låter intressant. Jag är ganska klar med Python nu men kommer att hålla på med mycket C++, olika algoritmer och deadlocks framöver så ska helt klart kolla in Rust.

Som sagt, lägger in min kod här så fort jag har fått in rapporten!

Visa signatur

Gaming: RTX 2070 & 3770k
Studier: MacBook pro retina 13
Ljud: QH-1339 & ett par rackans smidiga AirPods
Telefon: iPhone 6s plus
Skärm: ASUS 27" ROG Swift PG279Q med sån där g-sync