Thread save Queue



  • Hallo Leute,
    ich verstehe nicht warum und ich sehe auch nicht warum diese Klasse nicht thread safe ist!

    template <typename T>
    	class MessageQueue
    	{
    		public:
    
    			MessageQueue() {
    
    			}
    
    			T pop(){
    				boost::unique_lock<boost::mutex> mlock(mutex);
    				while (queue.empty()) {
    					cond.wait(mlock);
    				}
    
    				auto val = queue.front();
    				queue.pop();
    
    				return val;
    			}
    
    			void pop(T& item){
    				boost::unique_lock<boost::mutex> mlock(mutex);
    				while (queue.empty())
    				{
    					cond.wait(mlock);
    				}
    				item = queue.front();
    				queue.pop();
    			}
    
    			void push(const T& item){
    				boost::unique_lock<boost::mutex> mlock(mutex);
    				queue.push(item);
    				mlock.unlock();
    				cond.notify_one();
    			}
    
    		private:
    			std::queue<T> queue;
    			boost::mutex mutex;
    			boost::condition_variable cond;
    	};
    

    Hat jemand ne Idee was damit nicht stimmt



  • C_++std-2017 schrieb:

    ich verstehe nicht warum und ich sehe auch nicht warum diese Klasse nicht thread safe ist!

    Und warum nimmst du an, dass sie dennoch nicht thread safe ist?



  • Hi,
    wenn ich 1 Producer und 4 Konsumenten laufen lasse, kriege ich bei queue.pop() eine exception geworfen
    Grüße



  • C_++std-2017 schrieb:

    eine exception geworfen

    Eine?



  • Vielleicht besser gesagt 4



  • Glaubst du wirklich, dass ich nach der Anzahl gefragt habe?



  • Hi,
    eine? Kann man falsch verstehen und habe ich auch falsch verstanden, sorry.

    T pop(){
    				try {
    					boost::unique_lock<boost::mutex> mlock(mutex);
    					while (queue.empty()) {
    						cond.wait(mlock);
    					}
    				}
    				catch (boost::exception & e) {
    					std::cout << "Errror111111111\n" << "\n";
    				}
    				catch (const std::runtime_error& re)
    				{
    					std::cerr << "Runtime error: " << re.what() << std::endl;
    				}
    				catch (const std::exception& ex)
    				{
    					std::cerr << "Error occurred: " << ex.what() << std::endl;
    				}
    				catch (...) {
    					std::cout << "Errror222222222222222\n" << "\n";
    				}
    				try {
    					auto val = queue.front();
    					queue.pop();
    
    					return val;
    				}
    				catch (...) {
    					std::cout << "FERRRRRRR\n";
    				}
    				throw;
    			}
    

    Habe die Pop Methode um Catches erweitert kriege allerdings nur Error2222222 raus, deshalb kann ich nicht sagen was für eine Exception geworfen wird



  • Kann mir einer helfen, zumindest die exception zu fangen damit ich weiß was passiert?



  • Neuer Code, neues Glück.

    In Zeile 7 wird dein Mutex freigegeben. Das war's dann mit threadsafe.



  • Hi Leute,
    danke erstmal für die Hilfe.
    Die Klasse ist Thread Safe!

    Problem ist wenn ein weitere Thread die Konsumenten mit Interrupt beenden, kommt es zur exception!



  • C_++std-2017 schrieb:

    Problem ist wenn ein weitere Thread die Konsumenten mit Interrupt beenden, [...]

    Was im normalen Programmablauf niemals passieren sollte...



  • C_++std-2017 schrieb:

    Problem ist wenn ein weitere Thread die Konsumenten mit Interrupt beenden, kommt es zur exception!

    Das ist kein Problem, das ist das definierte Verhalten von boost::thread::interrupt() : Es führt dazu dass im unterbrochenen Thread eine boost::thread_interrupted Exception geworfen wird.
    Und da boost::thread_interrupted nicht von std::exception abgeleitet ist (und auch sonst keine Basisklassen hat), landet die halt im catch (...).

    => Es ist immer von Vorteil wenn man weiss was die Klassen/Funktionen die man verwendet so machen.



  • Richtig! Allerdings wäre mir nicht in den Sinn gekommen in der Queue diese Exception zu fangen. Aber man lernt aus Fehlern



  • Brauchst du ja nicht.
    Die boost::thread_interrupted Exception darf eh aus der Thread-Function rauspfeiffen. Wenn boost::thread eine boost::thread_interrupted Exception fängt, wird der Thread einfach nur beendet. Bei allen anderen Exceptions wird AFAIK das Programm abgebrochen (vermutlich über einen Aufruf von abort, terminate oder unexpected).

    ps: Wobei natürlich VIEL besser ist einfach boost::thread::interrupt() nicht zu verwenden.


Log in to reply