jajajalla Skrevet 18. desember 2004 Skrevet 18. desember 2004 (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 18. desember 2004 av jajajalla
abcd423417984 Skrevet 18. desember 2004 Skrevet 18. desember 2004 funksjonen må være static for at det skal virke. ulempen er at da vil enhver fordel med å bruke klasser forsvinne.
jajajalla Skrevet 18. desember 2004 Forfatter Skrevet 18. desember 2004 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å?
søppel Skrevet 18. desember 2004 Skrevet 18. desember 2004 (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 18. desember 2004 av søppel
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av søppel
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 For å kalle Sleep(mill.sec.) må man vel include <windows.h>? Eller?
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av søppel
jajajalla Skrevet 19. desember 2004 Forfatter Skrevet 19. desember 2004 Tusen takk for svar. Dette virker overkommelig!
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 Finnes det noe tilsvarende som en Sleep(mill.sec) i linux? (Jeg planlegger å skifte OS, så jeg vil ikke vli windows.h avhengig )
smegpot Skrevet 19. desember 2004 Skrevet 19. desember 2004 Finnes det noe tilsvarende som en Sleep(mill.sec) i linux? (Jeg planlegger å skifte OS, så jeg vil ikke vli windows.h avhengig ) void usleep(unsigned long usec) ...er vel en mulighet. Parameteret er microsekunder. Smeg out...
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av zirener
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av søppel
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 Ja takk, hvis du gidder ville jeg satt pris på et konkret eksempel.
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av søppel
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 Funker nesten. Får bare en error: 1 C:\Dev-Cpp\bin\sleep.cpp:18 unterminated #ifdef C:\Dev-Cpp\bin\Makefile.win [Build Error] [sleep.o] Error 1
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (endret) Hm, jeg ser ingen #ifdefs som mangler tilhørende #endif sånn i farta her .. Endret 19. desember 2004 av søppel
Dead_Rabbit Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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... Edit: Helt på slutten der altså. Endret 19. desember 2004 av zirener
søppel Skrevet 19. desember 2004 Skrevet 19. desember 2004 (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 19. desember 2004 av søppel
Anbefalte innlegg
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 kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå