Ik heb een applicatie waar ik een aantal threads gelijktijdig wil starten. Ik kan ergens nergens vinden hoe dit kan en of dit kan. Heb al aan een ThreadGroup gedacht, maar deze class biedt niet de mogelijkheid om de hele groep in 1 keer te starten. Op dit moment start ik dus iedere thread vervolgens op, maar het zou beter zijn moest dit in 1 keer kunnen, dus dat iedere thread op hetzelfde moment begint te lopen.
Pak een event en lock allebei de threads direct na hun start op dat event, en maak vervolgens het event in 1 keer hoog.
Je kunt je threads toch nooit op exact hetzelfde moment starten, dus zou ik het gewoon laten zoals het is. Het is onmogelijk om een zinnige oplossing te geven aangezien de Java VM praktisch niets garandeerd over de kosten van threads of synchronisatieprimitiven; alles is platformafhankelijk. Het maakt al een wereld van verschil of je dit op een systeem met een enkele processor probeert (dan kun je een klein aantal threads wel in dezelfde timeslice starten) of op een multiprocessor systeem.
Ik betwijfel of locks in de praktijk ook maar iets helpen. Zelfs als dat in jouw geval zo blijkt te zijn, is het alleen een situatiespecifieke winst, die op een ander platform misschien juist een verlies zou kunnen opleveren. Omdat je het dus eigenlijk niet goed kan doen, zou ik je aanraden om het gewoon niet te doen, en je tijd en extra code nuttiger te besteden.
Ik betwijfel of locks in de praktijk ook maar iets helpen. Zelfs als dat in jouw geval zo blijkt te zijn, is het alleen een situatiespecifieke winst, die op een ander platform misschien juist een verlies zou kunnen opleveren. Omdat je het dus eigenlijk niet goed kan doen, zou ik je aanraden om het gewoon niet te doen, en je tijd en extra code nuttiger te besteden.
Mijn voorstel met een Event (geen idee of Java zoiets heeft) boeit idd alleen als je HT en/of SMP hebt, en dan nog alleen als de threads op andere CPU's zijn gescheduled. Anders is er geen winst te behalen iddSoultaker schreef op 31 januari 2004 @ 03:12:
Het maakt al een wereld van verschil of je dit op een systeem met een enkele processor probeert (dan kun je een klein aantal threads wel in dezelfde timeslice starten) of op een multiprocessor systeem.
Volgens mij is dit vrijwel onmogelijk als je het programma op een single processor systeem uitvoert, zoals Soultaker al aangaf. Daarnaast heb je er weinig aan om twee threads dezelfde prioriteit geven aangezien dit op elk systeem een ander effect zal hebben.
De enige is HyperThreading of multiproc systemen
De enige is HyperThreading of multiproc systemen
The trade of the tools
[ me | specs ] Klipsch Promedia Ultra 5.1 + Sennheiser HD-590
De threads draaien allemaal op een aparte pc, ze hebben dus allemaal een eigen JVM ter beschikking en een eigen proc. Misschien maakt het inderdaad niet zo heel veel uit, maar kan dat op dit moment niet testen. Dat locken is inderdaad misschien wel een idee, ga dat zo snel mogelijk uitproberen.
[ Voor 14% gewijzigd door jopie1983 op 31-01-2004 12:28 ]
Het kan aan mij liggen, maar ik begrijp het niet helemaal meer. Je wilt vanaf verschillende pc's threads in een keer starten? Maar als het op verschillende pc's zit, dan heb je toch niks aan locking, maar zul je toch meer aan interprocess communication moeten gaan denken?
putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]
Hoe communiceeren je applicaties in je JVM met elkaar? Is het een ring of kent elk proces elk ander proces (vermaasd)?
Hoe dan ook, het lijkt me dat je één proces leider moet zien te maken (daar zijn electionalgoritmes voor, welke [in theorie] waitfree zijn, maar werken met message passing), welke dan een message stuurt naar alle applicaties dat ze de thread moeten launchen.
[edit] Als je een ring hebt, kun je Petersons Algortime gebruiken. Als je daar meer informatie over nodig hebt, moet je het maar even aangeven Daar kan Infinitive ook nog wel wat over vertellen
Hoe dan ook, het lijkt me dat je één proces leider moet zien te maken (daar zijn electionalgoritmes voor, welke [in theorie] waitfree zijn, maar werken met message passing), welke dan een message stuurt naar alle applicaties dat ze de thread moeten launchen.
[edit] Als je een ring hebt, kun je Petersons Algortime gebruiken. Als je daar meer informatie over nodig hebt, moet je het maar even aangeven Daar kan Infinitive ook nog wel wat over vertellen
[ Voor 23% gewijzigd door Glimi op 31-01-2004 15:29 ]
Verwijderd
Het perfect gelijktijdig starten over een netwerk is volgens mij niet mogelijk: je kan onmogelijk garanderen dat elk netwerk-pakketje op hetzelfde moment aankomt, en dat elk proces er even snel op reageert. Maar met locking/mutual exclusion kan je het wel proberen te benaderen.
Eenmaal je locking/mutual eclusion hebt, kan je elke client laten wachten op een denkbeeldige (soort coordinator zeg maar) client, die op dat moment in de kritieke sectie zit. Als alle clients ingelogd zijn, geeft de coordinator 'tegelijk' aan elke gekende client opdracht (bijv. door multicast, hierdoor benader je al vrij sterk je eis: tegelijk starten) om te starten.
Ahv. logische klokken en/of vector klokken kan je makkelijk mutual exclusion/locking afdwingen in een netwerk van computers (distributed networks). Hiervoor bestaan verschillende algoritmes, met elk hun eigen complexiteit. Zelf stel ik voor:
- een denkbeeldige ringstructuur, waarbij een token (= de toegang tot de mutual exclusion) volgens de ring doorgegeven & vastgehouden wordt
- het algoritme van Ricart & Agrawala
Je moet maar eens in google zoeken op 'logical clocks', 'vector clocks', 'Ricart Agrawala', 'mutual exclusion in a distributed system', ...
PS: in principe heb je geen locking nodig, je kan evengoed elke client op het commando van de coordinator laten wachten, maar ik heb het vage vermoeden dat je toch locking zal nodig hebben in de rest van je 'project'. Indien niet, lijkt het mij overkill!
EDIT: oops Gimli was me eigenlijk voor
Voor het kiezen van de coordinator (Gimli nonemt het de leider) kan je inderdaad een election algoritme toepassen.
Hmm, zet me aan het denken, als je toch een coordinator moet uitkiezen, en ooit mutual exclusion nodig hebt, kan je beter een makkelijker algoritme gebruiken voor het coordineren van de kritieke secties: de coordinator kan de token (= toegang tot sectie) aan 1 client geven, die op zijn beurt na een bepaalde tijd (eventueel afgedwongen door een timeout) de token teruggeef aan de coordinator. De coordinator regelt dus de kritieke secties en de clients vragen de kritieke sectie aan aan de coordinator.
Eenmaal je locking/mutual eclusion hebt, kan je elke client laten wachten op een denkbeeldige (soort coordinator zeg maar) client, die op dat moment in de kritieke sectie zit. Als alle clients ingelogd zijn, geeft de coordinator 'tegelijk' aan elke gekende client opdracht (bijv. door multicast, hierdoor benader je al vrij sterk je eis: tegelijk starten) om te starten.
Ahv. logische klokken en/of vector klokken kan je makkelijk mutual exclusion/locking afdwingen in een netwerk van computers (distributed networks). Hiervoor bestaan verschillende algoritmes, met elk hun eigen complexiteit. Zelf stel ik voor:
- een denkbeeldige ringstructuur, waarbij een token (= de toegang tot de mutual exclusion) volgens de ring doorgegeven & vastgehouden wordt
- het algoritme van Ricart & Agrawala
Je moet maar eens in google zoeken op 'logical clocks', 'vector clocks', 'Ricart Agrawala', 'mutual exclusion in a distributed system', ...
PS: in principe heb je geen locking nodig, je kan evengoed elke client op het commando van de coordinator laten wachten, maar ik heb het vage vermoeden dat je toch locking zal nodig hebben in de rest van je 'project'. Indien niet, lijkt het mij overkill!
EDIT: oops Gimli was me eigenlijk voor
Hmm, zet me aan het denken, als je toch een coordinator moet uitkiezen, en ooit mutual exclusion nodig hebt, kan je beter een makkelijker algoritme gebruiken voor het coordineren van de kritieke secties: de coordinator kan de token (= toegang tot sectie) aan 1 client geven, die op zijn beurt na een bepaalde tijd (eventueel afgedwongen door een timeout) de token teruggeef aan de coordinator. De coordinator regelt dus de kritieke secties en de clients vragen de kritieke sectie aan aan de coordinator.
[ Voor 21% gewijzigd door Verwijderd op 31-01-2004 20:02 ]
Uhm het was wellicht handig geweest als je dat meteen had gezegd, is redelijk relevantjopie1983 schreef op 31 januari 2004 @ 12:27:
De threads draaien allemaal op een aparte pc,
Je kunt hoogstens systeemtijden synchronizeren dan en een timed start geven.
Maar waarom in godesnaam al die moeite doen om een seconde delay te voorkomen?
Waarom al die moeite doen? Is een hele goed vraag besef ik nu. Ik wist niet dat het idd zoveel moeite zou kosten. Waarvoor ik het nodig heb, wij zijn bezig met een robotsoccer project, en het leek mij logisch dat al de robots op hetzelfde moment beginnen voetballen. Maar als het zoveel moeite kost, lijkt het mij idd een beetje overkill. Het gaat hier immers maar om een paar milliseconden. Verder werk ik met RMI, en weet niet of je daarmee over een netwerk kunt broadcasten. Het zou dus een totaal ander opzet van het systeem worden, en daar ben ik niet echt voor te vinden. In ieder geval bedankt voor de moeite
Nu ff een niet doordachte reactie:
Is jini niet iets voor zon project?
Is jini niet iets voor zon project?
Choose for Choice! Choose Linux! | src van icon
Jini biedt natuurlijk een hoop meer mogelijkheden dan RMI, maar voor ons iets te veel. RMI heeft een veel hogere abstractie dan Jini, je weet veel minder dat je met remote objects bezig bent. Op die manier kunnen we meer tijd besteden aan andere dingen, omdat we ons minder hoeven bezig te houden met de netwerkkant. En het is natuurlijk veel leuker om je met het aansturen van de robots, beeldherkenning en het voetbalalgoritme
bezig te houden.
Maar als al je robot-threads gewoon afzonderlijk draaien en werken, dan hoeven ze toch niet qua timing op elkaar zijn afgestemd? Stel dat er een botje uitvalt, dan moet de rest toch gewoon verder kunnen gaan, ook al ontvangen ze geen data meer (op tijd) van een andere robot?
Als een robot data krijgt van de rest, is dat alleen maar goed, maar wanneer er iets niet komt, of niet op tijd, dan moet het botje toch nog wel verder werken?
Als een robot data krijgt van de rest, is dat alleen maar goed, maar wanneer er iets niet komt, of niet op tijd, dan moet het botje toch nog wel verder werken?
Remember, if you have any trouble you can always send a telegram to the Right People.
Het gaat om het STARTEN van de threads. Dat je dus niet krijgt dat bv een spits een minuut of 10 eerder kan gaan lopen dan de keeper van de tegenpartij (slightly overdrevenraoulduke schreef op 03 februari 2004 @ 18:11:
Maar als al je robot-threads gewoon afzonderlijk draaien en werken, dan hoeven ze toch niet qua timing op elkaar zijn afgestemd? Stel dat er een botje uitvalt, dan moet de rest toch gewoon verder kunnen gaan, ook al ontvangen ze geen data meer (op tijd) van een andere robot?
Als een robot data krijgt van de rest, is dat alleen maar goed, maar wanneer er iets niet komt, of niet op tijd, dan moet het botje toch nog wel verder werken?
More than meets the eye
There is no I in TEAM... but there is ME
system specs
Daarvoor zou je één thread kunnen kiezen als teamleider of als scheidsrechter.
Ik weet niet hoe realistisch het wedstrijdje moet worden, maar ik zou me zo kunnen indenken dat je een botje zo autonoom mogelijk wilt maken en dat zo'n botje in principe zou moeten kunnen spelen met alleen data van de scheidsrechter en de posities van bal en spelers...
Ik weet niet hoe realistisch het wedstrijdje moet worden, maar ik zou me zo kunnen indenken dat je een botje zo autonoom mogelijk wilt maken en dat zo'n botje in principe zou moeten kunnen spelen met alleen data van de scheidsrechter en de posities van bal en spelers...
[ Voor 4% gewijzigd door Infinitive op 03-02-2004 18:35 ]
putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]
Misschien helpt het om te zeggen dat we met echte robots werken.
We wouden dus iedere robot precies gelijke kansen geven door ze op precies hetzelfde moment te starten. Voor de rest zijn die dingen volledig autonoom. Die thread waar ze in draaien heeft zelf ook nog een beeld- en sensorverwerkingsthread draaien waardoor ze hun camera- en sensorwaardes kunnen analyseren. De enige interventie die we doen is om de robots van een overtreding of een goal te verwittigen. Dit doen we via het centrale programma vanwaar alle threads gestart worden.
Naast de echte robots zijn we ook nog een simulatie aan het bouwen, dit om het testen van het algoritme te vergemakkelijken en omdat we nog een datamining dingetje erbij moeten doen. Deze hele zooi moet binnen 5 weken draaien, dus je kan je wel voorstellen dat we nogal wat dingen redelijk 'vlug' in mekaar moeten rammen en een uitgebreide netwerkinterface of het gelijktijdig starten van threads te veel tijd in beslag zou nemen.
Naast de echte robots zijn we ook nog een simulatie aan het bouwen, dit om het testen van het algoritme te vergemakkelijken en omdat we nog een datamining dingetje erbij moeten doen. Deze hele zooi moet binnen 5 weken draaien, dus je kan je wel voorstellen dat we nogal wat dingen redelijk 'vlug' in mekaar moeten rammen en een uitgebreide netwerkinterface of het gelijktijdig starten van threads te veel tijd in beslag zou nemen.
Een beetje een knullige oplossing is misschien om je threads aan te maken met een startdatum die een paar seconden in de toekomst ligt zodat je voldoende tijd hebt om alle threads te starten. De afzonderlijke threads doen een sleep() totdat het uur U is aangebroken en starten allemaal tegelijkerijd. Dit vereist natuurlijk wel dat de systeemklokken perfect gesynchroniseerd zijn.
With the light in our eyes, it's hard to see.
Als je toch RMI gebruikt, gebruik dan een centraal object waar alle robots aan kunnen vragen of iedereen al gestart is. Bijv:
Natuurlijk moet alles wel Remote enz zijn maar aangezien je toch al RMI gebruikt vertrouw ik er op dat dat lukt? Ik weet verder niks over multicast in RMI dus lijkt mij dit de makkelijkste oplossing.
Zorg dan dat iedere thread nadat ie gestart is Game.waitForGame() aanroept. Aanroepen via RMI worden op de server gedaan als aparte threads dus als een thread nog niet de laatste is blijft deze geblokkeerd. Zodra de laatste robot waitForGame() aanroept worden alle threads geunlocked en weten de aparte threads (mogelijk op andere host) dat het spel begonnen is.
Natuurlijk is er altijd wel een klein verschil in tijd maar dat hou je toch als je het makkelijk wilt houden ben ik bang.
Succes
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| class Game {
static final int MAX_ROBOTS = 2;
int numRobots = 0;
synchronized void waitForGame() {
numRobots++;
if (numRobots == MAX_ROBOTS)
this.notifyAll();
else
this.wait();
}
} |
Natuurlijk moet alles wel Remote enz zijn maar aangezien je toch al RMI gebruikt vertrouw ik er op dat dat lukt? Ik weet verder niks over multicast in RMI dus lijkt mij dit de makkelijkste oplossing.
Zorg dan dat iedere thread nadat ie gestart is Game.waitForGame() aanroept. Aanroepen via RMI worden op de server gedaan als aparte threads dus als een thread nog niet de laatste is blijft deze geblokkeerd. Zodra de laatste robot waitForGame() aanroept worden alle threads geunlocked en weten de aparte threads (mogelijk op andere host) dat het spel begonnen is.
Natuurlijk is er altijd wel een klein verschil in tijd maar dat hou je toch als je het makkelijk wilt houden ben ik bang.
Succes
Je beschrijft hier gewoon een semafoor. Als je dan een semafoor gebruikt, gebruik dan liever de library van Doug Lea omdat deze in 1.5 staandaard in de JDK zal komen te zitten
Hoe zie je dit voor je met een semafoor dan? Naar mijn idee doet die juist het omgekeerde: maximaal X processen tegelijk toestaan te executeren (de rest wacht), in plaats van te blokkeren tot alle X processen tegelijk wachten, zoals hier de bedoeling was.Glimi schreef op 04 februari 2004 @ 21:53:
Je beschrijft hier gewoon een semafoor. Als je dan een semafoor gebruikt, gebruik dan liever de library van Doug Lea omdat deze in 1.5 staandaard in de JDK zal komen te zitten
Oh, dat kan ook. Het resultaat is het zelfde. De implementatie wordt er wel iets anders op (niet makkelijker volgens mij) én synchronized methodes werken alleen altijd in Java zonder extra libraries. Dik kans dat die Semaphores ook gewoon geimplementeerd zijn met synchronized methodes.Glimi schreef op 04 februari 2004 @ 21:53:
[...]
Je beschrijft hier gewoon een semafoor. Als je dan een semafoor gebruikt, gebruik dan liever de library van Doug Lea omdat deze in 1.5 staandaard in de JDK zal komen te zitten
Ik wist niet dat dit standaard werd. Ik zie de meerwaarde er trouwens (in dit geval dan) ook niet zo van in. Nou ja..
[ Voor 6% gewijzigd door Tmr op 04-02-2004 22:17 ]
Soultaker schreef op 04 februari 2004 @ 22:12:
Hoe zie je dit voor je met een semafoor dan? Naar mijn idee doet die juist het omgekeerde: maximaal X processen tegelijk toestaan te executeren (de rest wacht), in plaats van te blokkeren tot alle X processen tegelijk wachten, zoals hier de bedoeling was.
Het nut van die code snap ik dan gelijk ook niet helemaal meer
Ik hou ermee op voor vandaag, ik heb
[ Voor 6% gewijzigd door Glimi op 04-02-2004 22:27 ]
Nou het idee erachter is eingelijk heel simpel:Glimi schreef op 04 februari 2004 @ 22:16:
Je hebt 100% gelijk. Weer niet goed gelezen
Het nut van die code snap ik dan gelijk ook niet helemaal meer
- all processen registreren zich (waitForGame()) welke blokkeert totdat de laatste thread zich aanmeldt.
- als de laatste thread zich aanmeldt dan wordt een notifyAll() gestuurd -> alle threads unblocken (op min of meer het zelfde moment).
That's all
Pagina: 1