多线程编程之嵌套锁

时间:2021-07-12 17:39:24

  嵌套锁只是针对一种特殊情况而引申出来的锁应用形式而已。

  参考下面这种应用场合:

HANDLE hLock;

void sub_func()
{
    WaitForSingleObject(hLock, INFINITE);
    do_something();
    ReleaseMutex(hLock);
}

void data_process()
{
    WaitForSingleObject(hLock, INFINITE);
    sub_func();
    ReleaseMutex(hLock);
}

   可以发现,sub_func()和data_process()都使用了相同的一把锁hLock。很明显,如果hLock不是信号量,那么sub_func()被data_process()调用之后将永远无法获取这把锁。怎么办呢?这个时候应该设计一种针对这种情况的特殊锁,也就是本文要说的嵌套锁

  嵌套锁的设计形式为:

typedef struct _NestLock
{
    int threadId;    /*记录线程ID*/
    int count;       /*记录相同线程中锁重复使用的次数*/
    HANDLE hLock;  /*锁句柄*/
}NestLock;

NestLock* create_nest_lock(HANLDE hLock)
{
    NestLock* hNestLock = (NestLock*)malloc(sizeof(NestLock));
    assert(NULL != hNestLock);

    hNestLock->threadId = hNestLock->count = 0;
    hNestLock->hLock = hLock;
    return hNestLock;
}

void get_nest_lock(NestLock* hNestLock)
{
    assert(NULL != hNestLock);

    if(hNestLock->threadId == GetThreadId())
    {
        hNestLock->count ++;
    }
    else
    {
        WaitForSingleObject(hNestLock->hLock);
        hNestLock->count = 1;
        hNestLock->threadId = GetThreadId();
    }
}

void release_nest_lock(NestLock* hNestLock)
{
    assert(NULL != hNestLock);
    assert(GetThreadId() == hNestLock->threadId);

    hNestLock->count --;
    if(0 == hNestLock->count)
    {
        hNestLock->threadId = 0;
        ReleaseMutex(hNestLock->hLock);
    }
}

void destroy_nest_lock(NestLock** phNestLock)
{
    assert(NULL != phNestLock);
    assert(NULL != *phNestLock)

    free(*phNestLock);
    *phNestLock = NULL;
}

 

小结:

  1. 嵌套锁不是一种新型锁,准确来说应该叫统计锁,只是针对特殊场合的一种应用形式而已;
  2. 嵌套锁的缺陷是监测起来比较麻烦一点。