c++ 11 sync(dynamische erzeugung, sync)



  • 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 raus
    

    Ah 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...


  • Mod

    Die beiden Varianten müssten sich doch gleich verhalten oder?

    Kommt auf joining_thread an, weil die Elemente des vector s 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...


  • Mod

    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
    -->ende

    joining_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;
    };
    

Anmelden zum Antworten