Thomas Sampson

Basic C++ Multi Threading

Leave a comment

This is a quick post for anyone who wants to get up and running with multiple threads quickly in C++. I have been doing a fair amount of python programming recently, in particular a 2D networked game, and have realised how useful distributing independent tasks across multiple threads can be. After looking into how best and easiest to translate this experience from python and get a working example going in C++, I am posting the following code which I will attempt to explain beneath.

#include <iostream>
#include <windows.h>
#include <conio.h>
using std::cout;
using std::endl;

int thread_count(0);
int main_thread_count(0);

DWORD_PTR WINAPI threadFunction(void* p)
{
  ++thread_count;
  while(true)
  {
    cout << "Thread "<<(unsigned int)p<<" busy...."<<endl;
  }

  return 0;
}

int main(int argc, char* argv[])
{
  cout << "Starting...."<<endl;

  //Gather processor info
  SYSTEM_INFO si={0,0};
  GetSystemInfo(&si);
  const unsigned int num_cores(si.dwNumberOfProcessors);

  cout << num_cores << " Cores detected"<<endl;

  //Set up thread handles
  HANDLE* thread_handle=new HANDLE[num_cores];
  ZeroMemory(thread_handle,sizeof(HANDLE)*num_cores);

  for(unsigned int core(0);core<num_cores; ++core)
  {
    DWORD_PTR rqd;
    thread_handle[core]=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadFunction, (LPVOID)core,     NULL, &rqd);
  }

  cout << "Main thread reached"<<endl;

  std::cin.get();
  std::cin.get();

  //Terminate threads
  DWORD exit_code( 0);
  for(unsigned int core(0);core<num_cores; ++core)
  {
    TerminateThread(thread_handle[core],exit_code);
  }

  delete[] thread_handle;

  return 0;
}

Quick run through!

How many threads to use? A good question! When you first come across threading you may believe it is the answer to every problem and spawn threads in abundance! In the example above I have used the GetSystemInfo() call to gather information about the available CPU’s, then use this information to spawn a thread per cpu. The threads get spawned in the same virtual address space as the parent process and are allocated a stack space of 1mb by default (although this is tweakable). For this reason you could essentially spawn as many threads as you like up to the virtual memory limit of the system, but a separate thread per cpu is usually prefered, and is the recommended approach over at msdn.

Spawning a thread essentially means running some previously declared function in parallel to main, and in this example each new thread runs threadFunction(). In real life this is seemingly useless, you would usually have a specific function and task for each thread such as rendering particles, or listening out on a socket for incoming connections.

Thread handles are used to allow you to make reference and work with your threads after you have created them, for a comprehensive list of thread operations see here. Be sure to use the thread handles to TerminateThread() on each of your threads before exiting the parent process.

Advertisements

Author: tomtech999

I have recently graduated with a 1st class degree in MComp Games Software Development at Sheffield Hallam University, focusing primarily on application development in C++, with experience in graphics programming, scripting languages, DVCS/VCS and web technology. In my spare time I enjoy Drumming, Reading and Snowboarding!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s