简体   繁体   中英

How do I pass multiple heap arrays to a new thread?

I'm trying to learn how create new threads and run them. I need to pass a few variables into the function that is run on the new thread but I can't find out how to actually pass anything to that new function/thread.

I'm following http://www.devarticles.com/c/a/Cplusplus/Multithreading-in-C/1/ but it only goes through how to pass a single parameter and nothing else.

Side question, do threads work the exact same way as functions do except just on a different thread or is it a little more complicated than just that?

Thanks,

-Faken

The underlying OS allows to pass only one parameter to a thread CreateThread :

HANDLE WINAPI CreateThread(
  __in_opt   LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in       SIZE_T dwStackSize,
  __in       LPTHREAD_START_ROUTINE lpStartAddress,
  __in_opt   LPVOID lpParameter,
  __in       DWORD dwCreationFlags,
  __out_opt  LPDWORD lpThreadId
);

Accordingly the CRT thread create function allows also only one parameter, despite the name being arglist :

uintptr_t _beginthreadex( 
   void *security,
   unsigned stack_size,
   unsigned ( *start_address )( void * ),
   void *arglist,
   unsigned initflag,
   unsigned *thrdaddr 
);

Given these restrictions the usual convention is to pass a pointer to a structure/class with all the arguments. Usually, with C++, one creates a static function that will be the thread handler and passes an instance as the argument:

class Foo
{
  int _someState;
  int _otherState;
  char _moreState[256];

  unsigned DoWork();
  static unsigned ThreadHandler(void*);

public:
  void StartThread();
}

void Foo::StartThread()
{
   _beginthreadex(..., Foo::ThreadHandler, this, ...);
}

unsigned Foo::ThreadHandler(void* arglist)
{
   Foo* pFoo = (Foo*) arglist;
   return pFoo->DoWork();
}

unsigned Foo::DoWork()
{
  // do here all the thread work
}

This is a fairly common idiom and in effect it allows you to pass as much state (=arguments) as needed to the thread.

the single parameter have the size of a pointer. thus, you can fill a structure with as much information as you like and pass a pointer to this structure when creating a new thread, the same as you would do for passing a big structure into a function.

regarding thread execution, it works exactly the same, but it executes in parallel to other thread in your program. so, you have to take great care when accessing a global variable in your thread, because it may be accessed by some other thread at the same time.

boost::thread lets you create threads with multiple parameters, if you want to give that a go. It's an alternative to the Windows thread APIs.

I'll just rephrase Remus Rusanu's answer. If you pass a single parameter, that means you can pass arbitrary size of any data, as many people pointed out. Just send a pointer to a structure that includes what you want to pass. It's really simple. My suggestion is somewhat C-style while Remus Rusanu's C++ style maybe.

struct THREAD_DATA {
  int data1;
  struct MYSTRUCT data2;
  ...
};

void foo()
{
   ...
  // It's important not to pass a stack-allocated local structure.
  // That can be invalidated when this function exits.
  // So, safely allocated with malloc/new.
  THREAD_DATA* data = new THREAD_DATA;
  data->data1 = // put the value you want to pass
  data->data2 = //
  _beginthreadex(..., ThreadWorkerFunc, data, ...);
}


unsigned int CALLBACK ThreadWorkerFunc(void* arg)
{
  THREAD_DATA* data = (THREAD_DATA*)arg;
  ... = data->data1 


  delete data;
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM