Ik ben een kleine applicatie aan het bouwen die bepaalde dingen simuleerd. Die app wil ik ook draaien op iets snellere machines met meer dan 1 cpu. Nu heb ik een tijdje geleden met MPI gewerkt op een redelijke cluster, wat erg fijn werkte. Daarbij moest ik op arrays en matrices werken, dat deed je dan door dezelfde code te hebben voor elke node, maar dat elke node een andere range van de array bewerkte.
Nu moet ik in deze app ook met arrays werken, waarbij elke thread dus fijn zijn gedeelte van de array neemt. Na een tijdje denken, heb ik besloten om een soort alternatieve versie van Thread en Runnable te maken, de MultiThread en MultiRunnable. Daarbij heb ik dan alvast een AbstractMultiRunnable gemaakt, die heel wat handige dingen implementeerd. Waaronder een soort van sync functie. In MPI werkte bijna alle functies als een soort sync functie, ben even de naam kwijt. Daarmee bedoel ik dat alle threads/processes pas doorgaan als ze allemaal daar zijn gekomen.
Ik heb nu een implementatie, maar volgens mij gaat ie niet werken.
Ik heb dus een array met booleans, als processes 'out of sync' zijn, dan is zijn boolean false. Als ze gaan syncen, dan zetten ze hun boolean op true. Ze mogen de methode syncAllThreads() dus pas verlaten als iedereen op true staat. Als dat niet het het geval is gaan ze wachten, totdat ze door een andere thread weer wakker worden gemaakt, omdat hij op zijn punt is gekomen.
Opzich lijkt het goed te gaan, maar nu het probleem. Als ze allemaal daar zijn beland, dan moet de boolean weer op false worden gezet. Als er 1 al aan het verlaten is, terwijl een ander nog aan het testen is, dan verlaat de ene, maar blijft de ander hangen.
Ik besef me nu dat ik ook een syncronized int veld kon gebruiken en die ophogen met 1 als een thread klaar is en controleren of hij even groot is als size (het aantal threads). Maar dan houd ik hetzelfde probleem met dat veld resetten.
Ik kan natuurlijk een sleep van een aantal milliseconden aan het einde van de sync zetten, zodat ik (bijna) zeker weet dat niemand meer aan het testen is de booleans terug gezet worden.
Ik heb nu ineens een andere ideetje...
Maar misschien hebben jullie ook nog iets briljants...
Nu moet ik in deze app ook met arrays werken, waarbij elke thread dus fijn zijn gedeelte van de array neemt. Na een tijdje denken, heb ik besloten om een soort alternatieve versie van Thread en Runnable te maken, de MultiThread en MultiRunnable. Daarbij heb ik dan alvast een AbstractMultiRunnable gemaakt, die heel wat handige dingen implementeerd. Waaronder een soort van sync functie. In MPI werkte bijna alle functies als een soort sync functie, ben even de naam kwijt. Daarmee bedoel ik dat alle threads/processes pas doorgaan als ze allemaal daar zijn gekomen.
Ik heb nu een implementatie, maar volgens mij gaat ie niet werken.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| public abstract class AbstractMultiRunnable implements MultiRunnable{ private int id; private boolean[] ready; private int size; public AbstractMultiRunnable(){ Arrays.fill(ready, false); } public void syncAllThreads(int id){ ready[id] = true; notifyAll(); while(!othersAreReady()){ try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } ready[id] = false; } public boolean othersAreReady(){ for(int i = 0; i < ready.length; i++) if(!ready[i])//one other is not ready return false; return true; } } |
Ik heb dus een array met booleans, als processes 'out of sync' zijn, dan is zijn boolean false. Als ze gaan syncen, dan zetten ze hun boolean op true. Ze mogen de methode syncAllThreads() dus pas verlaten als iedereen op true staat. Als dat niet het het geval is gaan ze wachten, totdat ze door een andere thread weer wakker worden gemaakt, omdat hij op zijn punt is gekomen.
Opzich lijkt het goed te gaan, maar nu het probleem. Als ze allemaal daar zijn beland, dan moet de boolean weer op false worden gezet. Als er 1 al aan het verlaten is, terwijl een ander nog aan het testen is, dan verlaat de ene, maar blijft de ander hangen.
Ik besef me nu dat ik ook een syncronized int veld kon gebruiken en die ophogen met 1 als een thread klaar is en controleren of hij even groot is als size (het aantal threads). Maar dan houd ik hetzelfde probleem met dat veld resetten.
Ik kan natuurlijk een sleep van een aantal milliseconden aan het einde van de sync zetten, zodat ik (bijna) zeker weet dat niemand meer aan het testen is de booleans terug gezet worden.
Ik heb nu ineens een andere ideetje...
Maar misschien hebben jullie ook nog iets briljants...
"Beauty is the ultimate defence against complexity." David Gelernter