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
joinwartet, 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 duaddmessagein einem eigenen Thread auf und nicht im Hauptthread?
-
#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
tloggingbeendet wird, bevor duaddmessageaufrufst,startkommt aber nie zurück, daher wirdaddmessageauch schon nicht aufgerufen.