CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Hybrid View

  1. #1
    Join Date
    Aug 2008
    Posts
    21

    Question Question for worker threads

    Hi all,

    I created three worker threads to work for two simultaneous runs at each time and one control (main) thread. The main thread is waiting while two (sub) thread are processing. Then,once the main get any finish signal from those two, it check if it needs to create another run or to stop. The user specify the limit count to stop. I don't want to stop the loop in the main thread unless both two threads finished their runs. Therefore, I made the main thread 'while' loop to go on til both finish.

    I don't know it is right to do for running 2 threads at the same time. (actually 3 including main thread).

    The problem is it works well sometimes and it doesn't.
    For example of problem, the user set 4 runs. Run1 and Run2 start together. Run1 finish first but Run2 stil running. Run1 needs to do 'third' process by creating new thread from main thread. It doesn't do that process and stops. Run2 keeps on running till the current process finishes and go on with third process.
    Finally, run2 finish running til the end (forth run) and the loop in main thread never gets out. Meaning that the whole process "hanging" there. After I check the 'while' loop is going on and on. Why is it that way?

    I think the logical variables are not stable or something is very wrong. Sometimes, it goes very smoothly.

    Pls help me. Thanks in advance.

    The codes are as following:

    Code:
    CEvent Run1, Run2, EContinue;
    
    UINT SubThread1(LPVOID param)
    {
    //run the process 1
    
    //........
    
    Run1.SetEvent();
    
    return 0;
    
    }
    
    UINT SubThread2(LPVOID param)
    {
    //run the process 2
    
    //........
    
    Run2.SetEvent();
    
    return 0;
    
    }
    
    
    UINT MainThread(LPVOID param)
    {
                    BOOL bRestart1 = FALSE;
    	BOOL bRestart2 = FALSE;
    	BOOL Continue = FALSE;
    	BOOL bRunOn;
    
    	HANDLE hSub1, hSub2;
    
    	CWinThread *pSub1 = NULL;
    	CWinThread *pSub2 = NULL;
    		
    	do
    	{		
    
    		if( (!Continue) && (!bRestart1) )
    		{
    			Run1.ResetEvent();
    			pSub1 = ::AfxBeginThread(SubThread1, param, THREAD_PRIORITY_NORMAL,
    											0, CREATE_SUSPENDED);
    			hSub1 = pSub1->m_hThread;
    			bRestart1 = TRUE;
    
    			::ResumeThread (hSub1);
    		}
    
    		::Sleep(100);
    
    		if( (!Continue) && (!bRestart2) )
    		{
    			Run2.ResetEvent();
    			pSub2 = ::AfxBeginThread(SubThread2, param, THREAD_PRIORITY_NORMAL,
    											0, CREATE_SUSPENDED);
    			hSub2 = pSub2->m_hThread;
    			bRestart2 = TRUE;
    
    			::ResumeThread (hSub2);
    		}
    
    		::Sleep(100);
    		
    		if(bRestart1)
    		{
    			DWORD run1 = ::WaitForSingleObject( Run1.m_hObject, 0 );
    			
    			if(run1 == WAIT_OBJECT_0)
    			{
    				CloseHandle(hSub1);
    				pSub1 = NULL;
    				bRestart1 = FALSE;
    				::Sleep(100);
    			}
    		}
    
    		::Sleep(100);
    	  
    		if(bRestart2)
    		{
    			DWORD run2 = ::WaitForSingleObject( Run2.m_hObject, 0 );
    			if(run2 == WAIT_OBJECT_0)
    			{
    				CloseHandle(hSub2);
    				pSub2 = NULL;
    				bRestart2 = FALSE;
    				::Sleep(100);
    			}
    		}
    		::Sleep(100);
    		
    			
    		if ( (!bRestart1) || (!bRestart2) )
    		{
    			::PostMessage((HWND)param, WM_ACONTINUE, 0, 0);
                                                     //go to the 'acontinue' function to monitor counts.
    			::Sleep(2000);
    		
    			DWORD StopLoop = ::WaitForSingleObject(EContinue.m_hObject, 0);
                                                //set the event when the limit is hit
    			if(StopLoop == WAIT_OBJECT_0)
    			{
    				Continue = TRUE;
    				::Sleep(100);
    			}
    			else Continue = FALSE;
    							
    		}
    		
    		::Sleep(100);
    
    		if(!Continue) 
    		{
    			bRunOn = TRUE;
    		}
    		else
    		{
    			if(bRestart1 || bRestart2) bRunOn = TRUE;
    			else
    			{
    				bRunOn = FALSE;
    				::Sleep(1000);
    
    			}
    		}
    		::Sleep(100);
    		
    			
    	}
    	while(bRunOn);//to signal to continue
    
    
    	return 0;
    }
    
    LRESULT MyDlg::AContinue(WPARAM wParam, LPARAM lParam)
    { 
           //count is initialise when start running
           
           if(count == limit) EContinue.SetEvent();
           count++;
        
           return 0;
    }
    
    void MyDlg::ClickButton()
    { 
          HWND hWnd = GetSafeHwnd();
    
          AfxBeginThread(MainThread, hWnd, THREAD_PRIORITY_ABOVE_NORMAL);
           
    }
    Last edited by nankyu; November 12th, 2008 at 02:26 AM.

  2. #2
    Join Date
    Jun 2002
    Location
    Stockholm, Sweden
    Posts
    1,641

    Re: Question for worker threads

    Hard to say, but CloseHandle is not needed with CWinThread - it is closed automatically if you use autodelete.
    And your use of events is superfluous. You can wait directly on the thread handle instead, but then you have to turn off autodelete.
    Code:
    pSub1 = ::AfxBeginThread(SubThread1, param, THREAD_PRIORITY_NORMAL,
    0, CREATE_SUSPENDED);
    pSub1->m_bAutoDelete=FALSE;
    ...
    pSub1->ResumeThread();
    ...
    WaitForSingleObject(pSub1->m_hThread, 0);
    ...
    delete pSub1;
    Nobody cares how it works as long as it works

  3. #3
    Join Date
    Aug 2008
    Posts
    21

    Re: Question for worker threads

    Quote Originally Posted by zerver View Post
    Hard to say, but CloseHandle is not needed with CWinThread - it is closed automatically if you use autodelete.
    And your use of events is superfluous. You can wait directly on the thread handle instead, but then you have to turn off autodelete.
    Thanks for your reply. zerver. Yes, I used many events and I think may be they are causing me this problem. I will try as you told me and post my outcomes and question if any.

    nankyu
    Last edited by nankyu; November 12th, 2008 at 08:04 PM.

  4. #4
    Join Date
    Aug 2008
    Posts
    21

    Re: Question for worker threads

    Hi,

    Zerver, your post helped me to solve the problem. Thanks alot.
    Since I used many events and I checked its object's status to control the loop. Now I used few events and no problem occurs.
    I think after 'SetEvent()' call for a event, I can see that its object equals to 'WAIT_OBJECT_0'. But as it was looping and called for 'SetEvent()' certain times, its object changed and not equal to 'WAIT_OBJECT_0' anymore (I think that is a problem).

    nankyu

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured