Click here to Skip to main content
11,496,146 members (822 online)
The site is currently in read-only mode for maintenance. Posting of new items will be available again shortly.
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

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 Dnyaneshwar@Pune 692
1 RyanDev 230
2 CHill60 163
3 Sascha Lefèvre 145
4 Sergey Alexandrovich Kryukov 124
0 Sergey Alexandrovich Kryukov 10,401
1 OriginalGriff 8,910
2 Sascha Lefèvre 3,899
3 Maciej Los 3,422
4 Richard Deeming 2,600


Advertise | Privacy | Mobile
Web03 | 2.8.150520.1 | Last Updated 30 May 2010
Copyright © CodeProject, 1999-2015
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