Forum: PC-Programmierung C++: Member-Funktion als Thread ausfuehren, wie macht man's richtig?


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Hallo Leute,

Ich moechte eine Member-Funktion einer Klasse als Thread laufen lassen.
Randbedingungen:
- keine third-party libs wie boost, qt oder sonst was
- es muss mit -std=c++98 compilieren
- muss nur auf Linux laufen
- compiler ist der gcc

Es sei folgendes Beispiel gegeben:
1
class Test
2
{
3
  public:
4
    Test();
5
    ~Test();
6
    void DoAny(void);
7
8
  private:
9
    void IncrementCnt(void);
10
    uint64_t m_Cnt;
11
};
12
//----------------------
13
Test::Test()
14
{
15
    m_Cnt = 0;
16
}
17
void Test::DoAny(void)
18
{
19
  // mach irgendwas
20
  // warte auf irgendwas
21
  IncrementCnt();
22
}
23
24
void Test::IncrementCnt(void)
25
{
26
  m_Cnt++;
27
}
28
//----------------------
29
int main(void)
30
{
31
  Test TestObj;
32
33
  TestObj.DoAny() // <-- soll als Thread ausgefuehrt werden
34
35
  // hier passieren noch andere sachen
36
  return 0;
37
}

Dazu habe ich diesen Beitrag auf Stackoverflow gefunden:
http://stackoverflow.com/questions/11194636/using-member-functions-in-pthreads-linux
Die dort gepostete Loesung funktioniert. Allerdings wird in den 
Antworten auf den Post gesagt, das es nur wegen eines Compiler Bugs 
funktioniert.
1
Technically this isn't valid, because the function pointer passed to pthread_create must be
2
extern "C" which the static member function isn't ... but it works with GCC (and other compilers)
3
due to a bug/feature that fails to differentiate between extern "C" and extern "C++" functions.
Wenn die dort gepostete Loesung wirklich unsauber ist, wie macht man es 
denn richtig? Hoffe Ihr koennt mir helfen. :)

Gruesse

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

So, wie Du es in Deinem Beispielcode machst, geht es nicht; die Funktion 
muss statisch sein und sie ist nicht über ein Objekt aufzurufen.

Wenn die Funktion sich auf eine Objektinstanz beziehen soll, muss der 
zugehörige this -Pointer auf andere Art und Weise mitgeliefert werden, 
denn von einem this-Pointer weiß die C-Aufrufkonvention nichts, die 
letztlich die Threadfunktionen aufruft.

Ich wüsste nicht, wieso der Aufruf einer statischen Memberfunktion ein 
"Compilerfehler" sein soll; aber um das (hypothetische?) Problem zu 
umgehen, kann man auch so vorgehen:

Nicht die Memberfunktion direkt wird als Threadfunktion verwendet, 
sondern eine tatsächlich mit normaler C-Aufrufkonvention definierte 
Funktion - und die ruft dann wiederum Deine Memberfunktion auf. Die muss 
dann noch nicht mal statisch sein, sondern kann genauso aufgerufen 
werden, wie Du es in Deinem Beispielcode machst.

von Konrad S. (maybee)


Lesenswert?

Mach eine Struktur und pack da einen Zeiger auf das Objekt und einen 
Zeiger auf die aufzurufende Methode rein. Beim Start des Threads 
übergibst du den Zeiger auf die Struktur. Jetzt hast du im Thread alles 
Nötige für den C++-gerechten Methodenaufruf.

von Jay (Gast)


Lesenswert?

Der neuste C++-Standard hat ein rudimentäres Threading-API, und einige 
GCC-Builds unterstützen das.
1
#include <thread>

Allerdings hat man wieder ein bisschen Template-Spielerei reingemixt, so 
dass man im ungünstigen Fall die für Templates nichtssagenden 
Fehlermeldungen bekommt.

von Klaus W. (mfgkw)


Lesenswert?

Jay schrieb:
> Der neuste C++-Standard

vs.

Kaj G. schrieb:
> - es muss mit -std=c++98 compilieren

von Rolf Magnus (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Kaj G. schrieb:
>> - es muss mit -std=c++98 compilieren

Dann kommt's drauf an, ob die libpthread als "3rd-Party-Lib" zählt. Wenn 
ja, dann wird's ziemlich umständlich.

Rufus Τ. Firefly schrieb:
> Ich wüsste nicht, wieso der Aufruf einer statischen Memberfunktion ein
> "Compilerfehler" sein soll;

Wie der Text schon sagt, erwartet pthread_create einen Zeiger auf eine 
Funktion, die extern "C" ist. statische Memberfunktionen sind das nicht, 
und man kann sie auch nicht explizit extern "C" machen. Es funktioniert 
nur deshalb, weil sich in gcc die Aufrufkonvention zwischen C und C++ 
aktuell nicht unterscheidet.
Ich bin mir grad nicht sicher, ob der Compiler da eigentlich einen 
Fehler melden müßte oder ob "nur" das Verhalten undefiniert ist.

von Martin (Gast)


Lesenswert?

Ich glaube pthread.h ist schon in c++98 drin gewesen:
1
#include <pthread.h>

https://computing.llnl.gov/tutorials/pthreads/

von Le X. (lex_91)


Lesenswert?

Martin schrieb:
> Ich glaube pthread.h ist schon in c++98 drin gewesen

Ich glaube, pthread.h ist in keinem C oder C++ Standard enthalten.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Erst mal danke fuer die Antworten. :)

Rolf Magnus schrieb:
> Dann kommt's drauf an, ob die libpthread als "3rd-Party-Lib" zählt. Wenn
> ja, dann wird's ziemlich umständlich.
Die pthread.h darf schon verwendet werden, nur halt nicht sowas wie 
<thread> (weil C++11), oder boost, oder qt, oder was es sont noch so 
gibt. Es soll halt funktionieren, ohne das etwas extra installiert 
werden muss.

le x. schrieb:
> Martin schrieb:
>> Ich glaube pthread.h ist schon in c++98 drin gewesen
>
> Ich glaube, pthread.h ist in keinem C oder C++ Standard enthalten.
Sagen wir mal so:
Die gepostete Loesung von Stackoverflow compiliert mit -std=c++98, somit 
ist das ok.

Ich werde mal ein bisschen mit den vorschlaegen von Rufus und Konrad 
spielen.

Danke fuer eure Hilfe. :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.