Zuerst werden Sie fast sofortige Stapelüberläufe mit diesem Code erhalten.
Ihre grundlegende Codepfad sieht wie folgt aus, in Pseudo-Code:
func() {
path = RAND(1, 3);
if(path == 1) /*DO STUFF*/ func();
else if(path == 2) /*DO STUFF*/ func();
else /*DO STUFF*/ func();
}
Also unabhängig davon, ob diese Schritte „gleichzeitig“ oder nicht, Ihren Code nie sowieso beendet. Wenn Sie möchten, dass der Code schließlich beendet wird, sollten Sie die Zufallszahl in einem Bereich haben, in dem nicht nur die Zahlen [1, 3]
ausgegeben werden.
int RandomNumber= qrand() %4; //Will stop when RandomNumber == 0
Wenn es eine explizitere Bedingung für, wenn die Rekursion stoppen soll (wie wenn energy == 0
), müssen Sie das in anstatt codieren.
Ihr zweites Problem ist, dass es nicht klar ist, was Sie meinen, indem Sie alle diese Schritte "gleichzeitig" ausführen. Erwarten Sie, dass alle Pfade parallel in mehreren Threads ausgeführt werden?
Sie werden so etwas schreiben müssen:
std::thread t1([=]{
LightParticle* i=new LightParticle(energy, position);
int speed = 3;
i->SimulatePath(time, speed, i->GetPosition());
i->GetPosition().Print();
energy--;
if(condition_to_continue_recursing()) {
Simulate(energy, i->GetPosition());
}
});
std::thread t2([=]{
MediumParticle* j=new MediumParticle(energy, position);
MediumParticle* k=new MediumParticle(energy, position);
int speed = 2;
j->SimulatePath(time,speed, position);
k->SimulatePath(time,speed, position);
j->GetPosition().Print();
k->GetPosition().Print();
if(condition_to_continue_recursing()) {
Simulate(energy, j->GetPosition());
Simulate(energy, k->GetPosition());
}
});
std::thread t3([=]{
HeavyParticle* l = new HeavyParticle(energy, position);
HeavyParticle* m = new HeavyParticle(energy, position);
HeavyParticle* n = new HeavyParticle(energy, position);
int speed = 1;
l->SimulatePath(time,speed, position);
l->GetPosition().Print();
m->SimulatePath(time,speed, position);
m->GetPosition().Print();
n->SimulatePath(time,speed, position);
n->GetPosition().Print();
if(condition_to_continue_recursing()) {
Simulate(energy, l->GetPosition());
Simulate(energy, m->GetPosition());
Simulate(energy, n->GetPosition());
}
});
t1.join();
t2.join();
t3.join();
Aber was auch immer condition_to_continue_recursing()
ist, wird von Ihnen entschieden werden müssen; Ich weiß nicht genug über Ihre allgemeine Aufgabe, dies zu beantworten. Auch das wird eine absurde Anzahl von Threads hervorbringen, wenn Ihr condition_to_continue_recursing
ziemlich wichtig ist; Die Verwendung eines Thread-Pools könnte bevorzugt werden. Und all das hängt davon ab, dass Sie entscheiden, dass die Verwendung von Threads für diese Art von Aufgabe ideal ist, was für mich nicht offensichtlich ist.
Ihr drittes Problem ist, dass dieses Code-Snippet mit ziemlich signifikanten Entwurfsfehlern übersät ist.
HeavyParticle* l = new HeavyParticle(energy, position);
HeavyParticle* m = new HeavyParticle(energy, position);
HeavyParticle* n = new HeavyParticle(energy, position);
Jeder dieser Zeiger wird undicht. Da die Objekte nur im Rahmen verwendet werden, in der sie definiert habe, die Verwendung von std::unique_ptr
ist wahrscheinlich ideal:
std::unique_ptr<HeavyParticle> l = std::make_unique<HeavyParticle>(energy, position);
std::unique_ptr<HeavyParticle> m = std::make_unique<HeavyParticle>(energy, position);
std::unique_ptr<HeavyParticle> n = std::make_unique<HeavyParticle>(energy, position);
EDIT: Alternativ gibt es keinen wirklichen Grund ist, warum sollten Sie Zeiger in diese verwenden Kontext in erster Linie. Der folgende Code würde perfekt funktionieren ohne Speicherlecks in Ordnung oder auf die Funktionalität des Codes ändern:
HeavyParticle l(energy, position);
HeavyParticle m(energy, position);
HeavyParticle n(energy, position);
int speed = 1;
l.SimulatePath(time,speed, position);
l.GetPosition().Print();
m.SimulatePath(time,speed, position);
m.GetPosition().Print();
n.SimulatePath(time,speed, position);
n.GetPosition().Print();
Simulate(energy, l.GetPosition());
Simulate(energy, m.GetPosition());
Simulate(energy, n.GetPosition());
Sie sollten auch wahrscheinlich nicht qrand
verwendet werden.
std::default_random_engine engine(std::random_device()());
void Reaction::Simulate(double energy, TwoVector position)
{
std::uniform_int_distribution<int> distribution(0, 3);
int RandomNumber = distribution(engine);
/*... Whatever*/
Ein besseres Design würde den Motor in die Funktion übergeben.
Alternative:
std::default_random_engine engine(std::random_device()());
void Reaction::Simulate(double energy, TwoVector position)
{
if(energy <= 0) return;
std::uniform_int_distribution<int> distribution(1, 3);
int RandomNumber = distribution(engine);
/*... Whatever*/
Es gibt eine Menge mehr dazu, aber es gibt eine Menge zu graben in. Hoffentlich wird dies einen guten Ausgangspunkt geben.
Für zukünftige Fragen stellen Sie bitte sicher, dass Ihr Code richtig formatiert ist. Unsachgemäß formatierter Code ist extrem schwierig zu analysieren und daher extrem schwer zu debuggen. – Xirema
wow das sieht so viel besser aus, danke –
Vielleicht wäre es besser, alle Partikel in einer Struktur darzustellen, wie zum Beispiel 'std :: vector', dann führe' Simulate' auf allen dann für eine einzelne Iteration aus und wiederhole es so oft wie Sie es für notwendig halten. Vermeiden Sie "neu". Mit einem Vektor verwenden Sie einfach 'push_back', um jedes neue Partikel hinzuzufügen. – wally