Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: MFC Threading
Assistance would be great.
 
I am just trying to learn multi-threading and the example below should create 10 threads, set them to sleep for a random period of time, wait for them all to trigger they are finished. The ::WaitForMultipleObjects always returns WAIT_TIMEOUT.
 
Can someone explain to me why the ::WaitForMultipleObjects doesn't complete after all the threads are finished?
 
I am sure it is pretty simple for the experts and apologies if it is obvious.
 
Thanks
 

void CtestmultithreadView::OnGo()
{
  // TODO: Add your command handler code here
  AlgoParam param;
  HANDLE    startHandles[10];
  HANDLE    finishedHandles[10];
  UINT seed = (unsigned)time( NULL );
  srand( seed );
  
  for( int i=0; i<10; i++ )
  {
    startHandles[i] = ::CreateEvent( NULL, FALSE, FALSE, NULL );
    finishedHandles[i] = ::CreateEvent( NULL, FALSE, FALSE, NULL );
    double r = ((double)rand()/RAND_MAX)*10000.0;
    param.startHandle = startHandles[i];
    param.finishedHandle = finishedHandles[i];
    param.i = i;
    param.interval = (DWORD)r;
		
    CWinThread* wt = AfxBeginThread( AlgoController, &param, 0, 0, CREATE_SUSPENDED );
    wt->m_bAutoDelete = TRUE;
    wt->ResumeThread();
    ::SetEvent( startHandles[i] );
    ::Sleep(100);
  }
 
  DWORD waitResult;
  ATLTRACE( _T("Waiting for multiple objects\n") );
  waitResult = ::WaitForMultipleObjects( 10, finishedHandles, TRUE, 45000 );
 
  if( waitResult==WAIT_TIMEOUT )
    ATLTRACE( _T("WAIT_TIMEOUT\n") );
  if( waitResult==WAIT_FAILED )
    ATLTRACE( _T("WAIT_FAILED\n") );
  if( waitResult==WAIT_OBJECT_0 )
    ATLTRACE( _T("WAIT_OBJECT_0\n") );
  if( waitResult==WAIT_ABANDONED_0 )
    ATLTRACE( _T("WAIT_ABANDONED_0\n") );
}
 

 
UINT AlgoController( LPVOID pParam )
{
  AlgoParam* param = (AlgoParam*)pParam;
	
  int     threadID = param->i;
  DWORD   interval = param->interval;
	
  ::WaitForSingleObject( param->startHandle, INFINITE );
  ATLTRACE2( _T("Thread id : %d sleeping for %ld\n"), threadID, interval );
  ::Sleep( interval );
  ATLTRACE2( _T("Thread id : %d finished\n"), threadID );
  ::SetEvent( param->finishedHandle );
	
  //	AfxEndThread( 0, FALSE );
  return 0L;
}
Posted 29-May-10 15:28pm
Edited 29-May-10 17:32pm
v2

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Banged Up Abroad wrote:
AlgoParam param;
 
// snip ...
 
param.startHandle = startHandles[i];
param.finishedHandle = finishedHandles[i];
param.i = i;
param.interval = (DWORD)r;
 
CWinThread* wt = AfxBeginThread( AlgoController, &param, 0, 0, CREATE_SUSPENDED );

Might it have something to do with a reference to the same param object being sent to each thread? They'd all be setting the same event when they get to the end of the function.
 
This might be fixed if you created a new object for each thread function's parameter. Alternatively you could just WaitForMultipleObjects on the thread handles instead of explicitly creating new events for that.
  Permalink  
Comments
Banged Up Abroad at 30-May-10 9:33am
   
Yep....that'd be it! Thanks Jimmanuel much appreciated
Created AlgoParam param[10] and modified the code accordingly and worked first go.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 240
1 Kamal Rocks 184
2 PIEBALDconsult 150
3 BillWoodruff 148
4 Jochen Arndt 135
0 OriginalGriff 5,695
1 DamithSL 4,506
2 Maciej Los 4,007
3 Kornfeld Eliyahu Peter 3,480
4 Sergey Alexandrovich Kryukov 3,190


Advertise | Privacy | Mobile
Web02 | 2.8.141216.1 | Last Updated 30 May 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100