unity C#什么是线程锁,以及使用案例

文章目录

    • 原理
      • 1. **互斥**(Mutual Exclusion):
      • 2. **缓存一致性与内存屏障**:
      • 3. **操作系统的支持**:
      • 4. **编程语言级别的实现**:
      • 5. **避免死锁**:
      • 图示
    • 实例1
    • 实例2

原理

线程锁的原理主要是为了在多线程环境下提供对共享资源访问的同步机制,防止多个线程同时读写同一数据导致的数据不一致、竞态条件和死锁等问题。以下是线程锁基本工作原理的概述:

1. 互斥(Mutual Exclusion):

线程锁的核心原理是互斥,即在同一时刻,只有一个线程能够获得锁并执行临界区(Critical Section)内的代码。当一个线程进入临界区时,它会先获取锁,此时其他试图获取该锁的线程将被阻塞或挂起,直到持有锁的线程执行完临界区内的代码,并释放锁。

2. 缓存一致性与内存屏障

在现代CPU架构中,为了提高性能,每个处理器都有自己的高速缓存,这就可能导致不同线程看到的数据不一致。线程锁在硬件层面通常配合内存屏障(Memory Barrier)使用,确保缓存中的数据在锁的获取和释放时与主内存保持一致,即修改后的数据会被及时刷新到主内存,而其他线程在获取锁后能从主内存重新加载最新的数据。

3. 操作系统的支持

在操作系统层面,比如Linux系统中,通过pthread_mutex_t这样的互斥量来实现线程锁。操作系统内核提供了原子操作来管理这些互斥量的状态,使得加锁、解锁的过程对于所有参与竞争的线程都是可见且有序的。

4. 编程语言级别的实现

在C#等高级编程语言中,可以通过关键字如lock(C#)或者synchronized(Java)来简化线程锁的使用。例如,在C#中,lock (obj)语句会隐式地调用Monitor类的Enter和Exit方法,从而实现对指定对象的加锁和解锁操作。

5. 避免死锁

为了避免死锁的发生,线程锁的使用需要遵循一定的规则,如避免循环等待锁的情况,以及在持有锁的情况下尽量不要尝试获取其他锁(除非满足特定的锁顺序)。

总结起来,线程锁通过强制单一线程在某一时刻独占资源,以及协调各个线程之间的执行顺序,来达到多线程环境下的资源共享安全和数据一致性。

图示

在这里插入图片描述

在Unity中,线程锁(Thread Lock)是一种同步机制,用于保护多线程环境下的共享资源不被多个线程同时访问和修改。由于Unity引擎本身主要运行在一个单线程(即主线程)上,但现代Unity项目中经常使用多线程处理耗时操作,如网络通信、文件I/O、计算密集型任务等,这时线程锁就显得尤为重要。

Unity中的线程锁通常采用C#的标准库System.Threading命名空间下的Mutex、Monitor或Semaphore类来实现,最常用的是Monitor类以及其提供的Enter和Exit方法,或者更简洁的lock关键字。

实例1

例如,假设我们有一个在多线程环境中需要安全访问和修改的共享数据结构:

public class ThreadSafeExample : MonoBehaviour
{// 共享资源private Queue<string> messageQueue = new Queue<string>();private object queueLock = new object(); // 创建一个对象作为锁// 线程A:添加消息到队列private void EnqueueMessage(string msg){lock (queueLock) // 使用lock语句进行加锁{messageQueue.Enqueue(msg);Debug.Log("Enqueued message: " + msg);}}// 线程B:从队列中取出并处理消息private void ProcessNextMessage(){string msg;lock (queueLock) // 同样在此区域加锁{if (messageQueue.Count > 0){msg = messageQueue.Dequeue();}else{msg = null;}}if (msg != null){Debug.Log("Processing message: " + msg);// 这里处理消息...}}// 启动线程private void StartThreads(){Thread sendThread = new Thread(EnqueueMessages);Thread receiveThread = new Thread(ProcessMessages);sendThread.Start();receiveThread.Start();}
}

在这个例子中,queueLock对象作为线程锁来确保当一个线程正在向队列中添加消息时,另一个线程不会同时尝试从队列中移除消息。通过使用lock关键字,我们可以创建一段互斥代码块,同一时刻只有一个线程能够执行这段代码,从而避免了竞态条件和其他并发问题。

实例2

当然,线程锁的使用场景非常广泛,下面是一个Unity中使用线程进行异步加载资源,并利用线程锁确保资源安全加载和访问的例子:

using UnityEngine;
using System.Collections;
using System.Threading;
using System.Collections.Generic;public class ThreadSafeResourceLoader : MonoBehaviour
{private readonly object resourceLock = new object();private Dictionary<string, Texture2D> loadedTextures = new Dictionary<string, Texture2D>();public void LoadTextureAsync(string texturePath){var thread = new Thread(() =>{Texture2D texture = null;// 异步加载资源WWW www = new WWW("file://" + texturePath);while (!www.isDone) { /* 等待加载完成 */ }if (string.IsNullOrEmpty(www.error)){texture = www.texture;}else{Debug.LogError("Failed to load texture: " + www.error);}// 使用线程锁安全地将加载好的资源添加到字典lock (resourceLock){loadedTextures[texturePath] = texture;}});thread.Start();}public Texture2D GetLoadedTexture(string texturePath){Texture2D texture = null;// 使用线程锁安全地从字典中获取已加载的资源lock (resourceLock){loadedTextures.TryGetValue(texturePath, out texture);}return texture;}
}

在这个例子中,LoadTextureAsync方法在新线程中异步加载纹理资源,加载完成后通过线程锁resourceLock安全地将加载好的纹理添加到loadedTextures字典中。同时,在主线程或其他线程调用GetLoadedTexture方法时,同样需要通过线程锁确保在读取已加载纹理时不会发生竞态条件。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/629789.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI对决:ChatGPT与文心一言的比较

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 引言ChatGPT与文心一言的比较Chatgpt的看法文心一言的看法Copilot的观点chatgpt4.0的回答 模型的自我评价自我评价 ChatGPT的优势在这里插入图片描述 文…

【送书活动七期】CMeet系列 技术生态沙龙:技术人职业交流会·杭州场-转鸿蒙 对应用开发来说是否是职业发展新机会

CSDN致力于促进城市区域内尖端新兴技术开发者交流,提供开放自由的切磋平台。在近期热议的话题中,“华为鸿蒙系统不再兼容安卓应用”的消息成了程序员们广泛关注并引发思考的问题。 因此便有了我们此次的活动探讨议题! 目录 题外话开场简单介绍活动主办方介绍活动话题讨论升职加…

微信小程序-----全局配置与页面配置

目录 前言 全局配置文件 一、window 1. 小程序窗口的组成部分 2. window 节点常用的配置项 3. 设置导航栏的标题 4. 设置导航栏的背景色 5. 设置导航栏的标题颜色 6. 全局开启下拉刷新功能 7. 设置下拉刷新时窗口的背景色 8. 设置下拉刷新时 loading 的样式 9. 设置…

dolphinscheduler分布式集群部署指南(小白版)

1.Apache DolphinScheduler概述 官方文档地址&#xff1a;https://dolphinscheduler.apache.org/zh-cn/docs/3.1.9 1.1.DolphinScheduler简介 摘自官网&#xff1a;Apache DolphinScheduler 是一个分布式易扩展的可视化DAG工作流任务调度开源系统。适用于企业级场景&#xf…

Hcie datacom实验手册哪里下载!

一、官方下载 首先&#xff0c;最直接的方式就是从华为官方网站下载Hcie Datacom实验手册。作为华为认证体系的核心资料&#xff0c;官方下载的内容是最全面、最准确的。您只需要访问华为官方网站&#xff0c;在搜索框中输入“Hcie Datacom实验手册”&#xff0c;即可找到相应…

十、Qt 操作PDF文件

《一、QT的前世今生》 《二、QT下载、安装及问题解决(windows系统)》《三、Qt Creator使用》 ​​​ 《四、Qt 的第一个demo-CSDN博客》 《五、带登录窗体的demo》 《六、新建窗体时&#xff0c;几种窗体的区别》 《七、Qt 信号和槽》 《八、Qt C 毕业设计》 《九、Qt …

考研英语打卡

[爱心]长难句分享第三十一天解析 [玫瑰]【词汇】&#xff1a;• astonishing [əˈstɑːnɪʃɪŋ] adj. 令人惊讶的• purchase [ˈpɜːrtʃəs] n. 购买• upmarket [ˌʌpˈmɑːrkɪt] adj. 高级的• grocery [ˈɡroʊsəri] n. 食品杂货店• chain [tʃeɪn] n. 连锁店…

【Linux驱动】Linux的中断系统 | 中断的重要数据结构

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux驱动》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 &#x1f3c0;Linux系统的中断⚽中断分类软中断和硬中断中断的上半部和下半部 ⚽tasklet⚽工…

普冉32位单片机 PY32C642,M0+内核,1.7 V ~ 5.5 V宽工作电压

PY32C642 单片机采用高性能的 32 位 ARM Cortex-M0内核&#xff0c;宽电压工作范围。嵌入 24Kbytes Flash 和 3 Kbytes SRAM 存储器&#xff0c;最高工作频率 24 MHz。包含多种不同封装类型产品。工作温度范围为-40C ~ 85C&#xff0c;工作电压范围 1.7 V ~ 5.5 V。1 路 12 位A…

深度强化学习的变道策略:Harmonious Lane Changing via Deep Reinforcement Learning

偏理论&#xff0c;假设情况不易发生 摘要 多智能体强化学习的换道策略&#xff0c;不同的智能体在每一轮学习后交换策略&#xff0c;达到零和博弈。 和谐驾驶仅依赖于单个车辆有限的感知结果来平衡整体和个体效率&#xff0c;奖励机制结合个人效率和整体效率的和谐。 Ⅰ. 简…

在Excel中如何打开VBA,这里提供两种方法

想在Excel中创建或添加自己的自定义Visual Basic脚本吗&#xff1f;第一步是了解如何在Excel中打开VBA编辑器。 在易用性和整体功能方面&#xff0c;没有其他电子表格应用程序能与Excel相提并论。无论你想做什么&#xff0c;只要你能深入挖掘Excel的深层菜单&#xff0c;就有很…

正点原子imx6ull网络环境配置:开发板和电脑通过网线直连、电脑WiFi上网

1.硬件连接 开发板通过网线连接电脑。电脑连接wifi 2.VMware设置 2.1添加桥接模式和NAT模式 1&#xff09;打开vm设置 2&#xff09;设置网络适配器为桥接模式&#xff0c;不要勾选 “赋值物理网络连接状态” 3&#xff09; 添加一个网络适配器并设置成NAT模式&#xff0c;…

阿里云服务器怎么样?阿里云服务器优势、价格及常见问题

阿里云服务器ECS英文全程Elastic Compute Service&#xff0c;云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;阿里云提供多种云服务器ECS实例规格&#xff0c;如ECS经济型e实例、通用算力型u1、ECS计算型c7、通用型g7、GPU实例等&#xff0c;阿里云服务器网al…

vue3.2二次封装antd vue 中的Table组件,原有参数属性不变

vue3.2中的<script setup>语法 在项目中多处使用到表格组件,所以进行了一个基础的封装,主要是通过antd vue 中表格的slots配置项,通过配合插槽来进行封装自定义表格; 这次主要的一个功能是编辑之后变成input框 修改了之后变成完成发送请求重新渲染表格&#xff1a; 子…

redis数据安全(二)数据持久化 RDB

目录 一、RDB快照持久化 原理 二、RDB快照持久化配置&#xff08;redis.conf&#xff09;&#xff1a; 三、触发RDB备份&#xff1a; 1、自动备份&#xff0c;需配置备份规则&#xff1a; 2、手动执行命令备份&#xff08;save | bgsave&#xff09;&#xff1a; 3、flus…

Unity Shader 的模板测试效果

模板测试是渲染管线中逐片元操作的一环&#xff0c;它的作用是筛选出指定模板的片元&#xff0c;而不符合模板的片元会被舍弃&#xff0c;从而做到一个遮罩的效果。 以下是Unity中实践的一个效果&#xff1a; 场景中可以看出&#xff0c;熊模型和茶壶模型都在差不多的位置&am…

用原型实现Class的各项语法

本人之前对Class一直不够重视。平时对原型的使用&#xff0c;也仅限于在构造函数的prototype上挂属性。原型尚且用不着&#xff0c;更何况你Class只是原型的一颗语法糖&#xff1f; 直到公司开始了一个webgis项目&#xff0c;使用openlayers。看了下openlayers的代码&#xff0…

头像空白问题

当用户没有设置头像时&#xff0c;我们可以使用用户名第一个字来当头像 主要涉及一个截取&#xff0c;截取字符串第一个字 变量名.charAt(0) 如果变量名为null或者undefine 那么就会报错 使用可选链操作符 &#xff1f; 当前面的值为nul或undefine时&#xff0c;就不会执行…

HTML--CSS--盒子模型

在CSS模型中&#xff0c;所有元素都可以看做是一个盒子&#xff0c;这个盒子的组成部分&#xff1a; content 内容&#xff0c;文本或者图片 padding 内边距&#xff0c;定义内容到边框的距离 margin 外边距&#xff0c;定义当前元素与其他元素之间的距离 border 边框&#xff…

第10章 通信业务

文章目录 10.1.1 通信行业1、通信行业的界定2、通信行业的特点 10.1.2 通信企业10.1.3 通信终端1、通信终端的分类2、终端发展趋势 10.2.1 通信业务的定义及分类10.2.2 基础电信业务1、第一类基础电信业务A11 固定通信业务A12 蜂窝移动通信业务A13 第一类卫星通信业务A14 第一类…