多线程编程之嵌套锁

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

  参考下面这种应用场合:

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. 嵌套锁的缺陷是监测起来比较麻烦一点。
时间: 2024-11-29 10:45:01

多线程编程之嵌套锁的相关文章

多线程编程之自旋锁

一.什么是自旋锁 一直以为自旋锁也是用于多线程互斥的一种锁,原来不是! 自旋锁是专为防止多处理器并发(实现保护共享资源)而引入的一种锁机制.自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用.无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁.但是两者在调度机制上略有不同.对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态.但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁

多线程编程之无锁队列

关于无锁队列的概念与实现,可以参考博文<无锁队列的实现>,主要涉及到的知识点包括CAS原子操作.无锁队列的链表实现.无锁队列的数组实现以及ABA问题. 下面借鉴了<多线程的那点儿事(之无锁队列)>的代码,说明两个线程(一个添加一个读取数据)之间的无锁队列,可以不借助线程互斥方法就能够达到并行效果.代码如下: #define MAX_NUMBER 1000L #define STATUS int #define OK 0 #define FALSE -1 typedef struct

多线程编程之顺序锁

一.什么是顺序锁 顺序锁对读写锁的一种优化,使用顺序锁时,读不会被写执行单元阻塞(在读写锁中,写操作必须要等所有读操作完成才能进行).也就是说,当向一个临界资源中写入的同时,也可以从此临界资源中读取,即实现同时读写,但是不允许同时写数据.如果读执行单元在读操作期间,写执行单元已经发生了写操作,那么,读执行单元必须重新开始,这样保证了数据的完整性,当然这种可能是微乎其微.顺序锁的性能是非常好的,同时他允许读写同时进行,大大的提高了并发性. 二.顺序锁的缺陷 顺序锁的缺陷在于,互斥访问的资源不能是指

Linux下多线程编程之互斥锁、条件变量、信号量

1.进程创建 int pthread_create (pthread_t * thread_id, __const pthread_attr_t * __attr, void *(*__start_routine) (void *), void *__restrict __arg); 第一个参数为指向线程标识符的指针,第二个参数用来设置线程属性,第三个参数是线程运行函数的起始地址,最后一个参数是运行函数的参数. 一个实例: void *producer(void *args); pthread_

Linux系统编程@多线程编程

多线程编程 操作系统原理概念 时间片 进程状态 上下文: 对进程来说,就是进程的执行环境,具体就是各个变量和数据,包括所有的寄存器变量.打开的文件.内存信息等. 进程的写时复制:由于一般 fork后面都接着exec,所以,现在的 fork都在用写时复制的技术,顾名思意,就是,数据段,堆,栈,一开始并不复制,由父,子进程共享,并将这些内存设置为只读.直到父,子进程一方尝试写这些区域,则内核才为需要修改的那片内存拷贝副本.这样做可以提高 fork的效率. 线程函数的可重入性:所谓“重入”,常见的情况

Linux多线程编程-互斥锁

互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr); int pthread_mutex_destroy(pthread_mutex_t *mutex); int p

python多线程编程(2): 使用互斥锁同步线程

上一节的例子中,每个线程互相独立,相互之间没有任何关系.现在假设这样一个例子:有一个全局的计数num,每个线程获取这个全局的计数,根据num进行一些处理,然后将num加1.很容易写出这样的代码: # encoding: UTF-8import threadingimport time class MyThread(threading.Thread): def run(self): global num time.sleep(1) num = num+1 msg = self.name+' set

Linux程序设计学习笔记----多线程编程线程同步机制之互斥量(锁)与读写锁

互斥锁通信机制 基本原理 互斥锁以排他方式防止共享数据被并发访问,互斥锁是一个二元变量,状态为开(0)和关(1),将某个共享资源与某个互斥锁逻辑上绑定之后,对该资源的访问操作如下: (1)在访问该资源之前需要首先申请互斥锁,如果锁处于开状态,则申请得到锁并立即上锁(关),防止其他进程访问资源,如果锁处于关,则默认阻塞等待. (2)只有锁定该互斥锁的进程才能释放该互斥锁. 互斥量类型声明为pthread_mutex_t数据类型,在<bits/pthreadtypes.h>中有具体的定义. 互斥量

.NET多线程编程

在.NET多线程编程这个系列我们讲一起来探讨多线程编程的各个方面.首先我将在本篇文章的开始向大家介绍多线程的有关概念以及多线程编程的基础知识;在接下来的文章中,我将逐一讲述.NET平台上多线程编程的知识,诸如System.Threading命名空间的重要类以及方法,并就一些例子程序来作说明. 引言 早期的计算硬件十分复杂,但是操作系统执行的功能确十分的简单.那个时候的操作系统在任一时间点只能执行一个任务,也就是同一时间只能执行一个程序.多个任务的执行必须得轮流执行,在系统里面进行排队等候.由于计