how you create threads in loop?

Jul 14, 2009 at 9:12pm
Hi Folks,

Im new to C++, but fairly experienced in Java. In this school project, I for one program I need to create threads in loop, using _beginthreadex(). This means that for each iteration a thread should be called, but all the threads in the loop should run in parallel, not one after the another in sequential order as the loop keeps rolling.

the example:
1
2
3
4
5
6
7
8
9
10
11
12
13
for(int jj = 0; jj < CPU_NO; jj++)
{
hth1 = (HANDLE)_beginthreadex( NULL,         // security
                                   0,            // stack size
                                   ThreadX::ThreadStaticEntryPoint,  // entry-point-function
                                   o1,           // arg list holding the "this" pointer
                                   CREATE_SUSPENDED,  // so we can later call ResumeThread()
                                   &uiThread1ID );

WaitForSingleObject( hth1, INFINITE );

....
}



The code above is not quite complete, but that is the idea. Now, this is what I have, I believe it will not run in parallel, for the reason that the function WaitForSingleObject() will make it wait, and again in the new iteration and so on, basically this looks to me very iterative, as if there was no thread at all, but direct call to the method!!!

You help is very much appreciated, thanx in advance.
Jul 14, 2009 at 9:47pm
Almost there. You should put the HANDLEs returned by _beginthreadex() in an array and call WaitForMultipleObjects() (I think that's its name) outside the loop. Also, don't create the threads suspended. Make them start as soon as possible, instead.
Jul 14, 2009 at 10:01pm
I'm sorry, but Im not so sure, on how to do that? The problem is I would also need to create the threads in array or?
Can you show me a bit of code?

thanx a lot & thanx for your reply!
Jul 14, 2009 at 10:14pm
I'm guessing CPU_NO is a compile-time constant (possibly a preprocessor macro):
1
2
3
4
HANDLE threads[CPU_NO];
//(for starts here) {
    threads[jj]=//(call to _beginthreadex() goes here)
}
Jul 14, 2009 at 10:32pm
Thanks a lot for your elegant solution! I appreciate it!
I managed to make it work, but I would appreciate it if you could have a look if my WaitForMultipleObjects has been correctly set, i.e, if Im sending correctly the handle pointer?? or address?
Im not so sure about the notation in C++ (as said, Im very new to this language)

** One important thing, when Im executing the code (to follow), the printed message is sequential, I dont see any interleaving :(, is my example to simple and stupid? Or how could I modify the method, so that I can make it interleave. In a project that Im about to work, I would need to do this loop for multiple IO (yes, I know about mutexes), and I wanna make sure I'm understanding this thing well?

here is my demo (stupid) code: The CPU macro is = 15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include "MyApp.h"



void MyApp::print()
{
	Sleep(100);
	printf("Hello World\n");
}

int main()
{
	MyApp *o1 = new MyApp();

	 HANDLE threads[CPU];
	 unsigned  uiThread1ID[CPU];

	 for(int i = 0; i < CPU; i++)
	 {
		threads[i] = (HANDLE)_beginthreadex( NULL,         // security
									   0,            // stack size
									   MyApp::ThreadStaticEntryPoint,
									   o1,           // arg list
									   0,
									   &uiThread1ID[i] );
		if ( threads[i] == 0 )
			printf("Failed to create thread 1\n");

		DWORD   dwExitCode;
		GetExitCodeThread( threads[i], &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
		printf( "initial thread %d exit code = %u\n", i, dwExitCode );
	 }

	 WaitForMultipleObjects(CPU, threads, true, INFINITE);
}
Jul 14, 2009 at 10:34pm
ahh pardon my ignorance, the code seems to run fine (interleaves!) when I comment out the Sleep(100) predicate. Of course!
Last edited on Jul 14, 2009 at 10:36pm
Jul 14, 2009 at 10:36pm
Line 34 looks good, but you don't really need lines 30 and 31. If threads[i] is !0 then you know the thread has been started.
Jul 14, 2009 at 10:56pm
yes, you right, I will delete these two lines. Anyways, thanks for your help, you helped me a lot
Jul 14, 2009 at 11:29pm
By plaving around with the code, a new issue has arrised,
see the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

#include "MyApp.h"



void MyApp::print()
{
	for (int i = loopStart; i <= loopEnd; ++i)
    {
      if (i % dispFrequency == 0)
      {
          printf( "%d: i = %d\n", threadName, i );
      }
    }
    printf( "%d thread terminating\n", threadName );
}


void MyApp::setName(int &t)
{
#ifdef WITH_SYNCHRONIZATION
    EnterCriticalSection( &m_CriticalSection );  
#endif
	threadName = t;
#ifdef WITH_SYNCHRONIZATION
    LeaveCriticalSection( &m_CriticalSection );   
#endif
}

int main()
{
	

	HANDLE threads[CPU];
	unsigned  uiThread1ID[CPU];


	for(int i = 0; i < CPU; i++)
	{	
		MyApp *o1 = new MyApp(0, 1000000, 20000);
		o1->setName(i); //critical section

		threads[i] = (HANDLE)_beginthreadex( NULL,         // security
									   0,            // stack size
									   MyApp::ThreadStaticEntryPoint,
									   o1,           // arg list
									   0,
									   &uiThread1ID[i] );
		if ( threads[i] == 0 )
			printf("Failed to create thread 1\n");

		//DWORD   dwExitCode;
		//GetExitCodeThread( threads[i], &dwExitCode );  // should be STILL_ACTIVE = 0x00000103 = 259
		//printf( "initial thread %d exit code = %u\n", i, dwExitCode );		
	
	 }

	 WaitForMultipleObjects(CPU, threads, true, INFINITE);

	 printf("This pain has ended!\n");
}


now when I move o1 pointer declaration outside the for loop, exmp in line 37, then there is no interleaving at all, it is executing only the last loop, cor CPU = 5, I get only the last loop i = 4.
But, with the pointe as it is, it works fine, however, creating so many pointers in the loop, I find it inefficient isn't it ?
Furthermore, with the code as it is, when I add the following lines (in the for loop):
delete o1;
o1 = NULL;

My application is behaving strange, and in Win 7 is reporting an error. Why is that? really strange.

Oh by the way, how does one close HANDLEs in this fashion? In one by one, manual thread creation I used to simply call this
CloseHandle( hth1 );

Or should I still call this in a seperate loop or there is a better way todo so?

thanx

Topic archived. No new replies allowed.