Klassenfunktion mit Parameter als Thread



  • Moin!

    Folgenden Code habe ich:

    class cfunktion() {
    
    public:
    void addmessage(std::string stext);
    
    }
    
    int main() {
    
    // Wie muss ich die Funktion "addmessage" als Task hinschreiben?
    // ohne Parameter wäre es:
    // std::thread t1(&cfunktion::addmessage, &cfunktion);
    
    return 0;
    }
    

    Vielen Dank im Voraus!



  • Guten Abend @no_name1991

    #include <iostream>
    #include <thread>
    #include <string>
    
    class Cfunktion {
    public:
        void addmessage(std::string stext) {
            std::cout << "Nachricht: " << stext << std::endl;
        }
    };
    
    int main() {
        Cfunktion obj; // Wir brauchen ein Objekt der Klasse
        std::string msg = "Hallo Welt";
    
        // Syntax: std::thread(Funktionsadresse, Objektadresse, Parameter1, Parameter2, ...)
        std::thread t1(&Cfunktion::addmessage, &obj, msg);
    
        t1.join(); // Warten, bis der Thread fertig ist
        return 0;
    }
    
    

    Hab Deine Frage an ne KI weitergegeben. So lernen wir und diese 😁.

    Wenn mehrere Threads die Methode aufrufen sollen, schau Dir auch mal "mutex" an.



  • @Helmut-Jakoby sagte in Klassenfunktion mit Parameter als Thread:

    // Wir brauchen ein Objekt der Klasse

    Das ist nicht korrekt.

    Er kann einfach eine Lambda-Funktion verwenden, und in ihr die Funktion auf dem Objekt (std::thread / Cfunktion) aufrufen.

    Ein ähnliches Thema gab es hier erst kürzlich. Dynamische Parameterbindung und so.



  • Das wäre dann in etwa wie folgt: https://www.c-plusplus.net/forum/post/2624561



  • Vielen Dank.

    Die Antworten haben mir sehr geholfen.



  • Gerne möchte ich die Funktion als Thread ausführen und ihm neue Nachrichten zukommen lassen. Dafür habe ich 2 Funktionen. Leider wird zwar der Logger (zum Speichern angedacht) ausgeführt. Doch es werden keine neuen Nachrichten ausgegeben (/gespeichert).

    Kann es an dem lock eventuell liegen?

    
    void clogging::start() {
    	std::cout << "logging start" << std::endl;
    	while (1!=0)
        {
            if (mutex.try_lock())
            {
                if(vsmessage.size()==0) {
                	
    			} else if(vsmessage.size()>0) {
    				std::cout << vsmessage << std::endl;
    				vsmessage.pop_back();
    			} else {
    			}
                mutex.unlock();
            } else {
            	mutex.unlock();
            }
            // for cpu and add new message
            mutex.unlock();
            std::this_thread::sleep_for(500ms);
        }
    }
    
    
    
    
    void clogging::addmessage(std::string stext) {
    	std::cout << "addmessage" << std::endl;
    	while (true)
        {
            if (mutex.try_lock())
            {
                std::cout << "job shared (" << " message " << ")\n";
                vsmessage.push_back(stext);
                mutex.unlock();
                return;
            } else {
            	vsmessage.push_back(stext);
            	std::cout << "job exclusive (" << " message " << ")\n";
            }
            mutex.unlock();
    		std::this_thread::sleep_for(500ms);
        }
    }
    
    clogging logging;
    	
    	
    	std::thread tlogging(&clogging::startA, &logging);
      	tlogging.join();
      	
      	std::string msg = "Hallo Welt";
      	
    	std::thread t1(&clogging::addmessageA, &logging, msg);
    	t1.join();
    

    Vielen Dank im Voraus!



  • @no_name1991 Kannst du den Code so zusammen stellen, dass wir direkt ein kompilierbares Beispiel haben? Dann müssen wir nicht annehmen, wo der Mutex lebt, in welchem Kontext deine Threads erstellt werden und sehen schneller, wo die Probleme liegen können.



  • ich entschuldige mich dafür und reiche hier meinen Code (compilierbar) nach:

    
    #include <algorithm>
    #include <filesystem>
    #include <fstream>
    #include <iostream>
    #include <string>
    
    #include <mutex>
    #include <thread>
    
    using namespace std::chrono_literals;
    
    class clogging{
    	
    	private:
    		
    		std::vector<std::string> vsmessage;
    		std::mutex mutex;
    		
    	protected:
    		
    	public:
    		
    		void start() {
    			std::cout << "logging start" << std::endl;
    			while (1!=0)
    		    {
    		        if (mutex.try_lock())
    		        {
    		            if(vsmessage.size()==0) {
    					} else if(vsmessage.size()>0) {
    						std::cout << vsmessage[0] << std::endl;
    						vsmessage.pop_back();
    					} else {
    					}
    		            mutex.unlock();
    		        } else {
    		        }
    		        std::this_thread::sleep_for(500ms);
    		    }
    		}
    		
    		void addmessage(std::string stext) {
    			std::cout << "addmessage" << std::endl;
    			while (true)
    		    {
    		        if (mutex.try_lock())
    		        {
    		            vsmessage.push_back(stext);
    		            mutex.unlock();
    		            return;
    		        } else {
    		        }
    				std::this_thread::sleep_for(500ms);
    		}
    		
    	};
    
    };
    
    
    int main() {
    	
    	clogging logging;
    	
    	std::thread tlogging(&clogging::start, &logging);
      	tlogging.join();
      	
      	std::string msg = "Hallo Welt";
      	
    	std::thread t1(&clogging::addmessage, &logging, msg);
    	t1.join();
    	
    	return 0;
    }
    
    
    
    


  • @no_name1991
    Da fehlt noch der Vektor include 😉

    https://en.cppreference.com/w/cpp/thread/thread/join.html

    join wartet, dass der Thread beendet wird. Da du da eine unendlich Schleife drinnen hast, wird das aber nie passieren.

    Edit:

    int main() {
    
      clogging logging;
    
    
      std::thread tlogging(&clogging::start, &logging);
    
      std::string msg = "Hallo Welt";
    
      std::thread t1(&clogging::addmessage, &logging, msg);
      tlogging.join();
    
      t1.join();
    
      return 0;
    }
    

    so siehst du zumindest eine Ausgabe 😉



  • @no_name1991
    Mal eine Frage: Warum rufst du addmessage in einem eigenen Thread auf und nicht im Hauptthread?



  • @Quiche-Lorraine

    #include <algorithm>
    #include <filesystem>
    #include <fstream>
    #include <iostream>
    #include <string>
    
    #include <mutex>
    #include <thread>
    
    using namespace std::chrono_literals;
    
    class clogging{
    	
    	private:
    		
    		std::vector<std::string> vsmessage;
    		std::mutex mutex;
    		
    	protected:
    		
    	public:
    		
    		void start() {
    			std::cout << "logging start" << std::endl;
    			while (1!=0)
    		    {
    		        if (mutex.try_lock())
    		        {
    		            if(vsmessage.size()==0) {
    					} else if(vsmessage.size()>0) {
    						std::cout << vsmessage[0] << std::endl;
    						vsmessage.pop_back();
    					} else {
    					}
    		            mutex.unlock();
    		        } else {
    		        }
    		        std::this_thread::sleep_for(500ms);
    		    }
    		}
    		
    		void addmessage(std::string stext) {
    			std::cout << "addmessage" << std::endl;
    			while (true)
    		    {
    		        if (mutex.try_lock())
    		        {
    		            vsmessage.push_back(stext);
    		            mutex.unlock();
    		            return;
    		        } else {
    		        }
    				std::this_thread::sleep_for(500ms);
    		}
    		
    	};
    
    };
    
    
    int main() {
    	
    	clogging logging;
    	
    	std::thread tlogging(&clogging::start, &logging);
      	tlogging.join();
      	
      	std::string msg = "Hallo Welt";
      	
    	//std::thread t1(&clogging::addmessage, &logging, msg);
    	//t1.join();
    	
    	logging.ddmessage(msg);
    	
    	return 0;
    }
    

    Dieser Code gibt nur die als Output "logging start" aus.

    Mein Ziel ist es, Ein/-Ausgaben, Zustände etc auszugehen bzw diese eventuell auf Festplatte zu speichern.
    Dies soll dann das restliche Programm nicht blockieren (warten bis die HDD etc es beendet hat).



  • @no_name1991 Du wartest darauf das tlogging beendet wird, bevor du addmessage aufrufst, start kommt aber nie zurück, daher wird addmessage auch schon nicht aufgerufen.


Anmelden zum Antworten