POSIX Thread und Polymorphie

Gast #3227549
Lesenswert?

Hallo!

Ich habe mir eine einfache Threadklasse gebaut, wie nachstehend, die 
unter Windows (GCC Codeblocks) auch wunderbar funktioniert. Wenn ich den 
gleichen Code versuche auf einem µCLinux-System (ARM11) zu compilieren 
und laufen zu lassen scheint die Applikation an der Stelle 
obj->Execute(); abzustürzen. Hat jemand eine Idee woran das liegen 
könnte?

Stefan
1
#include <iostream>
2
#include <conio.h>
3
#include <pthread.h>
4
#include <windows.h>
5

6
using namespace std;
7

8
class PThread
9
{
10
    private:
11
        pthread_t thread;
12
    public:
13
        virtual void Execute(void) = 0;
14
        PThread(void);
15
};
16

17
static void *execute(void *arg)
18
{
19
    PThread *obj = (PThread*) arg;
20
    obj->Execute();
21
    return 0;
22
}
23

24
PThread::PThread(void)
25
{
26
    pthread_create(&thread, NULL, &execute, this);
27
}
28

29
class MyThread: public PThread
30
{
31
    public:
32
        void Execute(void);
33
};
34

35
void MyThread::Execute(void)
36
{
37
    while (1)
38
    {
39
        cout << "Execute" << endl;
40
        Sleep(1000);
41
    }
42
}
43

44
int main()
45
{
46
    MyThread mythread;
47
    getch();
48
    return 0;
49
}
#3227640
Lesenswert?

hmm... Compiliert
( g++ -Wall -o x -pthread x.cc)
und läuft sowohl auf PC als auch auf Linux@ARMv7

Sicher dass du da denselben Code verwendest?

Mit void*-Casts und Polymorpie (oder gar Mehrfachvererbung) kriegt man 
leicht einen "pure virtual function call" hin...
Angehängte Dateien:
Gast #3227648
Lesenswert?

Stefan schrieb:
> printf("obj: %p\n", obj );
> obj->Execute();
>
> Unter µCLinux: 0x92c1a8
> Unter Windows: 0x28FF14

dann mach mal bitte noch hier eine ausgabe rein, da sollte das gleiche 
rauskommen

printf("obj: %p\n", this );
> pthread_create(&thread, NULL, &execute, this);
#3227741
Lesenswert?

Hi,

dass der Code in Windows funktioniert ist wohl eher Zufall. Der Thread 
läuft nämlich schon los, bevor Deine abgeleitete Klasse "MyThread" 
vollständig konstruiert ist. Du kannst an dieser Stelle noch nicht auf 
virtuelle Funktionen der Basisklasse zugreifen, da das Objekt hier noch 
nicht seine Endausprägung kennt. Normalerweise gibt das einen "pure 
virtual function called" Laufzeitfehler.
Schreibe eine Run()-Funktion und lass den Thread nach der Konstruktion 
von "MyThread" loslaufen.

Gruß, Oliver
Gast #3227755
Lesenswert?

>Du kannst an dieser Stelle noch nicht auf
>virtuelle Funktionen der Basisklasse zugreifen

Wenn man genau darüber nachdenkt eigentlich völlig logisch, vielen Dank 
für den Hinweis, ich werde meine Threadklasse umbauen!

Gruß
Stefan
#3227776
Lesenswert?

Genaugenommen handelt es sich hierbei um eine klassische Race-Condition: 
Ist "MyThread" konstruiert bevor der Thread darauf zugreift oder nicht?
Das erklärt wahrscheinlich auch, warum es unter Windows (meistens, 
immer?) funktioniert: Hier scheint der Thread zum Loslaufen länger zu 
brauchen, als die Konstruktion von "MyThread".


Gruß,
Oliver
Gast #3227814
Lesenswert?

Aber wenn ich den Thread innerhalb des Konstruktors der Klasse MyThread 
loslaufen lasse sollte alles ok sein, oder? Zu diesem Zeitpunkt müsste 
ja eigentlich die vtable schon fertig zusammengebaut sein...

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