zoukankan      html  css  js  c++  java
  • 多线程编程之嵌套锁

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

      参考下面这种应用场合:

    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. 嵌套锁的缺陷是监测起来比较麻烦一点。
  • 相关阅读:
    git 学习
    ruby on rails 把阿里云上的图片资源转移到七牛云上写的一个task 文件 自动转移
    修改mysql的默认编码
    ruby on rails 安装中遇到的一些问题
    unity打包资源格式全解析
    unity打包全过程解析
    mmorpg手游中的战斗系统
    在线调试lua原型设计
    lua特性纪要
    软件开发中的哲学问题
  • 原文地址:https://www.cnblogs.com/kuliuheng/p/4070528.html
Copyright © 2011-2022 走看看