Sorry for my dumness but i can''t figure out what i have to do at all - define my function static? is that all?
How to start a thread in Win32 C++
Define it static, then pass the "this" pointer to the thread function. Then you can cast the void pointer you get in the thread function to a pointer to your class and call whatever you want.
What I normally do is have a static function called StaticThreadProc, then delegate to the non-static ThreadProc.
Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
What I normally do is have a static function called StaticThreadProc, then delegate to the non-static ThreadProc.
Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
Actually, beginthreadex is preferred over beginthread. Here is a macro that you might find helpful. You might also find these urls informative.
Edit: for some reason the source tags are mangling the macro. Viewing the page source indicates the macro remains in place, albeit damaged. Given the overwhelming amount of code this macro is moot anyway. However, those urls are worth reviewing.
"Beautiful maiden," answered Candide, "when a man is in love, is jealous, and has been flogged by the Inquisition, he becomes lost to all reflection."
[edited by - lessbread on December 6, 2002 4:59:35 PM]
/* createthreadex.h */#ifndef CREATETHREADEX_H_#define CREATETHREADEX_H_#pragma once#include <process.h>/* ---------------------------------------------------------------------------Q132078: "How to Use _beginthreadex() and _endthreadex()"http://support.microsoft.com/default.aspx?scid=KB;EN-US;q132078& When developing a multithreaded Win32-based application with Visual C++, you need to use the CRT thread functions to create any threads that call CRT functions. To create and terminate threads, use either _beginthread() and _endthread() or _beginthreadex() and _endthreadex(). If you use the Win32 APIs CreateThread() and ExitThread() instead, some of the CRT functions used in the thread will not work. You need to use the CRT functions to both create and end the threads or you lose the memory that the CRT allocates for the thread. In addition to preventing memory leaks, using _beginthreadex places a structured exception handling frame around the thread function so that the signal function and floating point exceptions work correctly.See also:Win32 Q&A, MSJ July 1999http://www.microsoft.com/msj/0799/win32/win320799.htmWin32 Q&A, MSJ October 1999http://www.microsoft.com/msj/1099/win32/win321099.htmHere are two macro overlays to facilatate this usage:Note:The thread that uses CreateThreadEx to launch new threads shouldalso dispose of any generated thread handle using CloseHandle. HANDLE MyThread = CreateThreadEx(...); ... CloseHandle(MyThread);--------------------------------------------------------------------------- */typedef unsigned (__stdcall *StartAddressT)(void*);#define CreateThreadEx( lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId ) ( (HANDLE) _beginthreadex( (void *) (lpThreadAttributes), (unsigned int) (dwStackSize), (StartAddressT) (lpStartAddress), (void *) (lpParameter), (unsigned int) (dwCreationFlags), (unsigned int *) (lpThreadId) ) )#define ExitThreadEx(dwExitCode) _endthreadex((unsigned int)dwExitCode)#endif /* CREATETHREADEX_H_ */
Edit: for some reason the source tags are mangling the macro. Viewing the page source indicates the macro remains in place, albeit damaged. Given the overwhelming amount of code this macro is moot anyway. However, those urls are worth reviewing.
"Beautiful maiden," answered Candide, "when a man is in love, is jealous, and has been flogged by the Inquisition, he becomes lost to all reflection."
[edited by - lessbread on December 6, 2002 4:59:35 PM]
Thought I''d add that the Boost Library (www.boost.org) has a pretty nice, clean, multithreading and synchronisation section.
Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
// The classclass ThreadedClass{public: ThreadedClass(); static DWORD WINAPI threadInit( void * tc_arg ); void someMethod();}; DWORD WINAPI ThreadedClass::threadInit( void * tc_arg ){ ThreadedClass * tc = reinterpret_cast<ThreadedClass *>(tc_arg); tc->someMethod(); // function dispatch} // in some function somewhere{ ... ThreadedClass tc; DWORD id; HANDLE hThread = CreateThread( NULL, 0, ThreadedClass::threadInit, &tc, 0, &id ); ...}
thanks for the code supply - it would be morning over there till i managed it on my own - it i ever would have.
thank you
thank you
I would do something like the -- untested -- code that follows:
#include <iostream>#include <memory>#define NOMINMAX#include <windows.h>struct Foo{ DWORD ThreadProc1(void*) { std::cout << "Inside Foo::ThreadProc1" << std::endl; return 0; } DWORD ThreadProc2(void*) { std::cout << "Inside Foo::ThreadProc2" << std::endl; return 0; }};struct Bar{ DWORD ThreadProc(void*) { std::cout << "Inside Bar::ThreadProc1" << std::endl; return 0; }};template <typename T>struct ThreadInfo{ typedef T class_type; typedef DWORD(T::* function_type)(void*); T* obj; function_type function; void* data; ThreadInfo(class_type* f, function_type fp, void* d) : obj(f), function(fp), data(d) {}};template <typename T>DWORD WINAPI ThreadDispatch(void* data){ std::auto_ptr<ThreadInfo<T> > ti(static_cast<ThreadInfo<T>*>(data)); return ((ti->obj)->*(ti->function))(ti->data);}template <typename T>HANDLE CreateThread(SECURITY_ATTRIBUTES* sa, SIZE_T stackSize, T* object, DWORD(T::* threadRoutine)(void*), void* parameters, DWORD creationFlags, DWORD* tid){ std::auto_ptr<ThreadInfo<T> > ti(new ThreadInfo<T>(object, threadRoutine, parameters)); HANDLE rv = CreateThread(sa, stackSize, ThreadDispatch<T>, static_cast<void*>(ti.get()), creationFlags, tid); if(NULL != rv) { ti.release(); } return rv;}// In practice, you''ll normally not need all the parameters, so a convenience overload is provided.template <typename T>HANDLE CreateThread(T* object, DWORD(T::* threadRoutine)(void*), void* parameters){ return CreateThread(NULL, 0, object, threadRoutine, parameters, 0, NULL);}int main(){ using namespace std; auto_ptr<Foo> foo(new Foo); HANDLE thread = CreateThread(foo.get(), &Foo::ThreadProc1, NULL); WaitForSingleObject(thread, INFINITE); CloseHandle(thread); auto_ptr<Bar> bar(new Bar); thread = CreateThread(bar.get(), &Bar::ThreadProc, NULL); WaitForSingleObject(thread, INFINITE); CloseHandle(thread);}
If you''re a generic kinda guy, this helper-class lets you turn any class method into a thread.
Example use:
A single class can have more than one type of thread this way.
template <typename ParentClass>class Thread { public: Thread() : m_hThread(INVALID_HANDLE_VALUE), m_dwID(0), m_pParentClass(0) { } ~Thread() { if(IsValid()) { if(!IsTerminated()) { ASSERTMSG(0, "Thread object being destroyed prior to thread termination!\n"); Exit(); } CloseHandle(m_hThread); m_hThread=INVALID_HANDLE_VALUE; } } HANDLE handle(){return m_hThread;} typedef UINT (ParentClass::*MethodProc)(void); typedef Event<false, false> tyEvent; tyEvent m_evExit; bool Create(ParentClass* pThis, MethodProc pThreadMethod, const char* const name = 0) { ASSERTMSG(INVALID_HANDLE_VALUE==m_hThread, "Don''t call Thread<>::Create without calling Close!"); if(INVALID_HANDLE_VALUE!=m_hThread) return false; m_evExit.Reset(); m_pParentClass = pThis; m_pMethodProc = pThreadMethod; //m_hThread = (HANDLE)_beginthreadex(NULL, 0, &DefaultProc, this, 0, (UINT*)&m_dwID); m_hThread = CreateThread(NULL, NULL, &DefaultProc, this, 0, &m_dwID); if( (0==m_hThread) || (INVALID_HANDLE_VALUE==m_hThread) ) return false; else return true; } bool Exit(DWORD dwTime_ms=5000) { Lock<> AutoLock(m_csLock); if(IsValid()) { m_evExit.Signal(); if(WaitForTermination(dwTime_ms)) return true; else { char szMsg[128]; strcpy(szMsg, "* "); //strcpy(&szMsg[strlen(szMsg)], typeid(*this).name()); strcpy(&szMsg[strlen(szMsg)], "Thread<> "); strcpy(&szMsg[strlen(szMsg)], " forcefully terminated\n"); Debug::Console.Out(szMsg); return Terminate(); } } else return true; } bool Close() { assert(INVALID_HANDLE_VALUE!=m_hThread); ASSERTMSG(IsTerminated(), "Terminate the thread prior to closing it''s handle!"); if(!IsTerminated()) Exit(5000); if(CloseHandle(m_hThread)) { m_hThread=INVALID_HANDLE_VALUE; return true; } else return false; } bool IsValid() {return(INVALID_HANDLE_VALUE!=m_hThread);} bool IsTerminated() {return (WAIT_OBJECT_0==WaitForSingleObject(m_hThread, 0));} bool IsRunning() {return (WAIT_TIMEOUT==WaitForSingleObject(m_hThread, 0));} BOOL Suspend() { assert(INVALID_HANDLE_VALUE!=m_hThread); return SuspendThread(m_hThread); } BOOL Resume() { assert(INVALID_HANDLE_VALUE!=m_hThread); return ResumeThread(m_hThread); } enum ePriority { TimeCritical = THREAD_PRIORITY_TIME_CRITICAL, Highest = THREAD_PRIORITY_HIGHEST, AboveNormal = THREAD_PRIORITY_ABOVE_NORMAL, Normal = THREAD_PRIORITY_NORMAL, BelowNormal = THREAD_PRIORITY_BELOW_NORMAL, Lowest = THREAD_PRIORITY_LOWEST, Idle = THREAD_PRIORITY_IDLE }; BOOL SetPriority(ePriority priority) { assert(INVALID_HANDLE_VALUE!=m_hThread); return SetThreadPriority(m_hThread, priority); } bool WaitForTermination(DWORD dwTime_ms=INFINITE) { assert(INVALID_HANDLE_VALUE!=m_hThread); return(WAIT_OBJECT_0==WaitForSingleObject(m_hThread, dwTime_ms)); } protected: static unsigned long __stdcall DefaultProc(void* pv) { assert(pv); Sleep(10); return reinterpret_cast<Thread*>(pv)->Run(); } UINT Run() { try { assert(m_pParentClass); assert(this); assert(m_pMethodProc); if(m_pParentClass) { UINT x = (m_pParentClass->*m_pMethodProc)(); return x; } } catch(...) { ASSERTMSG(0, "Thread threw an uncaught exception"); throw; } return -3; } MethodProc m_pMethodProc; ParentClass* m_pParentClass; bool Terminate() { Lock<CriticalSection> AutoLock(m_csLock); if(INVALID_HANDLE_VALUE!=m_hThread) if(TerminateThread(m_hThread, -42)) return true; else return false; else return true; } protected: volatile HANDLE m_hThread; DWORD m_dwID; CriticalSection m_csLock; };
Example use:
struct SomeClass{Thread thread;UINT Run();void Initialize() { BOOL bResult = this->thread.Create(this, Run); }void Shutdown() { this->thread.Exit(); }};UINT SomeClass::Run(){while(!this->thread.m_evExit.WaitFor(sleepTime_ms)) { //Thread code goes here }}
A single class can have more than one type of thread this way.
now it is running and everything is fine.
am I right if I think I just have to give an other class in that last pointer to run a function from that class...
I just want to write some code down to make it threaded (processing input) i already coded it i an class and if I could now make it run with just switching the pointer/function that is called it would be greate.
anyway thank you - you guy''s realy help me a lot!
I hope I can help people with what i have learned today too someday!
am I right if I think I just have to give an other class in that last pointer to run a function from that class...
I just want to write some code down to make it threaded (processing input) i already coded it i an class and if I could now make it run with just switching the pointer/function that is called it would be greate.
anyway thank you - you guy''s realy help me a lot!
I hope I can help people with what i have learned today too someday!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement