est tut: weh: was machst volatile


  • Gesperrt

    Hallo,

    ich habe folgenden Snipsel zu durchlöchern:

    ...
    #include <mutex>
    
    static std::mutex mutex;
    
    
    void f(get_request<std::ostream>& request){
    	std::lock_guard<std::mutex> lockerzsch(mutex);
    	request.cancel();
    }
    
    
    int main(){
    	mutex.lock();
    	auto shp = mach_get_request(std::cerr, "https://example.net");
    	std::thread t{&::f, std::ref(*shp)};
    	shp->set(CURLOPT_VERBOSE, true);
    	shp->cancel_callback = [](){
    		std::cerr << "simply canceled:<3\n";
    	};
    	mutex.unlock();
    	std::cerr << "unlocked now sleeping 3 secs and canceled already done so....\n\n\n";
    	t.join();
    	std::this_thread::sleep_for(std::chrono::seconds(3));
    	shp->perform();
    }
    

    ich hab in meiner lib/request ein bool/atomic<bool> cancel_operation und eine cancel() die die get request cancelt.

    Ich versuche in meiner lib eine direkte cancel() methode einzubauen 🙂 Dafür hab ich (curl unterm Hut) in der CURLOPT_WRITE_FUNCTION statischen Methode anfangs den folgen Code stehen:

    std::size_t write_body(const char* data, std::size_t size) override{
    	if(cancel_operation){
    		if(cancel_callback) cancel_callback();
    		return abort_write_callback;
    	}
    ...
    

    Und dann die cancel()

    void cancel(){
    	cancel_operation = true;
    }
    

    und irgendwie klassenintern...

    (volatile) bool cancel_operation{false};
    

    Und jetzt schau auf den ersten Code. will innerhalb eines Threads die cancel Operation aufrufen, sogesehen vor perform(), warte 3 Sekunden dafür, joine es sogar, Dann mach ich perform() und das macht irgendwann write_body(...) intern.

    Und. Grad nochmal mit gdb Debugger. Setze ich das ding als erst auf true und dann ist die Bedingung letztendlech doch false. Und ich dachte volatile weil nix berühren oder so. Und das auch nicht. Und daraus schließt sich seit einem Abend rund ein paar Stündchen meine Frage warum. Bin ich dumm und meine lib die eigentlich immer geklappt hat und cancel_operation sonst nirgends berührt hab, doch nicht funzt, dann wodenn!?

    Sonst andere Diskussion. Wann brauch ich eigentlich dieses volatile. Bei IPC? Wenn ja dann okt. Ich hab da immer so gehört, Kompiller optimieren dinge und volatile macht dass nirgends was außergewöhnliches gemacht wird. Mehr hab ich jetzt nicht forensiert.

    Ich ende mal/.

    Danke für alle folgenden Antworten mal. 🙂

    PS: ich auch store() load() bei atomic gemacht!



  • volatile unterbindet gewisse Optimierungsmöglichkeiten weil der Compiler immer davon ausgehen muss, daß sich der Wert der Variable zu jeder Zeit geändert haben kann. volatile ist kein Mittel zur Synchronisation. [decl.type/5]


  • Gesperrt

    Doch atomic ist es. Also wo ist das Problem.



  • Nein. Eine Variable die volatile ist garantiert nicht atomic access. Wenn du weiter das Gegentum behaupten willst dann sag wo das geschrieben steht.


  • Gesperrt

    Hmpf irgendwo lieg ich daneben.

    Dann guck.

    #include <mutex>
    
    static std::mutex mutex;
    
    
    void f(get_request<std::ostream>& request){
    	std::lock_guard<std::mutex> lockerzsch(mutex);
    	request.cancel();
    }
    
    
    int main(){
    	mutex.lock();
    	auto p = much_get(std::cerr, "https://example.net");
    	std::thread t{&::f, std::ref(*p)};
    	p->rx_callback = [](const char* , std::size_t k){
    		std::cerr << "simply canceled:<3\n";
    		return false;
    	};
    	mutex.unlock();
    	std::cerr << "unlocked now sleeping 3 secs and canceled already done so....\n\n\n";
    	t.join();//hm
    	std::this_thread::sleep_for(std::chrono::seconds(3));
    	p->perform();
    }
    

    Also wie mach ich atomic access?




Anmelden zum Antworten