Showing posts with label threads. Show all posts
Showing posts with label threads. Show all posts

Thursday, 17 September 2009

Arbitrarily turn static functions into individual threads

There's a lot of routines that are supposed to run "behind the scene", accomplishing repetitive and constant taks. For instance, in 3D engine the movements should be time-based, so that things behave the same way indipendently from the underlying architecture. We could define a class that "checks the clock" and computes the "amount of changes" to do in the scene. Our observers - that is a geometry transformers or a physic routine - simply "emphasize" their values proportionally to the elapsed time.

The best way for keeping "background duties classes" and the main engine separate is the use of threads. I already used them in the past, but in a statical way. This time, I wanted some kind of "abstract thread converter" which takes a pointer to a static function and turns it into a thread on its own.

Here comes some brief snippet. First of all, I defined a PLTthread class:

class PLTthread {
public:
  // empty constructor 
  PLTthread() {};
  // links the specified function, using specified  parameters
  void LinkFunction(static DWORD WINAPI fun, void* dwThrdParam = 0); 
private:
  // handler for the created thread
  HANDLE ThreadHandler;
  // thread ID
  DWORD dwThreadId;
}
Many additional methods could be created for handling thread's execution, but I wanna keep this example straightforward: you'll just pass a static method and it will start on its own. The actual code:

void PLTthread::LinkFunction(static DWORD WINAPI fun, void* dwThrdParam) {
    this->ThreadHandler = CreateThread(NULL, 0,
                            (LPTHREAD_START_ROUTINE)fun, &dwThrdParam,
                            0, &this->dwThreadId);  
    }
That's it. Now you can instantiate a PLTthread class and send it your function, casting it as DWORD.

Threads are a bit tricky, MFC are a pain in the ass; everything is a complete mess if you use to think object oriented. But this facility helps me a lot.

Friday, 15 September 2006

Redo from start - Multithreading in C++ && OO

The Win32 API for threading have been designed for C, therefore they don't fit very well the use inside classes. In highest-level languages (such as Java), threading is implementable simply extending the Thread class and overriding the run() method. In C++, things are slighly more complex, expecially because it is impossible to reach classes methods from an isolated static function.

So, it is necessary... once again... pull up socks and use the _beginthreadex API.


class Threader
{
  public:

  // this is the method called by main
  static unsigned __stdcall ThreadStaticEntryPoint(void * pThis)
  {
    Threader * pthX = (Threader *) pThis;
    pthX -> EntryPoint();
  }

  // this is the real thread method
  void EntryPoint()
  {
    // put thread's job here
  }
};

int main() {

  unsigned int uiThread1ID;

  // let's call thread. the NULL are useful parameters, but not obbligatory
  HANDLE hth1 = (HANDLE)_beginthreadex( NULL, 0, Threader::ThreadStaticEntryPoint, NULL, NULL, &uiThread1ID );

}


You can find an excellent and more extended explanation on Code Project.

Don't forget to include process.h!