线程同步互斥之互斥量(Mutex)

其实互斥对象和临界区对象差不多,都是为了在多个线程访问公共数据块时,只允许一个线程访问此公共数据块。但是临界区是用户对象,互斥是内核对象;还有,在效率上来说,临界区效率高于互斥对象,下面来具体的看看。 
  准备知识: 
  1、内核对象互斥体(Mutex)的工作机理,WaitForSingleObject函数的用法,这些可以从MSDN获取详情; 
  2、当两个或更多线程需要同时访问一个共享资源时,系统需要使用同步机制来确保一次只有一个线程使用该资源。Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。 
下面是自己写的一个小Demo,具体代码如下:

#include <iostream>
#include <Windows.h>
using namespace std;
static HANDLE g_hMutex = INVALID_HANDLE_VALUE;
static int g_Count = 100;
DWORD WINAPI Thread1(LPVOID LPparameter);
DWORD WINAPI Thread2(LPVOID LPparameter);

int main()
{
    HANDLE thread1 = INVALID_HANDLE_VALUE;
    HANDLE thread2 = INVALID_HANDLE_VALUE;
    g_hMutex = CreateMutex(NULL, false, TEXT("Mutex"));
    if(!g_hMutex)
    {
        return -1;
    }

    thread1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
    thread2 = CreateThread(NULL, 0, Thread2, NULL , 0, NULL);
    Sleep(5000);
    CloseHandle(thread1);
    CloseHandle(thread2);
    return 0;
}


DWORD WINAPI Thread1(LPVOID LPparameter)
{
    while(1)
    {
        WaitForSingleObject(g_hMutex, INFINITE);
        if(g_Count>0)
        {
            //Sleep(20);
            cout<<"thread1:"<<g_Count--<<endl;
            ReleaseMutex(g_hMutex);
        }
        else
        {
            ReleaseMutex(g_hMutex);
            break;
        }
    }

    return 0;
}

DWORD WINAPI Thread2(LPVOID LPparameter)
{
    WaitForSingleObject(g_hMutex, INFINITE);
    while(1)
    {
        if(g_Count>0)
        {
            //Sleep(20);
            cout<<"thread2:"<<g_Count--<<endl;
            ReleaseMutex(g_hMutex);
        }
        else
        {
            ReleaseMutex(g_hMutex);
            break;
        }
    }   
    return 0;
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

个人感觉使用互斥对象的大概分为这个几个步骤: 
1、调用CreateMutex函数创建互斥对象; 
2、在线程中调用WaitForSingleObject函数等待线程(这个解释可能不是很清楚,可以自己查询MSDN看那看,这个函数有很多用处)。 
3、在线程保护完相关的公用数据后调用ReleaseMutex函数释放互斥对象的资源。

具体的使用的API的解释如下: 
HANDLE CreateMutex( 
LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针 
BOOL bInitialOwner, // 初始化互斥对象的所有者 
LPCTSTR lpName // 指向互斥对象名的指针 
); 
功能:创建一个互斥对象 
参数:lpMutexAttributes,互斥的安全属性,一般为NULL,使用默认安全属性 
参数:bInitialOwner,初始化互斥对象的所有者 
参数:lpName,互斥对象的名称 
返回值:返回一个互斥对象的句柄。

BOOL WIANPI ReleaseMutex( 
HANDLE hMutex 
); 
功能:释放一个互斥对象。 
参数:hMutex,需要释放互斥对象。 
返回值:TRUE为成功,FALSE为释放失败。

DWORD WaitForSingleObject( 
HANDLE hHandle, 
DWORD dwMilliseconds 
); 
功能:等待指定对象那的状态(这个解释不一定正确,可以自己去查询MSDN)。 
参数:hHandle,指定的对象的句柄,如何互斥量句柄或事件对象的句柄等。 
参数:dwMilliseconds,定时时间间隔,单位为milliseconds(毫秒).如果指定一个非零值,函数处于等待状态直到hHandle标记的对象被触发,或者时间到了。如果dwMilliseconds为0,对象没有被触发信号,函数不会进入一个等待状态,它总是立即返回。如果dwMilliseconds为INFINITE,对象被触发信号后,函数才会返回。 

返回值:执行成功,返回值指示出引发函数返回的事件


转自:http://m.blog.csdn.net/article/details?id=47836225

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值