Nehmen wir an, ich habe eine Klasse wie
class c {
// ...
void *print(void *){ cout << "Hello"; }
}
Und dann habe ich einen Vektor von c
vector<c> classes; pthread_t t1;
classes.push_back(c());
classes.push_back(c());
Jetzt möchte ich einen Thread erstellen c.print();
Und das Folgende gibt mir das folgende Problem: pthread_create(&t1, NULL, &c[0].print, NULL);
Fehlerausgabe: 'void * (tree_item ::) (void )' kann nicht in 'void * ( ) (void )' für das Argument '3' in 'int pthread_create (pthread_t *, const pthread_attr_t *, void * ( ) (void) konvertiert werden ), nichtig *) '
Meine bevorzugte Art, mit einem Thread umzugehen, besteht darin, ihn in ein C ++ - Objekt zu kapseln. Hier ist ein Beispiel:
Um es zu verwenden, erstellen Sie einfach eine Unterklasse von MyThreadClass mit der InternalThreadEntry () -Methode, die so implementiert ist, dass sie die Ereignisschleife Ihres Threads enthält. Sie müssen natürlich WaitForInternalThreadToExit () für das Thread-Objekt aufrufen, bevor Sie das Thread-Objekt löschen (und über einen Mechanismus verfügen, um sicherzustellen, dass der Thread tatsächlich beendet wird, da WaitForInternalThreadToExit () sonst niemals zurückkehren würde).
quelle
Sie müssen
pthread_create
eine Funktion angeben, die der gesuchten Signatur entspricht. Was Sie passieren, wird nicht funktionieren.Sie können jede beliebige statische Funktion implementieren, die Sie dazu
c
ausführen möchten , und sie kann auf eine Instanz des Threads verweisen und diese ausführen.pthread_create
wurde entwickelt, um nicht nur einen Funktionszeiger, sondern auch einen Zeiger auf "Kontext" aufzunehmen. In diesem Fall übergeben Sie ihm einfach einen Zeiger auf eine Instanz vonc
.Zum Beispiel:
quelle
Die obigen Antworten sind gut, aber in meinem Fall hat der erste Ansatz, der die Funktion in eine statische konvertiert, nicht funktioniert. Ich habe versucht, bestehenden Code zu konvertieren, um ihn in die Thread-Funktion zu verschieben, aber dieser Code enthielt bereits viele Verweise auf nicht statische Klassenmitglieder. Die zweite Lösung zum Einkapseln in ein C ++ - Objekt funktioniert, verfügt jedoch über 3-Ebenen-Wrapper zum Ausführen eines Threads.
Ich hatte eine alternative Lösung, die das vorhandene C ++ - Konstrukt verwendet - die Funktion 'friend' - und sie funktionierte perfekt für meinen Fall. Ein Beispiel, wie ich 'Freund' verwendet habe (verwendet das obige Beispiel für Namen, die zeigen, wie es mit Freund in eine kompakte Form umgewandelt werden kann)
Natürlich können wir boost :: thread verwenden und all dies vermeiden, aber ich habe versucht, den C ++ - Code so zu ändern, dass kein Boost verwendet wird (der Code wurde nur zu diesem Zweck gegen Boost verlinkt).
quelle
Meine erste Antwort in der Hoffnung, dass sie für jemanden nützlich sein wird: Ich bin jetzt eine alte Frage, aber ich habe genau den gleichen Fehler wie die obige Frage festgestellt, als ich eine TcpServer-Klasse schrieb und versuchte, pthreads zu verwenden. Ich habe diese Frage gefunden und verstehe jetzt, warum es passiert ist. Am Ende habe ich das gemacht:
Methode zum Ausführen von Threaded ->
void* TcpServer::sockethandler(void* lp) {/*code here*/}
und ich nenne es mit einem Lambda ->
std::thread( [=] { sockethandler((void*)csock); } ).detach();
das scheint mir ein sauberer Ansatz zu sein.
quelle
Zu oft habe ich Wege gefunden, um das zu lösen, wonach Sie fragen. Meiner Meinung nach sind sie zu kompliziert. Zum Beispiel müssen Sie neue Klassentypen, Linkbibliotheken usw. definieren. Deshalb habe ich beschlossen, ein paar Codezeilen zu schreiben, die es dem Endbenutzer ermöglichen, im Grunde eine "void :: method (void)" von "thread-ize" zu können welche Klasse auch immer. Natürlich kann diese von mir implementierte Lösung erweitert, verbessert usw. werden. Wenn Sie also spezifischere Methoden oder Funktionen benötigen, fügen Sie diese hinzu und halten Sie mich auf dem Laufenden.
Hier sind 3 Dateien, die zeigen, was ich getan habe.
// Die Klasse, die die gesamte Arbeit zum Thread-Ize einer Methode (test.h) einschließt:
// Eine Verwendungsbeispieldatei "test.cc", die ich unter Linux kompiliert habe. Die Klasse, die die gesamte Arbeit zum Thread-ize einer Methode zusammenfasst: g ++ -o mytest.exe test.cc -I. -lpthread -lstdc ++
quelle
Dies ist eine etwas alte Frage, aber ein sehr häufiges Problem, mit dem viele konfrontiert sind. Das Folgende ist eine einfache und elegante Möglichkeit, dies mithilfe von std :: thread zu handhaben
Der obige Code sorgt auch dafür, dass Argumente an die Thread-Funktion übergeben werden.
Siehe std :: thread Dokument für weitere Details.
quelle
Meine Vermutung wäre, dass dies b / c ist, das durch C ++ b / c ein wenig verstümmelt wird, wenn Sie ihm einen C ++ - Zeiger senden, keinen C-Funktionszeiger. Es gibt anscheinend einen Unterschied . Versuchen Sie es mit einem
und dann senden p.
Ich habe getan, was Sie mit einer Mitgliedsfunktion tun, aber ich habe es in der Klasse getan, die es verwendet hat, und mit einer statischen Funktion - was meiner Meinung nach den Unterschied ausmachte.
quelle
C ++: Wie übergebe ich die Klassenmitgliedsfunktion an pthread_create ()?
http://thispointer.com/c-how-to-pass-class-member-function-to-pthread_create/
quelle