c++ 11 sync(dynamische erzeugung, sync)
-
Du solltest std::thread btw nie
raw benutzen btw, sondern immer eine Klasse drum bauen die im Destruktor entweder joined oder detached.
-
wrock schrieb:
Arcoth schrieb:
std::vectorstd::thread threadVector;
for (int i = 0; i < mNumberofPlayers; i++)
threadVector.emplace_back(std::thread(Start, i));Nein, das war schon richtig von Arcoth, das std::thread davor ist unnötig.
-
cooky451 schrieb:
Du solltest std::thread btw nie
raw benutzen btw, sondern immer eine Klasse drum bauen die im Destruktor entweder joined oder detached.Auf keinen Fall! Das führt beides zu Problemen:
{ int local_variable; // gedacht um Resultat von t zu halten cookies_detaching_thread t([&local_variable]{...}); throw exception(); t.join(); // wird nie return local_variable; // ausgeführt } // t1.detach() // -> t1 schreibt den Stack kaputt{ int local_variable; // gedacht um Resultat von t zu halten cookies_joining_thread t([&local_variable]{...}); throw exception(); t.join(); // wird nie return local_variable; // ausgeführt } // t.join() // -> Es wird auf t gewartet, aber es macht keinen Sinn t weiter auszuführen
-
Am besten benutzt du auch keine Schleifen, das kann zu Problemen führen:
for (std::uint16_t i = 0; i < 123456; ++i) ; // Kommt nie aus der Schleife rausAh ne moment vielleicht liegt das Problem hier nicht bei der Schleife. Am besten du benutzt einfach keine ints, die sind gefährlich.
-
Ich glaube wir sollten auf beiden Seiten von voreiligen Generalisierungen abweichen.
Irgendwo hat cooky Recht, aber antiraii (doofer Name oO) hat natürlich auch schöne Beispiele angegeben, die crashen. Daher, es kommt auf den Anwendungsfall an.
-
dazu gleich mal ne Frage, beim joinale/detached thread wie muss cih da den construktor aufbauen damit er alle argumente weiterleitet? also das nichts velroren geht?
class joining_thread{ public: joining_thread(){} ~joining_thread(){ mThread.join(); } private: std::thread mThread; };
-
So in der Art:
template <typename Function, typename... Args> explicit scoped_thread(Function&& f, Args&&... args) : thr_(std::forward<Function>(f), std::forward<Args>(args)...) {}
-
cooky451 schrieb:
So in der Art:
template <typename Function, typename... Args> explicit scoped_thread(Function&& f, Args&&... args) : thr_(std::forward<Function>(f), std::forward<Args>(args)...) {}Dank dir !
noch eine Frage
joining_thread t1(&Mikado::Start,this,0); joining_thread t2(&Mikado::Start,this,1); joining_thread t3(&Mikado::Start,this,2); std::vector<joining_thread> myVec1; myVec1.emplace_back(&Mikado::Start,this,0); myVec1.emplace_back(&Mikado::Start,this,1); myVec1.emplace_back(&Mikado::Start,this,2);Die beiden Varianten müssten sich doch gleich verhalten oder?
Angelegt werden sie beide gleich, und bei empalce werden sie nur in den Vektor verschoben.
Nichtsdestotrotz funktioniertrt die Erste Variante mit meinm Program einwandfrei, und die Zweite nicht....kann mir eig nur einen Fehler mit der this reference vorstellen...
-
Die beiden Varianten müssten sich doch gleich verhalten oder?
Kommt auf
joining_threadan, weil die Elemente desvectors intern wahrscheinlich noch gemoved werden.
-
naja eigentlich nichts aufregende mehr
die copy konstruktoren sind leer implementiert
und die move semantik so:
//move semantik joining_thread(joining_thread&& other ):mThread(std::move(other.mThread)){} joining_thread& operator=(joining_thread&& other){ mThread=std::move(other.mThread); return *this; }demanch sollte es ja richtig verschoben werden oder?
Das Program kompiliert richtig weiter, sieht allerdings so aus als habe ehr bei den Mutex/Threads aufwecken dann ein problem...
-
Präzise Fehlerbeschreibungen sind das A und O beim Fragen stellen.
-
func1(){//incr counter if ((mPlayerCounter + 1) == mNumberofPlayers) { mPlayerCounter = 0; } else { mPlayerCounter++; } //wake up all threads std::unique_lock<std::mutex> lck(mCritMutex); mCondVar.notify_all(); } func2(int PlayerID){ while(true){ if(mPlayerCounter==PlayerID){ //do things func1(); } //going to sleep, wakes up when change in PlayerCounter //lambda functions is used for std::unique_lock<std::mutex> lck(mCritMutex); mCondVar.wait(lck,[&]{return mPlayerCounter==PlayerID;}); } }std::vector<joining_thread> myVec1; /*joining_thread t1(&MyClass::func2,this,0); joining_thread t2(&MyClass::func2,this,1); joining_thread t3(&MyClass::func2,this,2); */ myVec1.emplace_back(&MyClass::func2,this,0); myVec1.emplace_back(&MyClass::func2,this,1); myVec1.emplace_back(&MyClass::func2,this,2);erste Variante(ausgeklammert) funktioniert>:
thread 0 wird ausgeführt
thread 1 wird ausgeführt
thread 2 wird ausgeführt
thread 0 wird ausgeführt
.
.
.variante 2:
thread 0 wird ausgeführt
thread 1 wird ausgeführt
-->endejoining_thread
class joining_thread{ public: template <typename Function, typename... Args> explicit joining_thread(Function&& f, Args&&... args) : mThread(std::forward<Function>(f), std::forward<Args>(args)...) {} ~joining_thread(){ mThread.join(); } //copy semantik joining_thread(joining_thread& other ){} joining_thread& operator=(const joining_thread& other ){return *this;} //move semantik joining_thread(joining_thread&& other ):mThread(std::move(other.mThread)){} joining_thread& operator=(joining_thread&& other){ mThread=std::move(other.mThread); return *this; } private: std::thread mThread; };