MFC多线程互锁

CreateEvent跟CreateMutex的比较:
区别1,
 
CreateEvent跟CreateMutex,你第一个问题关键在于后者内置了一个计数器,比如:假若同一线程连续申请2次互斥量,那么计数器为2,若需要释放互斥量就需要ReleaseMutex()2次,而前者没有。  
区别2,
 
Event是一个线程通知另一个线程用的,是单向的。一方接收,其它方可以发送。一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的,双方地位并不平等。
Mutex是用于资源控制用的,对于同一个资源,一次只能有一人可以对资源进行访问。双方的地位是平等的。
Mutex比Event复杂一点,可以用Mutex实现Event的功能  
区别3,
 
MUTEX其实是你进临界区之前的   
 
CreateMutex的使用:
HANDLE CreateMutex(
LPSECURITY_ATTRIBUTESlpMutexAttributes, // 指向安全属性的指针
BOOLbInitialOwner, // 初始化互斥对象的所有者
LPCTSTRlpName // 指向互斥对象名的指针
);
5、
A handle to the mutex object indicates success. If the named mutex object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS. Otherwise, the caller created the mutex. NULL indicates failure. To get extended error information, call GetLastError.
#include "stdafx.h"
#include "windows.h"
  int main(int argc, char* argv[])
      {     HANDLE m_hMutex = CreateMutex(NULL,TRUE,"cplusplus_me");
             DWORD dwRet = GetLastError();  
                    if (m_hMutex) 
                          {         
                              if (ERROR_ALREADY_EXISTS == dwRet)   
                                  {      printf("程序已经在运行中了,程序退出!\n");       
                                         CloseHandle(m_hMutex);
                                         return 0;         
                                   } 
                           }
                   else    {
                             printf("创建互斥量错误,程序退出!\n");                                                       CloseHandle(m_hMutex) ;
                               return 0;     
                              } 
       while(1)
            {         printf("cplusplus_me\n");     }
      CloseHandle(m_hMutex);  
       return 0; 
     } 


搭配使用的WaitForMultipleObjects:
DWORD WINAPI WaitForMultipleObjects(
  __in      DWORD nCount,
  __in      const HANDLE* lpHandles,
  __in      BOOL bWaitAll,
  __in      DWORD dwMilliseconds
);
The WaitForMultipleObjects function can specify handles of any of the following object types in the lpHandles array:
·         Change notification 
·         Console input 
·         Event 
·         Memory resource notification 
·         Mutex 
·         Process 
·         Semaphore 
·         Thread 
·         Waitable timer 












例子2:(MUTEX对于同一个资源,一次只能有一人可以对资源进行访问)
这个例子使用了 WaitForSingleObject的方法,下面将用WaitForMultipleObjects 

#include <iostream>
#include <afx.h>
#include <process.h>
using namespace std;
HANDLE          hUp;
CRITICAL_SECTION g_data;
int arr[10];
HANDLE hMutex; //使用手动重置为无信号状态,初始化时有信号状态
UINT __stdcall   Add(LPVOID lParam)
{
    DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
    for (int i = 0; i<10;i++ )
    {
       arr[i]=i;//0-9
    }
    for (int i = 0;i < 10; i++)
    {
       cout<<arr[i]<<" ";
    }
    cout<<endl;
    ReleaseMutex(hMutex);
    return 1;
}
UINT __stdcall   Add2(LPVOID lParam)
{
    DWORD dReturn = WaitForSingleObject(hMutex,INFINITE);
    for (int i = 0; i<100 ;i++)
    {
       arr [i] = i+100;//10`1
    }
    for (int i = 0;i < 10; i++)
    {
       cout<<arr[i]<<" ";
    }
    cout<<endl;
    ReleaseMutex(hMutex);
    return 1;
}
int main()
{
    hMutex = CreateMutex(NULL,FALSE,"");
    hUp=(HANDLE)_beginthreadex(NULL, 0, Add, NULL, NULL, 0);
    hUp=(HANDLE)_beginthreadex(NULL, 0, Add2, NULL, NULL, 0);
    Sleep(5000);
}






 




例字3:(CreateEvent 一般用在单纯的同步上,就是一个操作要等待另一个操作完成时用的)(330有关)
Waiting for Multiple Objects

The following example uses the CreateEvent function to create two event objects and the CreateThread function to create a thread. It then uses the WaitForMultipleObjects function to wait for the thread to set the state of one of the objects to signaled using the SetEvent function.
For an example that waits for a single object, see Using Mutex Objects.




#include <windows.h>
#include <stdio.h>
HANDLE ghEvents[2];
DWORD WINAPI ThreadProc( LPVOID );
void main()
{
    HANDLE hThread; 
    DWORD i, dwEvent, dwThreadID; 




    // Create two event objects
    for (i = 0; i < 2; i++) 
    { 
        ghEvents[i] = CreateEvent( 
            NULL,   // default security attributes
            FALSE,  // auto-reset event object
            FALSE,  // initial state is nonsignaled
            NULL);  // unnamed object
        if (ghEvents[i] == NULL) 
        { 
            printf("CreateEvent error: %d\n", GetLastError() ); 
            ExitProcess(0); 
        } 
    } 


    // Create a thread
    hThread = CreateThread( 
                 NULL,         // default security attributes
                 0,            // default stack size
                 (LPTHREAD_START_ROUTINE) ThreadProc, 
                 NULL,         // no thread function arguments
                 0,            // default creation flags
                 &dwThreadID); // receive thread identifier
    if( hThread == NULL )
    {
        printf("CreateThread error: %d\n", GetLastError());
        return;
    }


    // Wait for the thread to signal one of the event objects
    dwEvent = WaitForMultipleObjects( 
        2,           // number of objects in array
        ghEvents,     // array of objects
        FALSE,       // wait for any object
        5000);       // five-second wait


    // The return value indicates which event is signaled
    switch (dwEvent) 
    { 
        // ghEvents[0] was signaled
        case WAIT_OBJECT_0 + 0: 
            // TODO: Perform tasks required by this event
            printf("First event was signaled.\n");
            break; 
            // ghEvents[1] was signaled
        case WAIT_OBJECT_0 + 1: 
            // TODO: Perform tasks required by this event
            printf("Second event was signaled.\n");
            break; 
        case WAIT_TIMEOUT:
            printf("Wait timed out.\n");
            break;
        // Return value is invalid.
        default: 
            printf("Wait error: %d\n", GetLastError()); 
            ExitProcess(0); 
    }
// Close event handles
    for (i = 0; i < 2; i++) 
        CloseHandle(ghEvents[i]);    
}




DWORD WINAPI ThreadProc( LPVOID lpParam )
{
    // Set one event to the signaled state
    if ( !SetEvent(ghEvents[0]) )     (330中的使用方法)
    {
        printf("SetEvent failed (%d)\n", GetLastError());
        return -1;
    }
    return 1;
}