K
Callback schrieb:
std::thread t1(car.control( calculate_Torques));
std::thread t2(car.control( calculate_JointVelocities));
da kommt leider immer nur invalid use of void expression
(1) Pass auf, dass Du keine Datenrennen bekommst, bei sowas. Der C++ Compiler verhindert das nicht. Du musst wissen, was Du tust. Was macht denn car-control? Will die Methode das car-Objekt verändern? Da es nichte zurück gibt, muss es ja irgendwas verändern, sonst wäre der Aufruf nutzlos. Das würde dann sehr wahrscheinlich ein Datenrennen erzeugen. Wenn Du nicht weißt, was das ist, würde ich davon die Finger lassen. Wenn Du multi-threaded Programmierung verkackst, dann verhält sich das Programm sehr komisch und es ist verhältnismäßig schwierig rauszufinden, was genau du falsch gemacht hast.
(2) Das Starten eines neues Threads kostet etwas Overhead. Falls Deine car-control Funktion relativ kurzlebig ist, wird sich das nicht lohnen. Eine Alternative sind dann noch Thread-Pools, in denen untätige Threads geparkt werden, die dann schneller auf etwas reagieren können.
(3) Du versuchst hier Thread-Objekte zu erzeugen, indem du das Ergebnis von car.control(calculate_Torques) und car.control( calculate_JointVelocities) als Parameter für den Konstruktor verwendest. Du rufst deine Funktionen schon quasi auf innerhalb deines Haupt-Threads. Und die control-Funktion gibt anscheinend "void" zurück, was Du aber nicht als Parameter verwenden kannst. Deswegen die Fehlermeldung "invalid use of void expression". Dem thread -Konstruktor gibt man Funktion und Parameter einzeln über:
void do_something_that_takes_a_while(int param1, double param2);
int main() {
std::thread t(do_something_that_takes_a_while, 42, 3.14159265);
// nicht t(do_something_that_takes_a_while(42, 3.14159265));
t.join();
}
In deinem Fall scheint aber die control -Methode überladen oder ein Template zu sein, da Du zwei verschiedene Funktionsobjekte übergeben willst, die jeweils etwas anderes zurückgeben:
void do_something_that_takes_a_while(int param1, double param2);
void do_something_that_takes_a_while(int param1, std::string param2);
int main() {
std::thread t(do_something_that_takes_a_while, 42, 3.14159265);
t.join();
}
Das wird so aber nicht funktionieren, weil es mehrdeutig ist. Es ist nicht klar, welches der do_something_that_takes_a_while -Funktionen du als ersten Parameter für den thread -Konstruktor übergeben willst. Deswegen würde ich generell einen Lambda-Ausdruck empfehlen:
int main() {
int p1 = 42;
std::string p2 = "pi";
std::thread t([p1, p2=std::move(p2)]{do_something_that_takes_a_while(p1,std::move(p2));});
t.join();
}
Und falls Du die "generalized lambda captures", die es seit C++14 gibt, noch nicht benutzen kannst, kannst Du so ein "Move capture" auch umgehen, indem man das per Lambda-Funktions-Parameter entgegen nimmt:
int main() {
int p1 = 42;
std::string p2 = "pi";
std::thread t( [p1](std::string p2){
do_something_that_takes_a_while(p1,std::move(p2));
}, std::move(p2) );
t.join();
}