当前位置: 首页 > news >正文

rust学习(recursive mutex 实现)

问题:

编写如下代码的时候出现死锁:

pub fn test_double_lock() {let t = Arc::new(Mutex::new(1));let t1 = t.clone();let t2 = t.clone();let h = std::thread::spawn(move || {println!("hello trace1");let l1 = t1.lock().unwrap();println!("hello trace2");let l2 = t2.lock().unwrap();println!("hello trace3");});h.join().unwrap();
}

输出卡在了"hello trace2",这个原因主要是Rust的mutex是非recursive的 。所以同一个线程中如果出现2次获取锁,就会死锁掉。哈哈,网上查了一下,很多人都说recursive lock是垃圾代码,要修复。鉴于个人能力,很多这样的代码我都改不掉,所以我用Rust实现了一个recursive的锁。。。

主要数据结构

struct TarMutexRecord {m_count:u32, //1m_ownerid:Option<ThreadId> //2
}pub struct TarMutex {m_record:Mutex<TarMutexRecord>, //3m_cond:Condvar //4
}

1.获取锁计数,如果计数到0的话,唤醒其他等待线程去拿锁

2.锁的owner,每次拿到锁以后记录拿锁线程,防止其他线程调用unlock释放

3.#1,#2的数据记录

4.如果锁的owner不是当前线程,则调用这个m_cond等待。当锁释放的时候,如果计数为0,唤醒m_cond等待的线程。

主要接口

pub fn lock(&self) {let tid = std::thread::current().id();loop {let mut lock = self.m_record.lock().unwrap();if lock.m_count == 0 {//no ownerlock.m_count += 1; //1lock.m_ownerid = Some(tid); //2return;} else if let Some(ownerid) = lock.m_ownerid{if ownerid == tid {lock.m_count += 1;//3return;}}self.m_cond.wait(lock);//4}}pub fn unlock(&self) {let tid = std::thread::current().id();let mut lock = self.m_record.lock().unwrap();if let Some(ownerid) = lock.m_ownerid{if ownerid == tid {lock.m_count -= 1;//5if lock.m_count == 0 {lock.m_ownerid = None;self.m_cond.notify_all();//6}}}}

1.如果当前线程没有获取过锁,则只要计数+1

2.记录当前获取到锁线程id

3.如果当前线程已经获取过锁,则只要计数+1

4.如果当前有其他线程正在拿锁,则等待

5.锁释放时先计数-1

6.如果当前计数为0,表明锁都已经释放,直接唤醒所有等待锁的队列。

相关文章:

rust学习(recursive mutex 实现)

问题&#xff1a; 编写如下代码的时候出现死锁&#xff1a; pub fn test_double_lock() {let t Arc::new(Mutex::new(1));let t1 t.clone();let t2 t.clone();let h std::thread::spawn(move || {println!("hello trace1");let l1 t1.lock().unwrap();println…...

DasViewer可以添加照片到里面吗?点开就可以看照片?

DasViewer主要是三维模型浏览器&#xff0c;二维可以添加矢量和正射影像&#xff0c;航片暂不支持。 DasViewer是由大势智慧自主研发的免费的实景三维模型浏览器,采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便…...

python蓝桥杯选数

文章目录 前言一、题意二、代码1.代码的实现2.读入数据 总结 前言 本题涉及到很多python中的知识点&#xff0c;比如combinations&#xff08;列表的组合&#xff09;应用&#xff0c;以及素数的判断 一、题意 已知 n 个整数 x1,x2,…,xn,以及一个整数 k&#xff08;k&#x…...

联想电脑开启虚拟化失败,开启虚拟化却提示还没有开启虚拟化

安装虚拟机的时候&#xff0c; 电脑要开启虚拟化&#xff0c; Intel VT&#xff0c; 去BIOS开启了&#xff0c; 但是依然报错&#xff0c;说虚拟化处于禁用状态。 解决方案&#xff1a; 去联想官方&#xff0c;下载BIOS更新包&#xff0c;更新BIOS。 更新文档&#xff1a; 联…...

物联网农业四情在线监测系统

TH-Q2随着科技的飞速发展和信息化时代的来临&#xff0c;物联网技术在各个领域都取得了显著的应用成果。其中&#xff0c;物联网农业四情在线监测系统作为农业现代化的重要组成部分&#xff0c;正在为农业生产带来革命性的变革。 一、物联网农业四情在线监测系统的概念 物联网…...

MySQL8.3.0 主从复制方案(master/slave)

一 、什么是MySQL主从 MySQL主从&#xff08;Master-Slave&#xff09;复制是一种数据复制机制&#xff0c;用于将一个MySQL数据库服务器&#xff08;主服务器&#xff09;的数据复制到其他一个或多个MySQL数据库服务器&#xff08;从服务器&#xff09;。这种复制机制可以提供…...

大数据相关组件安装及使用

自学大数据相关组件 持续更新中。。。 一、linux安装docker 1、更新yum sudo yum update2、卸载docker旧版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine3、…...

【攻防世界】web2(逆向解密)

进入题目环境&#xff0c;查看页面信息&#xff1a; <?php $miwen"a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";function encode($str){$_ostrrev($str);// echo $_o;for($_00;$_0<strlen($_o);$_0){$_csubstr($_o,$_0,1);$__ord($_c)1;…...

Linux文件查找命令详解——以CentOS为例

Linux文件查找命令详解——以CentOS为例 在Linux系统中&#xff0c;文件查找是一项非常重要的任务。无论是系统管理员还是普通用户&#xff0c;都需要掌握一些基本的文件查找命令。本文将详细介绍Linux中常用的文件查找命令&#xff0c;并以CentOS为例&#xff0c;展示如何使用…...

【JavaEE】浅谈线程(一)

线程 前言线程的由来线程是什么线程的属性线程更高效的原因举个例子&#xff08;线程便利性的体现&#xff09; 多线程代码线程并发执行的代码jconsole(观测多线程) 线程的调度问题创建线程的几种方法1&#xff09;通过继承Thread 重写run2&#xff09;使用Runnable接口 重写ru…...

深度解析SPARK的基本概念

关联阅读博客文章&#xff1a; 深入理解MapReduce&#xff1a;从Map到Reduce的工作原理解析 引言&#xff1a; 在当今大数据时代&#xff0c;数据处理和分析成为了企业发展的重要驱动力。Apache Spark作为一个快速、通用的大数据处理引擎&#xff0c;受到了广泛的关注和应用。…...

FreeGPT3.5 开源软件

GPT-3.5不需要付费&#xff0c;也不需要注册用户&#xff0c;可以直接使用了&#xff0c;官方彻底开放了API接口。 该API政策一放开&#xff0c;GitHub很快就已经出现了一个开源项目FreeGPT35&#xff0c;可以自动生成key调用GPT3.5的API接口&#xff0c;再也用不着注册账号和申…...

AI绘本生成解决方案,快速生成高质量的AI绘本视频

美摄科技凭借其深厚的技术积累和前瞻性的市场洞察力&#xff0c;近日推出了一款面向企业的AI绘本生成解决方案&#xff0c;旨在通过智能化、自动化的方式&#xff0c;帮助企业快速将文字内容转化为生动有趣的绘本视频&#xff0c;从而提升内容传播效率&#xff0c;增强品牌影响…...

RabbitMQ3.13.x之九_Docker中安装RabbitMQ

RabbitMQ3.13.x之_Docker中安装RabbitMQ 文章目录 RabbitMQ3.13.x之_Docker中安装RabbitMQ1. 官网2. 安装1 .拉取镜像2. 运行容器 3. 访问 1. 官网 rabbitmq - Official Image | Docker Hub 2. 安装 1 .拉取镜像 docker pull rabbitmq:3.13.0-management2. 运行容器 # lates…...

【操作系统】STM32-操作系统——持续更新

【操作系统】STM32-操作系统——持续更新 文章目录 前言一、ucosii二、freertos1.介绍2.移植 总结 前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、ucosii UCOSII移植到STM32F103C8T6上之移植记录&#xff08;一&#xff09; UCOSII移植到ST…...

Redux Toolkit+TypeScript最佳实践

Redux-Toolkit是为了简化使用Redux繁琐的步骤&#xff0c;可以j降低使用useReducer与useContext管理状态的频率&#xff0c;而且起到项目中状态管理规范和约束化的效果。 阅读本文需要的前置知识&#xff1a;React、Redux、Typescript、Redux hooks。 Redux-Toolkit使用步骤 …...

假期别闲着:REST API实战演练之创建Rest API

1、创建实体类&#xff0c;模拟实体对象 创建一个类&#xff0c;模拟数据数据库来存储数据&#xff0c;这个类就叫Person。 其代码如下&#xff1a; package com.restful;public class Person {private String name;private String about;private int birthYear;public Perso…...

C++模仿qq界面

#include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//设置窗口的大小this->resize(645,497);//设置窗口名字this->setWindowTitle("QQ");//设置窗口图标this->setWindowIcon(QIcon("C:\\zhouzhouMyfile\\qt_proj…...

3D模型在线轻量化工具

在计算机图形学领域&#xff0c;3D模型简化工具是一种强大的工具&#xff0c;用于减少模型的面数&#xff0c;以提高模型在渲染和处理过程中的性能。本文将全面介绍为何需要简化模型、简化的方法、常见的简化算法以及一款三维模型优化产品 的使用方法&#xff0c;帮助读者更好地…...

去中心化社交媒体:分析 Facebook 在区块链平台上的角色

在当今数字时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分。然而&#xff0c;随着人们对数据隐私和信息控制的关注不断增加&#xff0c;传统的中心化社交媒体平台也面临着越来越多的质疑和挑战。为了应对这些挑战&#xff0c;越来越多的人开始探索去中心化社…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

华为OD机考-机房布局

import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

redis和redission的区别

Redis 和 Redisson 是两个密切相关但又本质不同的技术&#xff0c;它们扮演着完全不同的角色&#xff1a; Redis: 内存数据库/数据结构存储 本质&#xff1a; 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能&#xff1a; 提供丰…...

第八部分:阶段项目 6:构建 React 前端应用

现在&#xff0c;是时候将你学到的 React 基础知识付诸实践&#xff0c;构建一个简单的前端应用来模拟与后端 API 的交互了。在这个阶段&#xff0c;你可以先使用模拟数据&#xff0c;或者如果你的后端 API&#xff08;阶段项目 5&#xff09;已经搭建好&#xff0c;可以直接连…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...