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

OP (Firma: RUB) #4004731
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
Persönliche Seite #4004748
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.
Gast #4004870
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.
Gast #4005070
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.
OP (Firma: RUB) #4005477
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. :)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren