Jag har en tråd som när ett message kommer in skapar ett ex av en tråd med parametrar från det inkomna meddelandet. Tyvärr, ;-j, så ska ett meddelande - som beror av trådens returvärde - skickas tillbaka varje gång en av de skapade trådarna avslutas. Har (för ett rätt bra tag sen) gjort ett mkt enkelt shell till OpenBSD och då använde jag nog principen att låta varje tråd göra sitt jobb, och låta den styrande tråden sköta all bokföring runt om. För trött för att kolla på koden exakt, men jag ska återkomma för att ge något slags input här. Ok, lite mer utförligt: Jag har en/flera klienter som när som helst kan skicka msg till en server om att skapa planeter i det här fallet :). Fortfarande för trött, men jag har några ytterligare spontana tankar: 1. Huvet på spiken B). Det är en skoluppgift, och det handlar om att synka åtkomst till delade objekt(planetdatabasen i det här fallet). Jag gillar uppgiften, mest kreativa som jag fått därifrån, speciellt som planeterna ritas upp i ett fönster så man ser vad som händer. Hur funkar det i allmänhet då, hur gör du om du vill ha "oändligt många"? Det här är bara om min allmänna ovilja att skriva begränsade program. I specen står det varken för eller emot begränsat antal planeter. Annars är det ju bara att allokera nya vid behov (eller varje gång, enklare). Eftersom det är pekare är det inte speciellt dyrt (om du har säg, <100 planeter), och då är det bara malloc som sätter gränserna. Det känns som att vi försöker övertyga varann om en sak som vi redan tycker lika om :). Hahaha....sitter och skriver när fyllan inte ens gått över till bakfylla... då blir det så... =)Trådar och returvärden i Win32. Var och när?
Alt 1) "Huvudtråden" känner av när en tråd avslutas, tar returvärdet och skickar iväg ett meddelande.
Alt 2) Den skapade tråden skriver själv ihop meddelandet som sista grej innan den avslutas.
1:an känns mer "ren", och som i kursens anda(handlar mycket om synkronisering). Men då kan jag antingen
while(1)
Om meddelande kommit in
skapa_tråd()
spara handle i array
WaitForMultipleObjects(arrayen, 0 i timeout)
Om nån tråd avslutats
GetExitCodeThread()
Skriv meddelande och skicka
Gör annat som behövs
eller
while(1)
Om meddelande kommit in
skapa_tråd()
spara handle i lista
Gå igenom listan
GetExitCodeThread(handle i nuvarande listpost)
Om ExitCode!=STILL_ACTIVE
Skriv ihop meddelande och skicka
Gör annat som behövs
Eftersom trådarna kan avsluta i vilken ordning som helst så är listan lättare att underhålla. Men inget av alternativen känns ju elegant..
Att skapa X trådar, vänta på att dom blir färdiga och göra annat samtidigt, och sedan ta deras returvärden *kan* inte vara en ovanlig sits i ett operativsystem. Så det känns som om nåt undgått mig än så länge.
Tycken/kritik/kommentarer?Sv: Trådar och returvärden i Win32. Var och när?
Sv:Trådar och returvärden i Win32. Var och när?
Servern skapar plats för planeten i databasen och skapar en tråd per planet, som uppdaterar planeten/databasen m.a.p. position(gravitationen mellan planeterna påverkar), livstid, etc. Servern har även en tråd som ritar ut planeterna i ett fönster kontinuerligt.
Data för planeterna som trådarna uppdaterar ligger i en databas/länkad lista. När livstiden för en planet gått ut eller om planeten hamnar utanför <satta gränskoordinater> så avslutar motsvarande "uppdaterar-tråd".
Ska man ha:
- Tråd som tar emot msg(mailslot), lägger till post i databasen och skapar ny "uppdaterar-tråd".
- X trådar som uppdaterar planeterna, med returkod beroende på om planeten hamnade utanför gränserna eller fick slut på livstid.
- Tråd som WaitForMultipleObjects() tills en planet är färdig, tar orsak till det och skickar det tillbaka till klienten. Problem om översta tråden skapar en till planet medan WaitForMultipleObjects() redan körs. Kan man lösa det genom att en av sakerna WaitForMultipleObjects() väntar på är nåt slags signal från översta tråden? Och resten som den väntar på är uppdaterartrådar?
Lol, hoppas det där gick att förstå.Sv: Trådar och returvärden i Win32. Var och när?
1. Ska beräkningen verkligen ske en tråd per planet? Då kommer de ju riskera att gå i ofas!
2. Om det är det som är poängen (inte omöjligt om det är skoluppgifter), så tycker jag att den lösningen du säger verkar funka. Kan du beskriva noggrannare varför det blir problem när en tråd skapas?
För att den inte kommer med i MultipleObjects?
I princip borde du då kunna göra så här:
Tråd A är den du nämner sist.
Den börjar med att starta en "väntar på grejer från klient"-tråd, tråd B.
Utöver det har den en radda planet-trådar tråd C1 ... CN.
När någon av C1 ... CN eller B avslutas, så kör du om från början.
Om det var B som avslutades, starar du den igen och en ny C(N+1) för den nya planeten. Sv:Trådar och returvärden i Win32. Var och när?
2. Rätt igen. (Ni vet ju säkert det här, men för att beskriva problemet:) Planeterna har antagligen en livstid på några minuter, så när ett skapaplanet-meddelande kommer in, så är WaitForMultipleObjects() antagligen redan igång. Och den väntar ju inte automatiskt på den nya planeten bara för att den läggs in i arrayen, utan Wait...() får avbrytas, arrayen uppdateras och sen startas Wait...() igen.
Få se nu(servern avslutas när fönstret stängs):
MainThread()
|
+------------------------------+-----+-...........-+
| | | |
GetClientMsgThread() P1 P2 Pn
GetClientMsgThread() väntar/loopar(hoppas inte, beror på vad jag hittar för kommandon för mailslots) tills ett message kommer. Det innehåller en struct som den ska se ut i databasen, så pekare till den returneras till MainThread()
Px uppdaterar sin planet tills livstiden är slut/planeten farit iväg utanför bild. Den får pekare till sin planet-struct som inparametern. När tråden avslutar så returnerar den pekare till planet-structen
MainThread()
for(;;)
Skapa GetClientMsgThread()
Spara handle i arrayen. Fast plats där för GetClientMsgThread()
WaitForMultipleObjects(array,INFINITE)
Om GetClientMsgThread() avslutade
Lägg in returnerade structen i databasen
Skapa Px-tråd och skicka med pekare till structen
(Leta upp ledig plats i arrayen)
Spara Px-trådhandle i arrayen
Om Px-tråd avslutade
Ta returnerad pekare till planet-struct
Ta bort planeten ur databasen
Skriv ihop meddelande och skicka till klient
Ta bort tråden ur arrayen
Problem med arrayen: Antar att WaitForMultipleObjects() inte gillar om arrayen har utspridda handles med x antal NULL mellan :-|.. Men det är ju inget som inte är lösbart.
Jag skruvar mig lite grann eftersom antalet planeter vid första anblicken ju blir begränsat till arrayens storlek. Men om man vid behov allokerar mera plats för arrayen så löser det sig ju..Sv: Trådar och returvärden i Win32. Var och när?
Sv:Trådar och returvärden i Win32. Var och när?
Inga konstigheter planerade iallafall, tänkte mig att klienten får ett meddelande tillbaka att planeten inte kunde startas, om det inte finns minne för databasposten eller utrymme i trådarrayen.Sv: Trådar och returvärden i Win32. Var och när?
Sv:Trådar och returvärden i Win32. Var och när?
"Jag skruvar mig lite grann eftersom antalet planeter vid första anblicken ju blir begränsat till arrayens storlek. Men om man vid behov allokerar mera plats för arrayen så löser det sig ju.."
För det måste väl tyvärr vara en array ändå, inte en lista.. Det större problemet blir ju när en tråd avslutas->en handle försvinner->arrayen måste kompakteras.
Hur som helst, så känns det här som en möjlig väg :).Sv: Trådar och returvärden i Win32. Var och när?
Bara för att get things straight: Du ämnar testa min variant, och kommer göra det med en array som är dynamisk i storlek?