多线程中递归锁的实现

2023-10-27

多线程中递归锁的实现

在上一篇文章中,我已经阐述了多线程中简单锁的实现,可在结束的时候,我就提了那么一个问题,那就是如果在一个链表中进行插入时,要进行查询的操作,如果只是简单的锁,是没法实现的。所以“递归锁”就浮现于世了。

可能有些人看到递归这两个字,有点傻了眼,其实也没什么的,简单的介绍,就是进行简单的计数而已。刚开始引用锁的时候,就产生它,当在锁没有解开的时候,还要继续用锁,就简单的加一,解开一把就减一,当计数为零时,就把锁销毁掉。下面用程序来简单的阐述一下,递归锁是怎么实现的:

1、递归锁接口的定义。(锁的接口的定义已经在上一篇定义过了,这里不再重复)

  1. /*------ recursive_locker.h -------*/
  2. #ifndef _RECURSIVE_H
  3. #define _RECURSIVE_H
  4. #include "locker.h"
  5. Locker* recursive_locker_create(Locker* real_locker);
  6. #endif /*_RECURSIVE_H*/

2、递归锁的实现。

  1. /*------ recursive_locker.c ------*/
  2. #include "recursive_locker.h"
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <assert.h>
  6. #include <string.h>
  7. typedef struct _PrivInfo
  8. {
  9.   Locker*  real_locker;
  10.   pthread_t current_pthread_locker;
  11.   int locker_count;
  12. }PrivInfo;
  13. static int recursive_locker_lock(Locker* thiz)
  14. {
  15.   assert(thiz != NULL);
  16.   PrivInfo* priv = thiz->priv;
  17.   if(priv->current_pthread_locker == pthread_self())
  18.   {
  19.     priv->locker_count ++;
  20.   }
  21.   else
  22.   {
  23.     locker_lock(priv->real_locker);
  24.     priv->lcoker_count = 1;
  25.     priv->current_pthread_locker = pthread_self();
  26.   }
  27.   return 0;
  28. }
  29. static int recursive_locker_unlock(Locker* thiz)
  30. {
  31.   assert(thiz != NULL);
  32.   PrivInfo* priv = thiz->priv;
  33.   if(priv->current_>pthread_locker == pthread_self())
  34.   {
  35.     if(priv->locker_count == 1)
  36.     {
  37.       priv->locker_count = 0;
  38.       priv->current_pthread_locker = 0;
  39.       locker_unlock(priv->real_locker);
  40.     }
  41.     else
  42.     {
  43.           priv->locker_count --;
  44.     }
  45.   }
  46.   else
  47.   {
  48.      assert(!"error");
  49.   }
  50.   return 0;
  51. }
  52. static void recursive_locker_destroy(Locker* thiz)
  53. {
  54.   assert(thiz != NULL);
  55.   PrivInfo* priv = thiz->priv;
  56.   locker_destroy(priv->real_locker);
  57.   free(thiz);
  58.   return ;
  59. }
  60. Locker* recursive_locker_create(Locker* real_locker)
  61. {
  62.   Locker* thiz = (Locker* )malloc(sizeof(Locker) + sizeof(PrivInfo));
  63.   PrivInfo* priv = thiz->priv;
  64.   priv->real_locker = real_locker;
  65.   priv->current_pthread_locker = 0;
  66.   priv->locker_count = 0;
  67.   thiz->lock = recursive_locker_lock;
  68.   thiz->unlock = recursive_locker_unlock;
  69.   thiz->locker_destroy = recursive_locker_destroy;
  70.   return thiz;
  71. }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多线程中递归锁的实现 的相关文章

  • 超线程简介

    超线程简介 超线程的技术原理 超线程技术在一个物理核上模拟两个逻辑核 两个逻辑核具有各自独立的寄存器 eax ebx ecx msr等等 和APIC 但会共享使用物理核的执行资源 包括执行引擎 L1 L2缓存 TLB和系统总线等等
  • 如何在C语言中调用shell命令

    如何在C语言中调用shell命令 在linux操作系统中 很多shell命令使用起来非常简单 这些shell命令的程序实现已经被底层实现好 有时候需要在程序中调用shell命令 这样可以就不用在控制台上手动输入shell命令了 下面就以三个
  • 一道有趣的GOOGLE面试题——找出至少一个重复元素

    一道有趣的GOOGLE面试题 找出至少一个重复元素 题目 一个大小为n的数组 里面的数都属于范围 0 n 1 有不确定的重复元素 找到至少一个重复元素 要求O 1 空间和O n 时间 这个题目要求用O n 的时间复杂度 这意味着只能遍历数组
  • Linux下编译链接多个源文件

    Linux下编译链接多个源文件 add c 的内容 int Add int a int b int result result a b return result minus c 的内容 int Minus int a int b int
  • 一道创新工场面试题详解:共打了多少鱼?

    一道创新工场面试题详解 共打了多少鱼 题目 abcde五人打渔 打完睡觉 a先醒来 扔掉1条鱼 把剩下的均分成5分 拿一份走了 b再醒来 也扔掉1条 把剩下的均分成5份 拿一份走了 然后cde都按上面的方法取鱼 问他们一共打了多少条鱼 解法
  • 用户级线程和内核级线程

    用户级线程和内核级线程 根据在用户空间还是在核心实现多线程机制 线程又被分为用户级线程 User Level Thread 和内核级线程 Kernel Level Thread
  • 海量数据随机抽样问题(蓄水池问题)

    海量数据随机抽样问题 蓄水池问题 随机抽样问题表示如下 要求从N个元素中随机的抽取k个元素 其中N无法确定 这种应用的场景一般是数据流的情况下 由于数据只能被读取一次 而且数据量很大 并不能全部保存 因此数据量N是无法在抽样开始时确定的 但
  • 反向代理服务器的工作原理

    反向代理服务器的工作原理 代理服务器按照其使用方式和作用 分为正向代理服务器 反向代理服务器和透明代理服务器 正向代理要求客户端自己设置代理服务器的地址 反向代理则设置在服务器端 因而客户端无须任何设置 透明代理只能设置在网关上 由于反向代
  • 关系数据库的特点

    关系数据库的特点 数据库管理系统将具有一定结构的数据组成一个集合 它主要具有以下几个特点 1 数据的结构化 数据库中的数据并不是杂乱无章 毫不相干的 它们具有一定的组织结构 属于同一集合的数据具有相似的特征 2 数据的共享性 在一个单位的各
  • linux设备驱动之构造和运行模块

    构造和运行模块 今天开始学习 linux设备驱动程序 第三版这本书 在看到第二章的构造和运行模块的时候 我在linux平台上做了一个小测试 下面就让我说下 在宿主机上安装开发工具和下载linux源码 要求版本号和目标机上的linux内核版本
  • linux上的一些系统监测工具简介

    linux上的一些系统监测工具简介 在linux中提供了很多有用的工具 以方便开发人员调试和评测服务器程序 下面介绍几个常用的工具 tcpdump nc strace lfos netstat vmstat ifstat和mpstat 1
  • 2.6内核的通用的编译步骤

    2 6内核的通用的编译步骤 1 下载源码并解压 虽然我们可以将内核源码存放在任何自己找得到的地方 但通常还是会将内核源码下载到 usr src目录并解压 cd usr src wget ftp kernel org pub linux ke
  • Linux服务器系统内存监控方法详解

    Linux服务器系统内存监控方法详解 内存是Linux内核所管理的最重要的资源之一 内存管理系统是操作系统中最为重要的部分 因为系统的物理内存总是少于系统所需要的内存数量 虚拟内存就是为了克服这个矛盾而采用的策略 系统的虚拟内存通过在各个进
  • 字符设备驱动程序

    字符设备驱动程序 下面以一个简单的例子来讲解下字符设备驱动程序 首先需要有内核环境 Linux下的设备驱动程序被组织为一组完成不同任务的函数的集合 通过这些函数使得Windows的设备操作犹如文件一般 在应用程序看来 硬件设备只 是一个设备
  • 把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,不能申请额外的空间

    把一个字符串的大写字母放到字符串的后面 各个字符的相对位置不变 不能申请额外的空间 题目以及要求 把一个字符串的大写字母放到字符串的后面 各个字符的相对位置不变 不能申请额外的空间 我的实现类似冒泡排序 代码为 include
  • syslog协议介绍

    syslog协议介绍 syslog架构 Unix Linux系统中的大部分日志都是通过一种叫做syslog的机制产生和维护的 syslog是一种标准的协议 分为客户端和服务器端 客户端是产生日志消息的一方 而服务器端负责接收客户端发送来的日
  • x86中内存管理寄存器

    x86中内存管理寄存器 处理器提供了4个内存管理寄存器 GDTR LDTR IDTR和TR 用于指定内存分段管理所用系统表的基地址 如图4 2所示 处理器为这些寄存器的加载和保存提供了特定的指令 GDTR LDTR IDTR和TR都是段基址
  • gdb调试多进程程序和多线程程序

    gdb调试多进程程序和多线程程序 平时一般用gdb直接调试短小的程序 好像我还没调试过多进程和多线程程序呢 1 gdb调试多进程程序 如果一个进程通过fork系统调用创建了子进程 gdb会继续调试原来的进程 子进程则正常运行 常用的有两种方
  • SO_LINGER选项

    SO LINGER选项 SO LINGER选项用于控制close系统调用在关闭TCP连接时的行为 默认情况下 当我们使用close系统调用来关闭一个socket时 close将立即返回 TCP模块负责把该socket对应的TCP发送缓冲区中
  • dword ptr指令讲解

    dword ptr指令讲解 8086CPU的指令 可以处理两种尺寸的数据 byte和word 所以在机器指令中要指明 指令进行的是字操作还是字节操作 对于这个问题 汇编语言中用一下方法处理 1 通过寄存器名指明要处理的数据的尺寸 例如 下面

随机推荐

  • 计算机组成与设计第五版课后答案ch04,数据结构第4章例题与答案

    四章 一 选择题 1 下面关于串的的叙述中 哪一个是不正确的 北方交通大学 2001 一 5 2分 a 串是字符的有限序列 b 空串是由空格构成的串 c 模式匹配是串的一种重要运算 d 串既可以采用顺序存储 也可以采用链式存储 2 若串s1
  • Linux 【基础】 xshell 简单使用

    xshell 首先xshell是什么 Xshell 是一个强大的安全终端模拟软件 它支持SSH1 SSH2 以及Microsoft Windows 平台的TELNET 协议 Xshell 通过互联网到远程主机的安全连接以及它创新性的设计和特
  • 聊天机器人案例

    HTMl
  • Android 学习之《第一行代码》第二版 笔记(二十三)Material Design 实战 —— 卡片式布局

    实现基础 Android 学习之 第一行代码 第二版 笔记 二十二 Material Design 实战 悬浮按钮和可交互提示 卡片式布局 卡片式布局是 Materials Design 中提出的一个新的概念 可以让页面中的元素看起来就像在
  • Python_OpenCV_TensorFlow微型仿真深度学习 Raspberry Pi 自动驾驶车

    视觉OpenCV 配置 Raspberry Pi 配置 TensorFlow OpenCV自主车道导航 import cv2 frame cv2 imread home pi DeepCar driver data road1 240x32
  • linux内核I2C子系统学习(二)

    下面具体分析如何写第一部分 主控芯片的i2c驱动分为2个步骤 写总线驱动 选了个主控芯片 比如 S3C8900 自己瞎编的芯片 在driver i2c busses i2c s3c2410 c中没有找到这个芯片的I2C支持 总线驱动支持 倒
  • Cesium 设置视角的两种方式

    作为开源WebGIS三维可视化领域的翘楚 Cesium中可以可以添加不同的Entity实体数据 也可以添加各种各样的模型数据 那么当我们添加好数据之后 如何设置视角以便于观察呢 这里介绍两种不同的方式设置视角 一种是设置添加数据的orien
  • java开发常见错误_java开发常见错误汇集

    1 一直出不来结果 原来是把el表达式写错了 后面多写了一个 谨记 2 浏览器报错 如 POST http localhost 8081 AntFooder shopcar addToShopCar 400 jquery 1 8 3 min
  • 春日

    春河日语风中雪 山花烂漫无旧人 朝看青川山岳早 屋棚夜下早还家 粉黛陶冠春暖意 笑含茹妆玉着衫 望风巍然而却下 不知天外九重天 潇潇暮雨冬来去 莺鸟桃花又一春 文人墨客山茶草 酸草含嚼苦味深 羽墨掸空不见色 横刀断水水无痕
  • Thinkpad VMware 安装虚拟机出现此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态(问题解决方法)

    今天在使用VMware打算在机器中安装新的虚拟机时 出现 此主机支持 Intel VT x 但 Intel VT x 处于禁用状态 错误如下 提示信息 此主机支持 Intel VT x 但 Intel VT x 处于禁用状态 如果已在 BI
  • mysql中innodb和myisam对比及索引原理区别

    InnoDB和MyISAM是很多人在使用MySQL时最常用的两个表类型 这两个表类型各有优劣 5 7之后就不一样了 1 事务和外键 InnoDB具有事务 支持4个事务隔离级别 回滚 崩溃修复能力和多版本并发的事务安全 包括ACID 如果应用
  • 【Linux】磁盘或内存 占用比较高要怎么排

    当 Linux 磁盘空间满了时 请注意 在进行任何删除操作之前 请确保你知道哪些文件可以安全删除 并备份重要文件 以免意外丢失数据 当 Linux 磁盘空间满了时 可以按照以下步骤进行排查 检查磁盘使用情况 运行 df h 命令来查看磁盘使
  • 【愉快的使用go.mod应用自己开发的package包(库)】

    GO引用自己写的模块1 仅使用 根 路径的go mod 在go中开启了GO111MODULE on 就可以使用go语言自带的mod来管理自己开发的项目的依赖 从而可以摆脱传统的必须把依赖的模块放在GOROOT或者GOPATH下的src pk
  • js数据结构之队列及其应用

    对列 刚好和栈相反 它是先进先出的 只允许在队列的一头添加元素 另一头删除元素 class queue constructor this arr 插入元素 enqueue ele this arr push ele 删除元素 dequeue
  • GLM:ChatGLM的基座模型

    介绍 ChatGLM 6B https github com THUDM ChatGLM 6B 主要是能够让我们基于单卡自己部署 ChatGLM的基座是GLM General Language Model Pretraining with
  • 手把手教你solidworks中的齿轮配合

    手把手教你solidworks中的齿轮配合 1 建立装配图 在装配体中导入两个齿轮 2 把齿轮1固定改为浮动 3 如下图所示选中隐藏 显示主要基准面 4 选中上视基准面和右视基准面 点击参考面之下的基准轴如下图所示 打上勾 建立基准轴后 点
  • SQL注入--报错和盲注

    目录 报错注入 floor函数报错注入 extractvalue 函数报错注入 updatexml 函数报错注入 盲注 布尔盲注 时间盲注 报错注入 文章内容篇幅较长 请认真研读 回顾之前的文章 sql注入基础 了解到sql注入的分类有 基
  • EXCEL-VBA:弹出对话框,打开文件(指定扩展名)两种方法

    方法一 Dim FileName As String FileName Application GetOpenFilename Excel 文件 xls xlsx 方法二 With Application FileDialog msoFil
  • Shell脚本入门 07:进程与信号

    文章目录 目的 进程相关 子进程 子Shell 进程替换 信号相关 发送信号 捕获信号 总结 目的 进程与信号中Linux中比较重要的内容 Shell脚本编写调试时也会涉及一些进程与信号相关的内容 这篇文章将对相关内容做个简单的记录 进程相
  • 多线程中递归锁的实现

    多线程中递归锁的实现 在上一篇文章中 我已经阐述了多线程中简单锁的实现 可在结束的时候 我就提了那么一个问题 那就是如果在一个链表中进行插入时 要进行查询的操作 如果只是简单的锁 是没法实现的 所以 递归锁 就浮现于世了 可能有些人看到递归