C++11 thread: Threadsteuerung mit <atomic> (mingw gcc 4.8.1)



  • Hallo!

    Ich möchte gerne einen thread über ein <atomic> von "außen" steuern (ich habe das zuerst mit "volatile" probiert, das hat nicht funktioniert und ist, wie ich gelesen habe, in C++11 auch dafür nicht vorgesehen.) Mit <atomic> sollte es funktionieren, jedoch reagiert der Thread im beigefügten Testcode auch nicht mit einem <atomic> (es handelt sich dabei um ein leicht geändertes Beispielprogramm zur Thread-Thematik. Den Copy-Constructor habe ich hinzugefügt, da er vom Compiler erwartet wird).

    Was mache ich falsch? Eigentlich sollte die Schleife "von außen" beendet werden, aber offenbar zieht die Compileroptimierung, so dass die Schleife weiterhin auf "while (true)" bleibt.

    Kann mir jemand einen Tipp geben?

    Vielen Dank!!

    #include <thread>
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <atomic>
    
    using namespace std;
    
    namespace mytest  {
    
    struct AtomicCounter {
    	std::atomic<int> value;
    	AtomicCounter() : value(0) {}
    	AtomicCounter(const AtomicCounter &acin) {this->value.store(acin.value.load() );}
    	AtomicCounter(const int &i) {this->value.store(i);}
    
    	void increment(){
    		++value;
    	}
    
    	void decrement(){
    		--value;
    	}
    
    	int get(){
    		cout << "AtomicCounter Get: " << value.load() << endl;
    		return value.load();
    	}
    	void set (int v) {
    		cout << "AtomicCounter Set: " << v << endl;
    		value.store(v);
    	}
    };
    
    class threadTest  {
    public:
      AtomicCounter ac;
      threadTest() : ac(0) { };
      threadTest(int init ) : ac(init) { };
      void show_ac()  {cout << "show_AC: " << ac.get() << endl; }
    
      void infinite_atomicrun()  {
    	  while (ac.get()==0)  {
    		  std::chrono::milliseconds dura(100);
    		  cout << ", ." << ac.get() ;
    		  cout << "in inf: "; show_ac();
    		  std::this_thread::sleep_for( dura );
    	  }
      }
    };
    
    int test()   {
    	  threadTest tt(0);
    	  std::thread thrd(&threadTest::infinite_atomicrun, tt);
    	  std::chrono::milliseconds dura( 500 );
    	  std::this_thread::sleep_for( dura );
    	  cout << "**************************** Sending STOPP" << (char)7 << endl;
    	  tt.ac.set(7);
    	  std::this_thread::sleep_for( dura );
    	  tt.show_ac();
          thrd.join();
          return 0;
    }
    
    }
    
    int main (int args, char **argv) {
    	mytest::test();
    	return 0;
    }
    

  • Mod

    bertl schrieb:

    Den Copy-Constructor habe ich hinzugefügt, da er vom Compiler erwartet wird).

    Und das bringt dich nicht auf den Gedanken, dass da vielleicht was kopiert wird?

    PS: Beim nochmal Lesen meines Beitrags fällt mir auf, dass das vielleicht doch ein etwas zu kryptischer Hinweis ist, wenn der Fragesteller nicht weiß, worauf man hinaus will. Daher:
    http://en.cppreference.com/w/cpp/utility/functional/ref
    Und noch ein Tutorial (sogar von dem Mann, der maßgeblich am Entwurf der C++11-Threads beteiligt war) mit passendem Eintrag:
    http://www.justsoftwaresolutions.co.uk/threading/multithreading-in-c++0x-part-3.html
    PPS: Compileroptimierungen können dir übrigens nichts kaputt machen, solange du dich an den Standard hältst. Und das solltest du. (Hast du hier ja auch gemacht, bloß macht dein Programm selber eben nicht das was du denkst, weil du eine versteckte Kopie übersehen hast. Aber was das Programm macht und was da warum kopiert wird, das ist ganz genau definiert 🙂 )



  • Vielen Dank!

    Da hab ich wohl eine Kopie übersehen 😉


Log in to reply