Du bist nicht angemeldet.

Werbeanzeige

1

05.05.2009, 18:09

Klassen Methoden und Threads

Hey...
Ich habe Probleme eine bestimmte Methode einer Klasse als Thread laufen zu lassen -.-
Kennt jmd ein gutes Tut dazu?

2

05.05.2009, 18:14

Erstmal Willkommen im Forum!

Bitte beschreibe deine Probleme mal etwas genauer.
Etwas Quellcode dazu, und ich bin sicher, wir kriegen das gelöst. ;)
fka tm

Databyte

Alter Hase

Beiträge: 1 044

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

3

05.05.2009, 19:29

Hi

wenn du unter Windows bist, könnte das hier das richtige sein:

https://www.spieleprogrammierer.de/phpBB…opic.php?t=6661

4

05.05.2009, 20:07

Also folgendes...

Ich habe keine Klasse und möchte darin jetzt eine Methode als Thread laufen lassen...
Gestartet werden soll das ganze durch eine andere Methode!

Starten will ich das ganze jetzt mit

C-/C++-Quelltext

1
_beginthread


bekommme dann aber eine Compilermeldung:

Quellcode

1
Dem Funktionsaufruf fehlt die Argumentliste ...


Das liegt iwie am this zeiger habe ich mal herausgefunden... (stimmt das)

dot

Supermoderator

Beiträge: 9 833

Wohnort: Graz

  • Private Nachricht senden

5

05.05.2009, 20:09

zeig mal deinen code her, wie versuchst dus, in welcher zeile tritt der fehler auf, ...? einfach so können wir leider maximal raten...

6

05.05.2009, 20:18

Also ich versuche einen kleinen IRC Client zu schreiben
(jetzt nicht gleich hauen ich mache das um mich weiterzubilden!)

hier mal die Mehode die als Thread laufen soll:


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void CIrc::ReceiveMsg(void *)
{
    char msg[1024];
    int x = 0;
    while(1)
    {
        x = recv(sock, msg, 1024, 0);
            
        if(x > 0)
        {
            msg[x] = 0;
            std::cout<< msg<< std::endl;
        }
        Sleep(10);
    }
}


Aufrufen tu ich das ganze so:

C-/C++-Quelltext

1
_beginthread(ReceiveMsg,0,(void *)NULL);

7

05.05.2009, 20:54

Zitat von »"blub23"«

C-/C++-Quelltext

1
_beginthread(ReceiveMsg,0,(void *)NULL);

da kannst du keine objektgebundene (nciht-statische) memberfunktion übergeben. statische ginge allerdings ;)

Databyte

Alter Hase

Beiträge: 1 044

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

8

05.05.2009, 20:57

Du kannst nur statische memberfunktionen mit _beginthread starten !!!

Ich hab irgendwann mal eine kleine Thread-Klasse programmiert...
da hab ich dann auch Sachen wie Criticle Sections, Events und Prioritäten implementiert.
Wenn du interesse hast, kann ich sie dir schicken... könnte auch noch ein paar Kommentare dazu packen...
Hier ein kleines Beispiel wie das dann funktioniert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// Klasse mit Thread-Funktion

class BackgroundProcess: public TThread
{
private:
// Paar kleine Extra Funktionen ( Namen sprechen für sich ;) )

    virtual void    OnEnter()   { std:: cout << "Start !!!\n"; }
    virtual void    OnKill()    { std:: cout << "Getötet Nein....!!!\n";}
    virtual void    OnStop()    { std:: cout << "Kurzer Stop!!!\n";}
    virtual void    OnResume()  { std:: cout << "Weiter Gehts!!!\n";}
 

// Diese Funktion wird jetzt in einem neuen Thread ausgeführt !

    virtual DWORD   Run()
    {
        // Immer wiederholen

        while(true)
        {
            std::cout << "Nerve ich ???";
            sleep(10000);
        }
        return 1;
    }
}


// ----------- Hier die anwendung -----------------

BackgroundProcess BGP;

// Jetzt starten ( ohne Parameter und sofort nach Aufruf )

BGP.create(NULL, true);

// Noch die Priorität runter setzten

BGP.SetPriority(TTP_Lowest);

// Kurz mal stoppen

BGP.Stop();

// wieder starten

BGP.Resum();

// Und beenden ( sollte möglichst vermieden werden.. normalerweise würde man oben die while-schleife auslaufen lassen.)

BGP. Kill();

Nox

Supermoderator

Beiträge: 5 282

Beruf: Student

  • Private Nachricht senden

9

05.05.2009, 21:47

Und wie schaut nun TThread aus? Ich glaube das würde ihn am meisten interessieren ;) . Leider ist die Lösung, die wir nutzen, schon sehr verzwickt. Daher kann ich sie leider nicht mal eben kurz zusammenfassen :S. Aber der Weg dahin wurde ja schon aufgezeigt :) . Einfach die Methode statisch machen, this als argument übergeben und in der statischen Methode dann den übergeben Zeiger, welcher ja nun ein void* Zeiger ist, wieder auf den ursprünglichen Typen zurückcasten. Nun kannst du auch die ganzen Methoden aufrufen, musst allerdings immer zeiger-> vor den Aufruf davorpacken.
Natürlich ist das nur das Streichholz. Der Umgang mit Zeigern, ein Talent für parallels Denken und einarbeiten in die Konzepte von Threads ist natürlich Voraussetzung![/cpp]
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Databyte

Alter Hase

Beiträge: 1 044

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

10

05.05.2009, 22:24

Ok... Hier TThread:
( Hoffe ihr könnt was erkennen... sind nen paar verschiebungen drin... liegt irgendwie an der Aufbereitung des HTMLs)
( Die Create-Funktion unterstützt auch noch Parameter aber die werden meist nicht gebraucht ;) )

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 *  + TThread_raw <typename T_ThreadParamType_, 
 *                  SIZE_T T_ThreadStackSize_ = 0>
 *  ----------------------------------------------------------------------------
 *  Klasse zur unterstützung von Threads.
 *  Erbende Klassen müssen eine Run-funktion beinhalten,
 *  die aufgerufen wird wenn der Thread gestartet ist.
 *  Außerdem gibt es Funktionen zum stoppen anhalten und
 *  wieder starten.
 *  ----------------------------------------------------------------------------
 *
 *
 *
 */


///////////////////////////////////////////////// e_TThreadPriority_ /////////////////////////////////////////////////


enum e_TThreadPriority_
{
    TTP_Idle                = THREAD_PRIORITY_IDLE,
    TTP_Lowest              = THREAD_PRIORITY_LOWEST,
    TTP_Low                 = THREAD_PRIORITY_BELOW_NORMAL,
    TTP_Normal              = THREAD_PRIORITY_NORMAL,
    TTP_Hight               = THREAD_PRIORITY_ABOVE_NORMAL,
    TTP_Hightest            = THREAD_PRIORITY_HIGHEST,
    TTP_TimeCritical        = THREAD_PRIORITY_TIME_CRITICAL,

    TTP_StartBackgroundMode = THREAD_MODE_BACKGROUND_BEGIN,
    TTP_StopBackgroundMode  = THREAD_MODE_BACKGROUND_END

};



///////////////////////////////////////////////// TThread_raw /////////////////////////////////////////////////


template<typename T_ThreadParamType_, SIZE_T T_ThreadStackSize_ = 0>
class TThread_raw
{
private:
    /* 
        Id des Threads 
    */
    DWORD                   _m_ThreadId_;


    /*
        Handle des Threads
    */
    HANDLE                  _m_ThreadHandle_;
    

    /* 
        Zeiger auf eine Struktur die Informationen für den Thread enthält o.ä.
    */
    T_ThreadParamType_*     _m_ThreadParam_;




    /*
        Interne Funktion zum starten des Threads
    */
    static DWORD WINAPI EntryPoint(void * _pStartingThread)
    {
       TThread_raw* _pStartThread = reinterpret_cast<TThread_raw*>(_pStartingThread);
       return _pStartThread->Run();
    }

protected:
    
    virtual void    OnEnter()       {}
    virtual DWORD   Run()           { return (1); }
    virtual void    OnKill()        {}
    virtual void    OnStop()        {}
    virtual void    OnResume()      {}

public:
    TThread_raw()
        : _m_ThreadId_(0)
    {}  

    /*
        Erstellt den Thread
    */
    DWORD   Create( T_ThreadParamType_* _ThreadParam    = NULL,
                    BOOL                _StartMomently  = true );


    /*
        Hält den Thread an. Er kann mit Resume wieder aktiviert werden
    */
    inline  DWORD   Stop()                                  { OnStop();     return SuspendThread(       _m_ThreadHandle_    ); }


    /*
        Holt den Thread aus dem Ruhezustand
    */
    inline  DWORD   Resume()                                { OnResume();   return ResumeThread(        _m_ThreadHandle_    ); }


    /*
        Elemeniert den Thread komplett
    */
    inline  BOOL    Kill()                                  { OnKill();     return TerminateThread( _m_ThreadHandle_, 1 ); }


    /*
        Setzt die Priorität des Threads
    */
    inline BOOL     SetPriority(e_TThreadPriority_ _pr)     { return SetThreadPriority(_m_ThreadHandle_, _pr); }



    // Inline - Methoden

    inline  DWORD               GetThreadId()       const   { return _m_ThreadId_; }
    inline  HANDLE              GetThreadHandle()   const   { return _m_ThreadHandle_; }
    inline  T_ThreadParamType_* GetThreadParam()    const   { return _m_ThreadParam_; }
};

template<typename T_ThreadParamType_, SIZE_T T_ThreadStackSize_ >
DWORD 
    TThread_raw<T_ThreadParamType_, T_ThreadStackSize_>
        ::Create(   T_ThreadParams_*    _ThreadParam,    // = NULL

                    BOOL                _StartMomently)   // = true

{
    OnEnter();

    _m_ThreadHandle_ = CreateThread(NULL,
                                    T_ThreadStackSize_,
                                    TThread_raw::EntryPoint,
                                    this,
                                    ( (_StartMomently)? (0) : (CREATE_SUSPENDED) ),
                                    &_m_ThreadId_);
    _m_ThreadParam_ = _ThreadParam;
    return (_m_ThreadId_);
}



typedef TThread_raw<void>   TThread;

Werbeanzeige