×÷ÕߣºArman Z. Sahakyan¡¡À´Ô´£º²©¿ÍÔ° ¡¡ ¿áÇÚÍøÊÕ¼¯¡¡2008-06-27

ÕªÒª
¡¡¡¡ÔÚÏß³ÌÖ´Ðйý³ÌÖУ¬»ò¶à»òÉÙ¶¼ÐèÒª±Ë´Ë½»»¥£¬ÕâÖÖ½»»¥ÐÐΪÓжàÖÖÐÎʽºÍÀàÐÍ¡£ÀýÈ磬һ¸öÏß³ÌÔÚÖ´ÐÐÍêËü±»¸³ÓèµÄÈÎÎñºó£¬Í¨ÖªÁíÒ»¸öÏß³ÌÈÎÎñÒѾ­Íê³É¡£È»ºóµÚ¶þ¸öÏß³Ì×ö¿ªÊ¼Ê£ÏµĹ¤×÷¡£ÏÂÊö¶ÔÏóÊÇÓÃÀ´Ö§³Öͬ²½µÄ£º1)ÐźÅÁ¿£»2)»¥³âËø£»3)¹Ø¼üÇøÓò£»4)ʼþ
 
 

¼ò½é

±¾ÎÄ̽ÌÖ»ù±¾µÄͬ²½¸ÅÄ²¢Êµ¼Ê¶¯ÊÖ°ïÖúÐÂÊÖÕÆÎÕ¶àÏ̱߳à³Ì¡£±¾ÎĵÄÖØµãÔÚ¸÷ÖÖͬ²½¼¼ÇÉ¡£

»ù±¾¸ÅÄî

ÔÚÏß³ÌÖ´Ðйý³ÌÖУ¬»ò¶à»òÉÙ¶¼ÐèÒª±Ë´Ë½»»¥£¬ÕâÖÖ½»»¥ÐÐΪÓжàÖÖÐÎʽºÍÀàÐÍ¡£ÀýÈ磬һ¸öÏß³ÌÔÚÖ´ÐÐÍêËü±»¸³ÓèµÄÈÎÎñºó£¬Í¨ÖªÁíÒ»¸öÏß³ÌÈÎÎñÒѾ­Íê³É¡£È»ºóµÚ¶þ¸öÏß³Ì×ö¿ªÊ¼Ê£ÏµĹ¤×÷¡£

ÏÂÊö¶ÔÏóÊÇÓÃÀ´Ö§³Öͬ²½µÄ£º

1)ÐźÅÁ¿

2)»¥³âËø

3)¹Ø¼üÇøÓò

4)ʼþ

ÿ¸ö¶ÔÏó¶¼Óв»Í¬µÄÄ¿µÄºÍÓÃ;£¬µ«»ù±¾Ä¿µÄ¶¼ÊÇÖ§³Öͬ²½¡£µ±È»»¹ÓÐÆäËû¿ÉÒÔÓÃÀ´Í¬²½µÄ¶ÔÏ󣬱ÈÈç½ø³ÌºÍÏ̶߳ÔÏ󡣺óÁ½ÕßµÄʹÓÃÓɳÌÐòÔ±¾ö¶¨£¬±ÈÈç˵ÅжÏÒ»¸ö¸ø¶¨½ø³Ì»òÏß³ÌÊÇ·ñÖ´ÐÐÍê±ÏΪÁËʹÓýø³ÌºÍÏ̶߳ÔÏóÀ´½øÐÐͬ²½£¬ÎÒÃÇÒ»°ãʹÓÃWait*º¯Êý£¬ÔÚʹÓÃÕâЩº¯Êýʱ£¬ÄãÓ¦µ±ÖªµÀÒ»¸ö¸ÅÄÈκα»×÷Ϊͬ²½¶ÔÏóµÄÄں˶ÔÏ󣨹ؼüÇøÓò³ýÍ⣩¶¼´¦ÓÚÁ½ÖÖ״̬֮һ£ºÍ¨Öª×´Ì¬ºÍδ֪ͨ״̬¡£ÀýÈ磬½ø³ÌºÍÏ̶߳ÔÏ󣬵±ËûÃÇ¿ªÊ¼Ö´ÐÐʱ´¦ÓÚδ֪ͨ״̬£¬¶øµ±ËûÃÇÖ´ÐÐÍê±Ïʱ´¦ÓÚ֪ͨ״̬£¬

ΪÁËÅжÏÒ»¸ö¸ø¶¨½ø³Ì»òÏß³ÌÊÇ·ñÒѾ­½áÊø£¬ÎÒÃDZØÐëÅжϱíʾÆäµÄ¶ÔÏóÊÇ·ñ´¦ÓÚ֪ͨ״̬£¬¶øÒª´ïµ½ÕâÑùµÄÄ¿µÄ£¬ÎÒÃÇÐèҪʹÓÃWait*º¯Êý¡£

Wait*º¯Êý

      ÏÂÃæÊÇ×î¼òµ¥µÄWait*º¯Êý£º

// create an auto-reset event

CEvent g_eventStart;

UINT ThreadProc1(LPVOID pParam)
{
    ::WaitForSingleObject(g_eventStart, INFINITE);
        
    
return 0;
}

UINT ThreadProc2(LPVOID pParam)
{
    ::WaitForSingleObject(g_eventStart, INFINITE);

        
    
return 0;
}

        ÔÚÕâ¸öÀý×ÓÖУ¬Ò»¸öÈ«¾ÖµÄCEvent¶ÔÏó±»´´½¨£¬µ±È»ËüÊÇ×Ô¶¯ÖØÖÃÐ͵ġ£³ý´ËÒÔÍ⣬ÓÐÁ½¸ö¹¤×÷Ïß³ÌÔڵȴýÕâ¸öʼþ¶ÔÏóÒԱ㿪ʼÆä¹¤×÷¡£Ö»ÒªµÚÈý¸öÏ̵߳÷ÓÃÄǸöʼþ¶ÔÏóµÄSetEvent·½·¨£¬ÔòÁ½¸öÏß³ÌÖÐÖ®Ò»£¨µ±È»Ã»ÈËÖªµÀ»áÊÇÄĸö£©»á½ÓÊÕµ½Í¨Öª£¬È»ºóʼþ»á½øÈëδ֪ͨ״̬£¬Õâ¾Í·ÀÖ¹Á˵ڶþ¸öÏß³ÌÒ²µÃµ½Ê¼þµÄ֪ͨ¡£

      ÏÂÃæÀ´¿´µÚ¶þ¸öÀý×Ó:

// create a manual-reset event

CEvent g_eventStart(FALSE, TRUE);

UINT ThreadProc1(LPVOID pParam)
{
    ::WaitForSingleObject(g_eventStart, INFINITE);
        
    
return 0;
}


UINT ThreadProc2(LPVOID pParam)
{
    ::WaitForSingleObject(g_eventStart, INFINITE);
        
    
return 0;
}

    Õâ¶Î´úÂëºÍÉÏÃæµÄÉÔÓв»Í¬£¬CEvent¶ÔÏó¹¹Ô캯ÊýµÄ²ÎÊý²»Ò»ÑùÁË£¬µ«ÒâÒåÉϾʹó²»Í¬ÁË£¬ÕâÊÇÒ»¸öÊÖ¶¯ÖØÖÃÐÍʼþ¶ÔÏó¡£ÈôµÚÈý¸öÏ̵߳÷ÓÃʼþ¶ÔÏóµÄSetEvent·½·¨£¬Ôò¿ÉÒÔÈ·±£Á½¸ö¹¤×÷Ï̶߳¼»áͬʱ£¨¼¸ºõÊÇͬʱ£©¿ªÊ¼¹¤×÷¡£ÕâÊÇÒòΪÊÖ¶¯ÖØÖÃÐÍʼþÔÚ½øÈëÒÑ֪ͨ״̬ºó£¬»á±£³Ö´Ë״ֱ̬µ½¶ÔÓ¦µÄResetEvent±»µ÷Óá£

      ³ý´ËÒÔÍâʼþ¶ÔÏó»¹ÓÐÒ»¸ö·½·¨£ºCEvent::PulseEvent¡£Õâ¸ö·½·¨Ê×ÏÈʹµÃʼþ¶ÔÏó½øÈëÒÑ֪ͨ״̬£¬È»ºóʹÆäÍ˻ص½Î´Í¨Öª×´Ì¬¡£ÈôʼþÊÇÊÖ¶¯ÖØÖÃÐÍ£¬Ê¼þ½øÈëÒÑ֪ͨ״̬»áÈÃËùÓÐÕýÔڵȴýµÄÏ̵߳õ½Í¨Öª£¬È»ºóʼþ½øÈëδ֪ͨ״̬¡£ÈôʼþÊÇ×Ô¶¯ÖØÖÃÐÍ£¬Ê¼þ½øÈëÒÑ֪ͨ״̬ʱֻ»áÈÃËùÓеȴýµÄÏß³ÌÖ®Ò»µÃµ½Í¨Öª¡£ÈôûÓÐÏß³ÌÔڵȴý£¬Ôòµ÷ÓÃResetEventʲôҲ²»¸É¡£

ʵÀý---¹¤×÷ÕßÏß³Ì

       ±¾ÎÄËù´øµÄÀý×ÓÖУ¬×÷Õß½«Õ¹Ê¾ÈçºÎ´´½¨¹¤×÷ÕßÏß³ÌÒÔ¼°ÈçºÎºÏÀíµØÏú»ÙËüÃÇ¡£×÷Õß¶¨ÒåÁËÒ»¸ö±»ËùÓÐÏß³ÌʹÓõĿØÖƺ¯Êý¡£µ±µã»÷ÊÓÍ¼ÇøÓòʱ£¬¾Í´´½¨Ò»¸öÏ̡߳£ËùÓб»´´½¨µÄÏß³ÌʹÓÃÉÏÊö¿ØÖƺ¯ÊýÔÚÊÓͼ¿Í»§Çø»æÖÆÒ»¸öÔ˶¯µÄÔ²ÐΡ£ÕâÀï×÷ÕßʹÓÃÁËÒ»¸öÊÖ¶¯ÖØÖÃÐÍʼþ£¬Ëü±»ÓÃÀ´Í¨ÖªËùÓй¤×÷Ïß³ÌÆäËÀѶ¡£³ý´ËÒÔÍ⣬ÎÒÃǽ«¿´µ½ÈçºÎʹµÃÖ÷Ï̵߳ȴýÖ±µ½ËùÓй¤×÷ÕßÏß³ÌÏú»Ùµô¡£

×÷Õß½«Ï̺߳¯Êý¶¨ÒåΪȫ¾ÖµÄ:

struct THREADINFO
{
    HWND hWnd;
//Ö÷ÊÓÍ¼Çø
    POINT point;//Æðʼµã
}
;

UINT ThreadDraw(PVOID pParam);

extern CEvent g_eventEnd;

UINT ThreadDraw(PVOID pParam)
{
    
static int snCount = 0;//Ï̼߳ÆÊýÆ÷
    snCount ++;//¼ÆÊýÆ÷µÝÔö
    TRACE(TEXT("- ThreadDraw %d: started\n"), snCount);

    
//È¡³ö´«ÈëµÄ²ÎÊý
    THREADINFO *pInfo = reinterpret_cast<THREADINFO *> (pParam);

    CWnd 
*pWnd = CWnd::FromHandle(pInfo->hWnd);//Ö÷ÊÓÍ¼Çø

    CClientDC dc(pWnd);
    
    
int x = pInfo->point.x;
    
int y = pInfo->point.y;
    
    srand((UINT)time(NULL));
    CRect rectEllipse(x 
- 25, y - 25, x + 25, y + 25);

    CSize sizeOffset(
11);
    
//Ë¢×ÓÑÕÉ«Ëæ»ú
    CBrush brush(RGB(rand()% 256, rand()% 256, rand()% 256));
    CBrush 
*pOld = dc.SelectObject(&brush);

    
while (WAIT_TIMEOUT == ::WaitForSingleObject(g_eventEnd, 0))
    
{//Ö»ÒªÖ÷Ï̻߳¹Î´Í¨ÖªÎÒ×Ôɱ£¬¼ÌÐø¹¤×÷!(×¢Òâʱ¼äÉèÖÃΪ)
        CRect rectClient;
        pWnd
->GetClientRect(rectClient);

        
if (rectEllipse.left < rectClient.left || rectEllipse.right > rectClient.right)
            sizeOffset.cx 
*= -1;

        
if (rectEllipse.top < rectClient.top || rectEllipse.bottom > rectClient.bottom)
            sizeOffset.cy 
*= -1;

        dc.FillRect(rectEllipse, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

        rectEllipse.OffsetRect(sizeOffset);
        
        dc.Ellipse(rectEllipse);
        Sleep(
25);//ÐÝÃßÏ£¬¸øÆäËû»æÖÆ×ÓÏß³ÌÔËÐеĻú»á
    }


    dc.SelectObject(pOld);    

    delete pInfo;
//ɾ³ý²ÎÊý£¬·ÀÖ¹ÄÚ´æÐ¹Â¶

    TRACE(TEXT(
"- ThreadDraw %d: exiting.\n"), snCount --);//¹é»¹¼ÆÊýÆ÷
    return 0;
}

        ×¢Òâ×÷Õß´«ÈëµÄÊÇÒ»¸ö°²È«¾ä±ú£¬¶ø²»ÊÇÒ»¸öCWndÖ¸Õ룬²¢ÇÒÔÚÏ̺߳¯ÊýÖÐͨ¹ý´«ÈëµÄ¾ä±ú´´½¨Ò»¸öÁÙʱµÄC++¶ÔÏó²¢Ê¹Óá£ÕâÑù¾Í±ÜÃâÁËÔÚ¶àÏ̱߳à³ÌÖжà¸ö¶ÔÏóÒýÓõ¥¸öC++¶ÔÏóµÄΣÏÕ¡£
    CArray<CWinThread *, CWinThread *> m_ThreadArray;//±£´æCWinThread¶ÔÏóÖ¸Õë


// manual-reset event
CEvent g_eventEnd(FALSE, TRUE);

void CWorkerThreadsView::OnLButtonDown(UINT nFlags, CPoint point)
{
    THREADINFO 
*pInfo = new THREADINFO;//Ï̲߳ÎÊý
    pInfo->hWnd = GetSafeHwnd();//ÊÓͼ´°¿Ú
    pInfo->point = point;//µ±Ç°µã
    
//½«½çÃæ×÷Ϊ²ÎÊý´«ÈëÏß³ÌÖУ¬¾Í¿ÉÒÔÔÚÏß³ÌÖÐ×Ô¼º¸üÐÂÖ÷½çÃæ,¶ø²»ÓÃȥ֪ͨÖ÷Ï̸߳üнçÃæ
    CWinThread *pThread = AfxBeginThread(ThreadDraw, (PVOID) pInfo, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);//´´½¨Ị̈߳¬³õʼ״̬Ϊ¹ÒÆð
    pThread->m_bAutoDelete = FALSE;//Ïß³ÌÖ´ÐÐÍê±Ïºó²»×Ô¶¯Ïú»Ù
    pThread->ResumeThread();//Ï߳̿ªÊ¼Ö´ÐÐ
    m_ThreadArray.Add(pThread);//±£´æ´´½¨µÄÏß³Ì
}

    ÎªÁ˺ÏÀíµØÏú»ÙËùÓÐỊ̈߳¬Ê×ÏÈʹµÃʼþ½øÈëÒÑ֪ͨ״̬£¬Õâ»á֪ͨ¹¤×÷Ï߳̓ËÀÆÚÒÑÖÁ”£¬È»ºóµ÷ÓÃWaitForSingleObjectÈÃÖ÷Ï̵߳ȴýËùÓеŤ×÷ÕßÏß³ÌÍêÈ«Ïú»Ùµô¡£×¢Òâÿ´Îµü´úʱµ÷ÓÃWaitForSingleObject»áµ¼Ö´ÓÓû§Ä£Ê½½øÈëÄÚºËģʽ¡£ÀýÈ磬10´Ëµü´ú»áÀ˷ѵô´óÔ¼10000´ÎʱÖÓÖÜÆÚ¡£ÎªÁ˱ÜÃâÕâ¸öÎÊÌ⣬ÎÒÃÇ¿ÉÒÔʹÓÃWaitForMultipleObjects¡£Õâ¾ÍÊǵڶþÖÖ·½·¨¡£
    
void CWorkerThreadsView::OnDestroy()
{
    g_eventEnd.SetEvent();

/*    // µÚÒ»ÖÖ·½Ê½
    for (int j = 0; j < m_ThreadArray.GetSize(); j ++)
    {
        ::WaitForSingleObject(m_ThreadArray[j]->m_hThread, INFINITE);
        delete m_ThreadArray[j];
    }
*/

    
//µÚ¶þÖÖ·½Ê½
    int nSize = m_ThreadArray.GetSize();
    HANDLE 
*= new HANDLE[nSize];
    
for (int j = 0; j < nSize; j ++)
    
{
        p[j] 
= m_ThreadArray[j]->m_hThread;
    }

    ::WaitForMultipleObjects(nSize, p, TRUE, INFINITE);
    
for (int j = 0; j < nSize; j ++)
    
{
        delete m_ThreadArray[j];
    }

    delete [] p;
    TRACE(
"- CWorkerThreadsView::OnDestroy: finished!\n");
}

 ¹Ø¼üÇøÓò

      ºÍÆäËûͬ²½¶ÔÏó²»Í¬£¬³ý·ÇÓÐÐèÒªÒÔÍ⣬¹Ø¼üÇøÓò¹¤×÷ÔÚÓû§Ä£Ê½Ï¡£ÈôÒ»¸öÏß³ÌÏëÔËÐÐÒ»¸ö·â×°ÔڹؼüÇøÓòÖеĴúÂ룬ËüÊ×ÏÈ×öÒ»¸öÐýת·âËø£¬È»ºóµÈ´ýÌØ¶¨µÄʱ¼ä£¬Ëü½øÈëÄÚºËģʽȥµÈ´ý¹Ø¼üÇøÓò¡£Êµ¼ÊÉÏ£¬¹Ø¼üÇøÓò³ÖÓÐÒ»¸öÐýת¼ÆÊýÆ÷ºÍÒ»¸öÐźÅÁ¿£¬Ç°ÕßÓÃÓÚÓû§Ä£Ê½µÄµÈ´ý£¬ºóÕßÓÃÓÚÄÚºËģʽµÄµÈ´ý£¨ÐÝÃß̬£©¡£ÔÚWin32APIÖУ¬ÓÐÒ»¸öCRITICAL_SECTION½á¹¹Ìå±íʾ¹Ø¼üÇøÓò¶ÔÏó¡£ÔÚMFCÖУ¬ÓÐÒ»¸öÀàCCriticalSection¡£¹Ø¼üÇøÓòÊÇÕâÑùÒ»¶Î´úÂ룬µ±Ëü±»Ò»¸öÏß³ÌÖ´ÐÐʱ£¬±ØÐëÈ·±£²»»á±»ÁíÒ»¸öÏß³ÌÖжϡ£

Ò»¸ö¼òµ¥µÄÀý×ÓÊǶà¸öÏ̹߳²ÓÃÒ»¸öÈ«¾Ö±äÁ¿£º

int g_nVariable = 0;

UINT Thread_First(LPVOID pParam)
{
    
if (g_nVariable < 100)
    
{
       
    }

    
return 0;
}


UINT Thread_Second(LPVOID pParam)
{
    g_nVariable 
+= 50;
    
    
return 0;
}


      Õâ¶Î´úÂë²»ÊÇḬ̈߳²È«µÄ£¬ÒòΪûÓÐÏ̶߳ԱäÁ¿g_nVariableÊǶÀռʹÓõġ£ÎªÁ˽â¾öÕâ¸öÎÊÌ⣬¿ÉÒÔÈçÏÂʹÓãº
CCriticalSection g_cs;
int g_nVariable = 0;

UINT Thread_First(LPVOID pParam)
{
    g_cs.Lock();
    
if (g_nVariable < 100)
    
{
       
    }

    g_cs.Unlock();
    
return 0;
}


UINT Thread_Second(LPVOID pParam)
{
    g_cs.Lock();
    g_nVariable 
+= 20;
    g_cs.Unlock();
    
    
return 0;
}

    ÕâÀïʹÓÃÁËCCriticalSectionÀàµÄÁ½¸ö·½·¨£¬µ÷ÓÃLockº¯Êý֪ͨϵͳÏÂÃæ´úÂëµÄÖ´Ðв»Äܱ»Öжϣ¬Ö±µ½ÏàͬµÄÏ̵߳÷ÓÃUnlock·½·¨¡£ÏµÍ³»áÊ×Ïȼì²é±»ÏµÍ³¹Ø¼üÇøÓò·âËøµÄ´úÂëÊÇ·ñ±»ÁíÒ»¸öÏ̲߳¶»ñ¡£ÈôÊÇ£¬ÔòÏ̵߳ȴýÖ±µ½²¶»ñÏß³ÌÊͷŵô¹Ø¼üÇøÓò¡£

      ÈôÓжà¸ö¹²Ïí×ÊÔ´ÐèÒª±£»¤£¬Ôò×îºÃΪÿ¸ö×ÊԴʹÓÃÒ»¸öµ¥¶ÀµÄ¹Ø¼üÇøÓò¡£¼ÇµÃÒªÅä¶ÔʹÓÃUnLockºÍLock¡£»¹ÓÐÒ»µãÊÇÐèÒª·ÀÖ¹ËÀËø¡£

class CSomeClass
{
    CCriticalSection m_cs;
    
int m_nData1;
    
int m_nData2;

public:
    
void SetData(int nData1, int nData2)
    
{
        m_cs.Lock();
        m_nData1 
= Function(nData1);
        m_nData2 
= Function(nData2);
        m_cs.Unlock();
    }


    
int GetResult()
    
{
        m_cs.Lock();
        
int nResult = Function(m_nData1, m_nData2);
        m_cs.Unlock();
        
return nResult;
    }

}
;
 

»¥³âËø

      ºÍ¹Ø¼üÇøÓòÀàËÆ£¬»¥³âËøÉè¼ÆÎª¶Ôͬ²½·ÃÎʹ²Ïí×ÊÔ´½øÐб£»¤¡£»¥³âËøÔÚÄÚºËÖÐʵÏÖ£¬Òò´ËÐèÒª½øÈëÄÚºËģʽ²Ù×ÝËüÃÇ¡£»¥³âËø²»½öÄÜÔÚ²»Í¬Ïß³ÌÖ®¼ä£¬Ò²¿ÉÒÔÔÚ²»Í¬½ø³ÌÖ®¼ä½ø³Ìͬ²½¡£Òª¿ç½ø³ÌʹÓã¬Ôò»¥³âËøÓ¦¸ÃÊÇÓÐÃûµÄ¡£MFCÖÐʹÓÃCMutexÀàÀ´²Ù×Ý»¥³âËø¡£¿ÉÒÔÈçÏ·½Ê½Ê¹Óãº
        ÎÒÃÇ¿ÉÒÔʹÓû¥³âËøÀ´ÏÞÖÆÓ¦ÓóÌÐòµÄÔËÐÐʵÀýΪһ¸ö¡£¿ÉÒÔ½«ÈçÏ´úÂë·ÅÖõ½InitInstanceº¯Êý£¨»òWinMain£©ÖУºÐźÅÁ¿

CSingleLock singleLock(&m_Mutex);
singleLock.Lock();  
// try to capture the shared resource
if (singleLock.IsLocked())  // we did it
{
    
// use the shared resource 
    
// After we done, let other threads use the resource
    singleLock.Unlock();
}

»òÕßͨ¹ýWin32º¯Êý£º
// try to capture the shared resource

::WaitForSingleObject(m_Mutex, INFINITE);

// use the shared resource 


// After we done, let other threads use the resource

::ReleaseMutex(m_Mutex);

 

HANDLE h = CreateMutex(NULL, FALSE, "MutexUniqueName");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{//»¥³âËøÒѾ­´æÔÚ
    AfxMessageBox("An instance is already running.");
    
return(0);
}

 

      ΪÁËÏÞÖÆÊ¹Óù²Ïí×ÊÔ´µÄÏß³ÌÊýÄ¿£¬ÎÒÃÇÓ¦¸ÃʹÓÃÐźÅÁ¿¡£ÐźÅÁ¿ÊÇÒ»¸öÄں˶ÔÏó¡£Ëü´æ´¢ÁËÒ»¸ö¼ÆÊýÆ÷±äÁ¿À´¸ú×ÙʹÓù²Ïí×ÊÔ´µÄÏß³ÌÊýÄ¿¡£ÀýÈ磬ÏÂÃæ´úÂëʹÓÃCSemaphoreÀà´´½¨ÁËÒ»¸öÐźÅÁ¿¶ÔÏó£¬ËüÈ·±£ÔÚ¸ø¶¨µÄʱ¼ä¼ä¸ôÄÚ£¨Óɹ¹Ô캯ÊýµÚÒ»¸ö²ÎÊýÖ¸¶¨£©×î¶àÖ»ÓÐ5¸öÏß³ÌÄÜʹÓù²Ïí×ÊÔ´¡£»¹¼Ù¶¨³õʼʱûÓÐÏ̻߳ñµÃ×ÊÔ´£ºÒ»µ©Ï̷߳ÃÎʹ²Ïí×ÊÔ´£¬ÐźÅÁ¿µÄ¼ÆÊýÆ÷¾Í¼õ1.Èô±äΪ0£¬Ôò½ÓÏÂÀ´¶Ô×ÊÔ´µÄ·ÃÎʻᱻ¾Ü¾ø£¬Ö±µ½ÓÐÒ»¸ö³ÖÓÐ×ÊÔ´µÄÏß³ÌÀ뿪£¨Ò²¾ÍÊÇ˵ÊÍ·ÅÁËÐźÅÁ¿£©¡£ÎÒÃÇ¿ÉÒÔÈçÏÂʹÓãº

CSemaphore g_Sem(55);

 

 

// Try to use the shared resource
::WaitForSingleObject(g_Sem, INFINITE);
// Now the user's counter of the semaphore has decremented by one

// Use the shared resource 
// After we done, let other threads use the resource
::ReleaseSemaphore(g_Sem, 1, NULL);
// Now the user's counter of the semaphore has incremented by one

 Ö÷´ÓÏß³ÌÖ®¼äµÄͨÐÅ

      ÈôÖ÷Ïß³ÌÏë֪ͨ´ÓÏß³ÌһЩ¶¯×÷µÄ·¢Éú£¬Ê¹ÓÃʼþ¶ÔÏóÊǺܷ½±ãµÄ¡£µ«·´¹ýÀ´È´ÊǵÍЧ£¬²»·½±ãµÄ¡£ÒòΪÕâ»áÈÃÖ÷Ïß³ÌÍ£ÏÂÀ´µÈ´ýʼþ£¬½ø¶ø½µµÍÁËÓ¦ÓóÌÐòµÄÏìÓ¦ËÙ¶È¡£×÷ÕßÌá³öµÄ·½·¨ÊÇÈôÓÏ̷߳¢×Ô¶¨ÒåÏûÏ¢¸ø¸¸Ï̡߳£

    #define WM_MYMSG WM_USER + 1

    ÕâÖ»Äܱ£Ö¤´°¿ÚÀàÖÐΨһ£¬µ«ÎªÁËÈ·±£Õû¸öÓ¦ÓóÌÐòÖÐΨһ£¬¸üΪ°²È«µÄ·½Ê½ÊÇ£º

#define WM_MYMSG WM_APP + 1

afx_msg LRESULT OnMyMessage(WPARAM , LPARAM );

LRESULT CMyWnd::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
    
// A notification got

    
// Do something 
    return 0;
}


BEGIN_MESSAGE_MAP(CMyWnd, CWnd)
    
    ON_MESSAGE(WM_MYMSG, OnMyMessage)
END_MESSAGE_MAP()

UINT ThreadProc(LPVOID pParam)
{
    HWND hWnd 
= (HWND) pParam;
    
    
// notify the primary thread's window
    ::PostMessage(hWnd, WM_MYMSG, 00);
    
return 0;
}

    µ«Õâ¸ö·½·¨ÓиöºÜ´óµÄȱÏÝ--ÄÚ´æÐ¹Â¶£¬×÷ÕßûÓÐÉîÈëÑо¿£¬¿ÉÒԲο¼ÎÒÕâÆªÎÄÕ¡¶Ç³Ì¸Ò»¸öÏß³ÌͨÐÅ´úÂëµÄÄÚ´æÐ¹Â¶¼°½â¾ö·½°¸ ¡·

Download source files - 47.7 KB

 

Ô­ÎÄÁ´½Ó£ºSynchronization in Multithreaded Applications with MFC
À´×Ô£º¡¾Òë¡¿ÆÊÎöMFC¶àÏ̳߳ÌÐòµÄͬ²½»úÖÆ

DWORD WaitForSingleObject
(
  HANDLE hHandle,
  DWORD dwMilliseconds
);

²ÎÊýhHandle±íʾ´ý¼ì²éÆä״̬£¨Í¨Öª»òÕßδ֪ͨ£©µÄ¶ÔÏó£¬dwMilliseconds±íʾµ÷ÓÃÏß³ÌÔÚ±»¼ì²é¶ÔÏó½øÈëÆä֪ͨ״̬ǰӦ¸ÃµÈ´ýµÄʱ¼ä¡£Èô¶ÔÏó´¦ÓÚ֪ͨ״̬»òÖ¸¶¨Ê±¼ä¹ýÈ¥ÁË£¬Õâ¸öº¯Êý·µ»Ø¿ØÖÆÈ¨¸øµ÷ÓÃÏ̡߳£ÈôdwMillisecondsÉèÖÃΪINIFINITE£¨ÖµÎª-1£©£¬Ôòµ÷ÓÃÏ̻߳áÒ»Ö±µÈ´ýÖ±µ½¶ÔÏó״̬±äΪ֪ͨ£¬ÕâÓпÉÄÜʹµÃµ÷ÓÃÏß³ÌÓÀÔ¶µÈ´ýÏÂÈ¥£¬µ¼Ö¶öËÀ¡£

      ÀýÈ磬¼ì²éÖ¸¶¨Ïß³ÌÊÇ·ñÕýÔÚÖ´ÐÐ, dwMillisecondsÉèÖÃΪ0,ÊÇΪÁËÈõ÷ÓÃÏß³ÌÂíÉÏ·µ»Ø¡£

 

DWORD dw = WaitForSingleObject(hProcess, 0);
switch (dw)
{
   
case WAIT_OBJECT_0:
      
// the process has exited
      break;
   
case WAIT_TIMEOUT:
      
// the process is still executing
      break;
   
case WAIT_FAILED:
      
// failure
      break;
}

    ÏÂÒ»¸öWaitÀຯÊýÀàËÆÉÏÃæµÄ£¬µ«Ëü´øµÄÊÇһϵÁоä±ú£¬²¢ÇҵȴýÆäÖÐÖ®Ò»»òÈ«²¿½øÈëÒÑ֪ͨ״̬¡£
DWORD WaitForMultipleObjects
(
  DWORD nCount,
  CONST HANDLE 
*lpHandles,
  BOOL fWaitAll,
  DWORD dwMilliseconds
);
  ²ÎÊýnCount±íʾ´ý¼ì²éµÄ¾ä±ú¸öÊý£¬lpHandlesÖ¸Ïò¾ä±úÊý×飬ÈôfWaitAllΪTRUE,ÔòµÈ´ýËùÓеĶÔÏó½øÈëÒÑ֪ͨ״̬£¬ÈôΪFALSE£¬Ôòµ±ÈκÎÒ»¸ö¶ÔÏó½øÈëÒÑ֪ͨ״̬ʱ£¬º¯Êý·µ»Ø¡£dwMillisecondsÒâÒåͬÉÏ¡£

ÀýÈ磬ÏÂÃæ´úÂëÅжÏÄĸö½ø³Ì»áÏȽáÊø£º

HANDLE h[3];
h[
0= hThread1;
h[
1= hThread2;
h[
2= hThread3;

DWORD dw 
= WaitForMultipleObjects(3, h, FALSE, 5000);//ÈκÎÒ»¸ö½øÈëÒÑ֪ͨ¾Í·µ»Ø
switch (dw)
{
   
case WAIT_FAILED:
      
// failure
      break;
   
case WAIT_TIMEOUT:
      
// no processes exited during 5000ms
      break;
   
case WAIT_OBJECT_0 + 0:
      
// a process with h[0] descriptor has exited
      break;
   
case WAIT_OBJECT_0 + 1:
      
// a process with h[1] descriptor has exited
      break;
   
case WAIT_OBJECT_0 + 2:
      
// a process with h[2] descriptor has exited
      break;
}


  ¾ä±úÊý×éÖÐË÷ÒýºÅΪindexµÄ¶ÔÏó½øÈëÒÑ֪ͨ״̬ʱ£¬º¯Êý·µ»ØWAIT_OBJECT_0 + Ë÷ÒýºÅ¡£ÈôfWaitAllΪTRUE£¬Ôòµ±ËùÓжÔÏó½øÈëÒÑ֪ͨ״̬ʱ£¬º¯Êý·µ»ØWAIT_OBJECT_0¡£

      Ò»¸öÏß³ÌÈôµ÷ÓÃÒ»¸öWait*º¯Êý£¬ÔòËü´ÓÓû§Ä£Ê½Çл»ÎªÄÚºËģʽ¡£Õâ´øÀ´µÄºó¹ûÓкÃÓлµ¡£²»ºÃµÄÊÇÇл»½øÈëÄÚºËģʽ´ó¸ÅÐèÒª1000¸öʱÖÓÖÜÆÚ£¬ÕâÏûºÄ²»ËãС¡£ºÃµÄÊǵ±½øÈëÄÚºËģʽºó£¬¾Í²»ÐèҪʹÓô¦ÀíÆ÷£¬¶øÊǽøÈëÐÝÃß̬£¬²»²ÎÓë´¦ÀíÆ÷µÄµ÷¶ÈÁË¡£

      ÏÖÔÚÈÃÎÒÃǽøÈëMFC£¬²¢¿´¿´ËüÄÜΪÎÒÃÇ×öЩʲô¡£ÕâÀïÓÐÁ½¸öÀà·â×°Á˶ÔWait*º¯ÊýµÄµ÷ÓÃ: CSingleLockºÍCMultiLock¡£
 

ͬ²½¶ÔÏó

µÈ¼ÛµÄC++Àà

Events

CEvent

Critical sections

CCriticalSection

Mutexes

CMutex

Semaphores

CSemaphore

ÿ¸öÀà¶¼´ÓÒ»¸öÀà--CSyncObject¼Ì³ÐÏÂÀ´£¬´ËÀà×îÓÐÓõijÉÔ±ÊÇÖØÔØµÄHANDLEÔËËã·û£¬Ëü·µ»ØÖ¸¶¨Í¬²½¶ÔÏóµÄÄÚÔÚ¾ä±ú¡£ËùÓÐÕâЩÀà¶¼¶¨ÒåÔÚ<AfxMt.h>Í·ÎļþÖС£

ʼþ

      Ò»°ãÀ´Ëµ£¬Ê¼þÓÃÓÚÕâÑùµÄÇéÐÎÏ£ºµ±Ö¸¶¨µÄ¶¯×÷·¢Éúºó£¬Ò»¸öỊ̈߳¨»ò¶à¸öỊ̈߳©²Å¿ªÊ¼Ö´ÐÐÆäÈÎÎñ¡£ÀýÈ磬һ¸öÏ߳̿ÉÄܵȴý±ØÐèµÄÊý¾ÝÊÕ¼¯Íêºó²Å¿ªÊ¼½«Æä±£´æµ½Ó²ÅÌÉÏ¡£ÓÐÁ½ÖÖʼþ£ºÊÖ¶¯ÖØÖÃÐͺÍ×Ô¶¯ÖØÖÃÐÍ¡£Í¨¹ýʹÓÃʼþ£¬ÎÒÃÇ¿ÉÒÔÇáËɵØÍ¨ÖªÁíÒ»¸öÏß³ÌÌØ¶¨µÄ¶¯×÷ÒѾ­·¢ÉúÁË¡£¶ÔÓÚÊÖ¶¯ÖØÖÃÐÍʼþ£¬Ïß³ÌʹÓÃËü֪ͨ¶à¸öÏß³ÌÌØ¶¨¶¯×÷ÒѾ­·¢Éú£¬¶ø¶ÔÓÚ×Ô¶¯ÖØÖÃÐÍʼþ£¬Ïß³ÌʹÓÃËüÖ»¿ÉÒÔ֪ͨһ¸öÏ̡߳£ÔÚMFCÖУ¬CEventÀà·â×°ÁËʼþ¶ÔÏó£¨ÈôÔÚwin32ÖУ¬ËüÊÇÓÃÒ»¸öHANDLEÀ´±íʾµÄ£©¡£CEventµÄ¹¹Ô캯ÊýÔËÐÐÎÒÃÇÑ¡Ôñ´´½¨ÊÖ¶¯ÖØÖÃÐͺÍ×Ô¶¯ÖØÖÃÐÍʼþ¡£Ä¬ÈϵĴ´½¨ÀàÐÍÊÇ×Ô¶¯ÖØÖÃÐÍʼþ¡£ÎªÁË֪ͨÕýÔڵȴýµÄỊ̈߳¬ÎÒÃÇ¿ÉÒÔµ÷ÓÃCEvent::SetEvent·½·¨£¬Õâ¸ö·½·¨½«»áÈÃʼþ½øÈëÒÑ֪ͨ״̬¡£ÈôʼþÊÇÊÖ¶¯ÖØÖÃÐÍ£¬Ôòʼþ»á±£³ÖÒÑ֪ͨ״̬£¬Ö±µ½¶ÔÓ¦µÄCEvent::ResetEvent±»µ÷Óã¬Õâ¸ö·½·¨½«Ê¹µÃʼþ½øÈëδ֪ͨ״̬¡£Õâ¸öÌØÐÔʹµÃÒ»¸öÏ߳̿ÉÒÔͨ¹ýÒ»¸öSetEventµ÷ÓÃȥ֪ͨ¶à¸öÏ̡߳£ÈôʼþÊÇ×Ô¶¯ÖØÖÃÐÍ£¬ÔòËùÓÐÕýÔڵȴýµÄÏß³ÌÖÐÖ»ÓÐÒ»¸öÏ̻߳á½ÓÊÕµ½Í¨Öª¡£µ±ÄǸöÏ߳̽ÓÊÕµ½Í¨Öªºó£¬Ê¼þ»á×Ô¶¯½øÈëδ֪ͨ״̬¡£

      ÏÂÃæÁ½¸öÀý×Ó½«Õ¹Ê¾ÉÏÊöÌØÐÔ£º

·ÖÀࣺ Windows±à³Ì .NET¼¼Êõ ÓÎÏ·¿ª·¢

ÉÏһƪ£ºµ