Gå til innhold

Threading med klasser


Anbefalte innlegg

Skrevet (endret)

Heisann,

jeg har et lite problem jeg håper dere kan hjelpe meg med:

 

Jeg skal skrive et program hvor multithreading skal brukes, og

dette skal/bør gjøres ved hjelp av klasser.

 

Spørsmålet er; Hvordan kjører jeg en intern klasse funksjon som en thread?

Øh, det ble litt fiklete forklart, men her har jeg litt kode som kanskje kan

klare det opp litt!

 

Headeren til en enkel klasse:


#include <windows.h>
#include <iostream>
using namespace std;
class THREAD_CLASS
{
     public:
           void RunThread();
      private:
           HANDLE threadHandle;
           void myThread();
}

 

...og her kommer koden som jeg lurer på:

#include "main.h"

void THREAD_CLASS::RunThread()
{
    //Dette er det jeg lurer på!*************************
    this->threadHandle = createThread(NULL,(LPTHREAD_START_ROUTINE)this->myThread());
    //*********************************************
}

void THREAD_CLASS::myThread()
{
    while (1)
    {
      cout << "Yeah" << endl;
    }
}

 

Takker for alle svar,

mvh Espen Øybø

Endret av jajajalla
Videoannonse
Annonse
Skrevet

Hmm, ideen min er at jeg kunne har flere klasser i en array, dvs at jeg

kunne starte flere threader med forskjellige data mens

programmet gikk, finnes det

andre måter å gjøre det på?

Skrevet (endret)

	class Thread {
public:
 Thread(); ///< Constructor
 Thread(bool execute_at_once); ///< Constructor
 virtual ~Thread(); ///< Destructor
 
 HANDLE thread; ///< The PID or thread-ID.
 signed char exit_code; ///< Did the thread/process end o.k.?

 virtual char main() = 0; ///< Entrypoint of thread. Defined by subclasses.
 void run(); ///< Execute thread. (Non-blocking)
 HANDLE operator()(); ///< The PID or thread-ID.
 operator ThreadID(); ///< The PID or theard-ID.
 void waitForSignal(); ///< Makes thread wait for signal before continuing execution. (Blocking)
 void finish(); ///< Makes external calling thread wait until this thread finishes, "syncronization". (Blocking)


private:
}; // Thread

 

DWORD WINAPI callback(LPVOID obj)
{
 static_cast<Oxymora::Thread*>(obj)->exit_code = static_cast<Oxymora::Thread*>(obj)->main();
return(0);
} // callback()


Thread::Thread()
{
} // constructor


Thread::Thread(bool exec)
{
if(exec)
 run();
} // constructor


Thread::~Thread()
{
} // destructor


void Thread::run()
{
thread = CreateThread(0, 0, &callback, this, 0, 0);
} // run


void Thread::waitForSignal()
{
SuspendThread(thread); // TODO: Returns DWORD -1 on error. Generate code to check when debugging.
} // waitForSignal


void Thread::finish()
{
WaitForSingleObject(thread, INFINITE);
} // finish


Thread::operator ThreadID()
{
return(thread);
} // operator ThreadID


ThreadID Thread::operator()()
{
return(thread);
} // operator()

 

Edit:

paster et eksempel som bruker koden om noen strakser - :] (dette er tatt fra Oxymora btw... )

 

Edit2:

Eller faen - jeg har ikke tilgang til en Windows-maskin nå -- skjønner du koden uansett?

Endret av søppel
Skrevet (endret)

Her:

#include <windows.h>
#include <iostream>
#include <vector>
#include <oxymora/util/thread.hpp>

using namespace std;


class MyThread : public Oxymora::Thread {
public:
signed char main()
{
 cout << "MyThread::main" << endl;
 return(0);
} // main
}; // MyThread


int main()
{
// main er virtuell - derfor må man allokere på heap. Artig.
MyThread* mt = new MyThread;
mt->run();

// Her er et ex. som lager et array med tråder:
MyThread* amt[3];
amt[0] = new MyThread;
amt[1] = new MyThread;
amt[2] = new MyThread;

amt[0]->run();
amt[1]->run();
amt[2]->run();

Sleep(1000); // for å være sikker på at alle trådene er ferdig ..
delete(mt);
delete[](amt);

return(0);
} // main

 

Edit:

Det er også et eksempel under Kodesnutter-tråden:

http://forum.hardware.no/index.php?showtop...dpost&p=2269516

Endret av søppel
Skrevet (endret)

Stemmer - jeg har ikke testet koden, siden jeg (fortsatt) ikke sitter forran en Windows-maskin. Jeg testet altså samme klassen under Linux men med en annen implementasjon (så klart) i stedet.

 

Takker. :]

 

Fungerte resten da?

 

Edit:

Uansett så skal eksempelet under "kodesnutter"-tråden (som nevnt ovenfor) fungere, tror jeg, den testet jeg under Windows for en tid tilbake.

Endret av søppel
Skrevet
:)

Finnes det noe tilsvarende som en Sleep(mill.sec) i linux?

(Jeg planlegger å skifte OS, så jeg vil ikke vli windows.h avhengig :p)

void usleep(unsigned long usec)

 

...er vel en mulighet. Parameteret er microsekunder.

 

Smeg out...

Skrevet (endret)

Okæi! Takk!

Den ligger i unistd.h den, ser det ut som...

Edit: Jeg testa på Windows maskina mi. Men det funka ikke...

Virker kansje kun i Linux?

Errors:

10 C:\Dev-Cpp\bin\TestProject.cpp `usleep' undeclared (first use this function)

(Each undeclared identifier is reported only once for each function it appears in.)

C:\Dev-Cpp\bin\Makefile.win [build Error] [TestProject.o] Error 1

 

Edit2: Kode:

#include <cstdlib>
#include <iostream>
#include <unistd.h>

using namespace std;

int main(int argc, char *argv[])
{
   cout << "Hello, world!";
   usleep(30000);
   return EXIT_SUCCESS;
}

Endret av zirener
Skrevet (endret)

Du må (eller bør) sette opp et eget interface (.hpp-fil) med to forskjellige implementasjoner (.cpp-filer) om du ønsker å kode platform-uavhengig kode her.

 

Edit:

Si fra om du vil ha et konkret eksempel.

Endret av søppel
Skrevet (endret)

Koden under kan kompileres som en helhet i en enkelt fil. "LEGG FØLGENDE ..." er ment som forslag ang. organisering av koden.

 

#include <iostream>

using namespace std;


// ******************************************************
// **** LEGG FØLGENDE I EN FIL, config.hpp, ELLERNOE ****
// ******************************************************

// The MinGW compiler under Win32 (or MinGW under Wine in Linux)
#if defined(__MINGW32__) || defined(MINGW)
#warning Compiling for the MinGW compiler under Win32 (or MinGW under Wine in Linux).
#define M_win32
#define M_win32_mingw
#define M_export
#endif // MINGW

// The GCC compiler under Linux
#if defined(__linux__)
#warning Compiling for the GCC compiler under Linux.
#define M_linux
#define M_linux_gcc
#define M_export
#endif // __linux__


// ******************************************************
// **** LEGG FØLGENDE I EN FIL, sleep.hpp, ELLERNOE *****
// ******************************************************

// For at ikke sleep under Linux skal "blandes" med sleep her,
// legges ting i et eget namespace.
namespace Oxymora {
void sleep(double sec);
}; // Oxymora

#if defined(M_win32)
// #include "win32/sleep.cpp" // Uncomment denne i "virkelig" kode.
#elif defined(M_linux)
// #include "linux/sleep.cpp" // Uncomment denne i "virkelig" kode.
#endif


#ifdef M_win32 // Fjern denne i et "virkelig" eksempel.

// ***********************************************************
// **** LEGG FØLGENDE I EN FIL, win32/sleep.cpp, ELLERNOE ****
// ***********************************************************

namespace Oxymora {
#include <windows.h>
inline void sleep(double sec)
{
 Sleep(static_cast<DWORD>(sec * 1000));
} // sleep
}; // Oxymora

#endif // Fjern denne i et "virkelig" eksempel.


#ifdef M_linux // Fjern denne i et "virkelig" eksempel.

// ***********************************************************
// **** LEGG FØLGENDE I EN FIL, linux/sleep.cpp, ELLERNOE ****
// ***********************************************************

namespace Oxymora {
#include <unistd.h>
inline void sleep(double sec)
{
 usleep(static_cast<unsigned int>(sec * 1000000)); // usleep er visst deprecated btw.
} // sleep
}; // Oxymora

#endif // Fjern denne i et "virkelig" eksempel.



int main(int argc, char* argv[])
{
cout << "2.5 sekunder.." << endl;
Oxymora::sleep(2.5); 
cout << "..forsvannt just nuh." << endl;
return(0);
} // main

 

Jeg har desverre ikke testet denne under Windows, fungerer dette?

Endret av søppel
Skrevet (endret)

// ******************************************************
// **** LEGG FØLGENDE I EN FIL, sleep.hpp, ELLERNOE *****
// ******************************************************

// For at ikke sleep under Linux skal "blandes" med sleep her,
// legges ting i et eget namespace.
namespace Oxymora {
void sleep(double sec);
}; // Oxymora

#if defined(M_win32)
// #include "win32/sleep.cpp" // Uncomment denne i "virkelig" kode.
#elif defined(M_linux)
// #include "linux/sleep.cpp" // Uncomment denne i "virkelig" kode.
#endif


#ifdef M_win32 // Fjern denne i et "virkelig" eksempel.

Her kansje?? Ser ikke noen endif er...:hmm:

Edit: Helt på slutten der altså.

Endret av zirener
Skrevet (endret)

Fikk en annen til å teste koden (MinGW under Windows) - og den fungerer som den skal. Tror du må sjekke om det er gått noe galt under copy/paste-jobben. :]

Endret av søppel

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...