?
Solved

Multithreading, WaitForMultipleObjects and Variable Number of Threads

Posted on 2009-12-17
11
Medium Priority
?
1,091 Views
Last Modified: 2013-12-14
I am writing a multithreaded application in C using MSVS 2008.  Normally, to create several threads you would write the following lines of code:

HANDLE hThrds[3];

hThrds[0] = (HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID);
hThrds[1] = (HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID);
hThrds[2] = (HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID);

We would then wait for the threads to finish with the following line of code:

WaitForMultipleObjects (3, hThrds, TRUE, INFINITE);

My question is what do we do if we do not know how many threads we will create till runtime?  For example, suppose we still had the declaration

HANDLE hThrds[3];

But only created one thread.

hThrds[0] = (HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID);

Then the line

WaitForMultipleObjects (3, hThrds, TRUE, INFINITE);

will return an error since the other two thread handles are invalid.  If I put

WaitForMultipleObjects (1, hThrds, TRUE, INFINITE);

instead (because only one thread was created), this causes an error as well.  Therefore, how can I store the handles to a variable number of threads and then use WaitForMultipleObjects?  Or is there another solution that you might suggest?

FYI - I tried using calloc and malloc to create hThrds dynamically,

hThrds = calloc (3, sizeof (HANDLE));

but this did not work since HANDLE does not have a size.
0
Comment
Question by:jtrades
  • 3
  • 3
  • 2
  • +3
11 Comments
 
LVL 8

Expert Comment

by:milindsm
ID: 26077762
Declare a class for thread object. It will have a linked list of thread handles. You may need to override [] operator. Also maintain the current thread count as a static member of that class. See if this works...!!!
0
 

Expert Comment

by:niceprogrammer
ID: 26077968
do like this:


for(i = 0; i<3 ; i++)
{
WaitForMultipleObjects (i, hThrds, TRUE, INFINITE);  
}

Open in new window

0
 

Author Comment

by:jtrades
ID: 26078027
I was able to use the following line

HANDLE *hThrds = new HANDLE[numThreads];

where numThreads is declared at runtime.  It compiled and worked.  Does anyone see any problems with this method?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:milindsm
ID: 26078059
But as you said, this number might vary.... right????
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26078140
I prefer to declare this array of handles as:
HANDLE arrHandles[MAX_POSSIBLE_NUMBER_OF_HANDLES];
but this array should contain only with the valid handles in the beginning and so, for WaitForMultipleObjects I pass the valid number of the objects to wait for.
For example the maximal number of handles can be 8, but now I need only 4, so the first 4 elements of this array are valid handles and 4 is the parameter for WaitForMultipleObjects.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 26078523
Why not just use a standard vector to solve your problem?
http://www.cplusplus.com/reference/stl/vector/

std::vector<HANDLE> vh;
vh.push_back((HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID));
... as many as you like
vh.push_back((HANDLE)_beginthreadex (NULL, 0, &ThreadFunction, &params, 0, &threadID));
WaitForMultipleObjects (vh.size(), &vh[0], TRUE, INFINITE);

Open in new window

0
 
LVL 3

Accepted Solution

by:
Greg_Arnold earned 2000 total points
ID: 26081913
Everyone, he's writing in C so suggeting classes and new() isn't going to work.  I tried

HANDLE *h = malloc(sizeof(HANDLE));

in VS 2005 and it worked for me.  Could you post what error you're getting when you try it?
0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26082258
The error is simple - WaitForMultipleObjects does not wait.
So again, as the most people have said, in the beginning of the array of handles should be only valid handles; the first parameter for WaitForMultipleObject is the number of the valid handles in this array.
Add a stop event handle (a valid HANDLE created by CreateEvent) as the first array element. So even if one thread was created, you call WaitForMultipleObjects and everything works fine. In such cases you always may have few events - for example, pause and continue, stop, begin, etc.

0
 
LVL 33

Expert Comment

by:pgnatyuk
ID: 26082289
@Greg_Arnold: it is, probably, just a typo:
HANDLE *h = malloc(sizeof(HANDLE));
0
 

Author Comment

by:jtrades
ID: 26082981
Took Greg's suggestion with some modifications

HANDLE *h = (HANDLE *) calloc(thread_cnt, sizeof(HANDLE));

This seems to work fine.  Thanks for everyone's help.
0
 

Author Closing Comment

by:jtrades
ID: 31667644
Just need to cast the pointer from calloc/malloc to the type you need.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question