Click here to Skip to main content
15,884,388 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
Updated 29-May-10 16:32pm
v2

1 solution

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.
 
Share this answer
 
Comments
Banged Up Abroad 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)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900