zoukankan      html  css  js  c++  java
  • Mutex与Event控制互斥事件的使用详解

      最近写一程序,误用了Mutex的功能,错把Mutex当Event用了。

    【Mutex】

      使用Mutex的主要函数:CreateMutex、ReleaseMutex、OpenMutex、WaitForSingleObject、WaitForMultipleObjects。

      CreateMutex:其中第二个参数是表示当前线程拥有权。
        TRUE:创建线程获得初始所有权的互斥对象(即信号已被当前线程获得,没有释放前其它线程不能获得。如果当前线程调用了WaitForSingleObject函数,则释放次数等于调用次数加1)。
        FALSE:创建线程没有获得互斥对象的所有权。也就是自由争取,看谁先Wait到。
      不管怎么样,MUtex的释放规则是:谁拥有谁释放,还有在线程结束时,线程所获得的Mutex自动释放;当然还可以使用命名Mutex做唯一性验证,这个在整个windows生存期下有效。

    【Event】

      与Mutex不一样,Event是任何时候都是可以操作的,而且没有同调用多次WaitForSingleObject和同时释放多次一说。它的主要操作函数有:CreateEvent、SetEvent、WaitForSingleObject。

      CreateEvent参数说明。
        第二个参数表示调用WaitForSingleObject后手动(TRUE)/自动(FALSE)为无信号状态。
        第三个参数表示初始状态为有(TRUE)/无(FALSE)信号。
      Event的获得是通过一个队列去排队获得的,SetEvent没有限制使用,在任何可以调用的地方都可以调用。

    Mutex,的互斥是以线程为基本单位,而Event是以代码段为基本单位。所以在两者的使用上有着不同的功能用途。

    【测试代码】

    // Mutex_release.cpp : 定义控制台应用程序的入口点。
    //
    //
    #include "stdafx.h"
    #include "iostream"
    #include "windows.h"
    
    using namespace std;
    
    DWORD WINAPI ThreadProc1(LPVOID lpParam);
    DWORD WINAPI ThreadProc2(LPVOID lpParam);
    HANDLE hEvent = NULL;
    HANDLE hThread1 = NULL;
    HANDLE hThread2 = NULL;
    int main(int argc,char *args[])
    {
        hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); // 使用 *重置为无信号状态,初始化时*信号状态
    //    hEvent = CreateMutex(NULL, FALSE, NULL); // FALSE: 创建线程没有获得互斥对象的所有权 TRUE: 创建线程获得初始所有权的互斥对象
        hThread1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc1,NULL,0,NULL);
        Sleep(200);
        hThread2 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc2,NULL,0,NULL);
        Sleep(200);
        if (NULL == hThread1 || NULL == hThread2)
        {
            cout <<"create thread fail!";
        }//DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);
        //cout<< dReturn << endl;
        //ReleaseMutex(hEvent);
        //ReleaseMutex(hEvent);
        while(1){
    
            Sleep(100);
        //    ReleaseMutex(hEvent);
            SetEvent(hEvent);
        }
        return 0;
    }
    DWORD WINAPI ThreadProc1(LPVOID lpParam)
    {
        cout <<"in thread1@!"<<endl;
        DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);
        if (WAIT_OBJECT_0 == dReturn)
        {
            cout <<"thread1 signaled ! "<<endl;
        }
        
        dReturn = WaitForSingleObject(hEvent,INFINITE);
        if (WAIT_OBJECT_0 == dReturn)
        {
            cout <<"thread1 signaled*&* ! "<<endl;
        }
    
        cout <<"in thread1 --signal"<<endl;
        //SetEvent(hEvent);
    
        //ReleaseMutex(hEvent);
        //ReleaseMutex(hEvent);
        while(1){
            Sleep(100);
        }
        return 0;
    }
    DWORD WINAPI ThreadProc2(LPVOID lpParam)
    {
        cout <<"in thread2@!"<<endl;
        DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);
        if (WAIT_OBJECT_0 == dReturn)
        {
            cout <<"thread2 signaled ! "<<endl;
        }
        cout <<"in thread2--signal"<<endl;
        //SetEvent(hEvent);
        //SetEvent(hEvent);
        //ReleaseMutex(hEvent);
        while(1){
            Sleep(100);
        }
        return 0;
    }
    
    //int _tmain(int argc, _TCHAR* argv[])
    //{
    //
    ////    HANDLE m_hMutex = CreateEvent(NULL,FALSE,TRUE,NULL);// 检查错误代码
    //    HANDLE m_hMutex = CreateMutex(NULL, TRUE, NULL);
    //    if(m_hMutex == NULL)
    //    {
    //        printf("create no!\n");
    //        return -1;
    //    }
    //
    //    printf("create yes!\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes\n");
    //
    //    //SetEvent(m_hMutex);
    //    //SetEvent(m_hMutex);
    //    //SetEvent(m_hMutex);
    //
    //    //ReleaseMutex(m_hMutex);
    //    //ReleaseMutex(m_hMutex);
    //    //ReleaseMutex(m_hMutex);
    //
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 2\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 3\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 4\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 5\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 6\n");
    //    WaitForSingleObject(m_hMutex, INFINITE);
    //    printf("wait yes 7\n");
    //    return 0;
    //}
    世界如此的美好,江山如此的多娇! ---阳光正能量--->>>>>>>>>>>>>>>
  • 相关阅读:
    asp.net core 使用 signalR(一)
    实现一个基于码云的Storage
    架构设计原则
    给 asp.net core 写个中间件来记录接口耗时
    [svc]ext4文件删除&访问原理
    [svc]为何linux ext4文件系统目录默认大小是4k?
    [svc]traceroute(udp+icmp)&tracert(icmp)原理
    [jk]服务器远控卡及kvm切换器
    [svc]find+xargs/sed&sed后向引用+awk多匹配符+过滤行绝招总结&&产生随机数
    [svc]linux正则及grep常用手法
  • 原文地址:https://www.cnblogs.com/upendi/p/2932154.html
Copyright © 2011-2022 走看看