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

C# 中多线程锁的使用经验

C# 中多线程锁的使用经验:全局锁,实例锁

全局锁

        private static object _exeLock = new object();

       static 静态的是全应用程序的资源。如果在一个类里定义了这样一个锁,你在调用使用这个类的时候,是NEW了一个对象,并把这个对象给了一个静态全局变量中保存。这时这个锁就是全局锁了。

        你在调用带锁的方法时会受到【全局锁】的影响。

实例锁

        private object _exeLock = new object();

        影响只在这个对象实例中。

示例

全局锁代码

类的代码

/// <summary>
/// 雷赛板卡 AxisDMC3000
/// </summary>
public class DMC3000 : AxisModel
{public DMC3000() { }public DMC3000(string name) { }/// <summary>/// 全局锁/// </summary>private static object _exeLockAll = new object();/// <summary>/// 对象锁/// </summary>//private object _exeLock = new object();/// <summary>/// 移动到指定位置/// </summary>/// <param name="posname">位置名称</param>/// <returns></returns>public override bool MoveAbs(string posname){var isFinsh = false;lock (_exeLockAll){try{int dis = (int)(GetAxisPosList(posname) * Param.PulseRatio);SetAxisParam();//单轴运动函数//Dist 目标位置,单位:pulse,范围:-134217728~+134217728//posi_mode 运动模式,0:相对坐标模式,1:绝对坐标模式isFinsh = LTDMC.dmc_pmove(CardNum, AxisNum, dis, 1) == 0;}catch (Exception ex){isFinsh = false;WorkFlow.ShowMsgError("MoveAbs(string posname) 异常:" + ex.Message,"MoveAbs(string posname)");}}return isFinsh;}
}

上面的代码中有一个【全局锁】和一个用了【全局锁】的方法

调用这个类时的代码

创建两个类对象

#region 轴
/// <summary>
/// (焊接)X轴 左右移动X轴
/// </summary>
private static DMC3000 _axis_CarryX;/// <summary>
/// (焊接)Y轴 前后移动Y轴
/// </summary>        
private static DMC3000 _axis_CarryY;//Axis_CarryY = 1,/// <summary>
/// 送针X 左右移动
/// </summary>
private static DMC3000 _axis_SongzhengX;
#endregion/// <summary>
/// 初始化 轴
/// </summary>
/// <returns></returns>
public static bool InitAxis()
{var isFinish = false;_axis_CarryX = new DMC3000(AxisType.Axis_CarryX.ToString());_axis_CarryY = new DMC3000(AxisType.Axis_CarryY.ToString());_axis_SongzhengX = new DMC3000(AxisType.Axis_SongzhengX.ToString());return isFinish;
}

上面三个轴都是new的方式生成是三个独立的对象。

但在用线程Task调用MoveAbs方法时你会发现,三个轴的运动情况是一个一个的移动。而不是同时移动的

public static void Test()
{Task.Factory.StartNew(() => {_axis_CarryX.MoveAbs("ToPos");});Task.Factory.StartNew(() => {_axis_CarryY.MoveAbs("ToPos");});Task.Factory.StartNew(() => {_axis_SongzhengX.MoveAbs("ToPos");});
}

原因就是对象里使用对【全局锁】每个对象在调用MoveAbs方法时都会进行排对,第一个线程用完后,第二个线程去用。以此类推。这像就相对于是单线程了,上面开了三个线程去执行,完全没有用和不用Task调用是一样的。这样的效果一定不是我们所希望的。那要怎么解决这个问题呢。

        有人可能会说那就不用锁了。这样不是解决问题了吗?这也是一种解决方法。但我在工作中。发现一个问题就是在不用锁时发现有时轴无法走到指定的点位。在获取轴当前的坐标时也不是我们指定的坐标位。本文就是为解决这个时而出现的多线程问题而写的总结。

        为了达到同步效果又要解决一个轴在多个线程中有调用的情况时。我选择了【对象锁】解决问题。【对象锁】从名称中就可以知道,这锁的范围在对象中,不会影响到其他对象的的调用。这样就可以解决问题。多线程中同时调用MoveAbs方法时进行锁排对,执行和取读当前坐标不会因为多线程为影响。

实例锁代码

/// <summary>
/// 雷赛板卡 AxisDMC3000
/// </summary>
public class DMC3000 : AxisModel
{public DMC3000() { }public DMC3000(string name) { }/// <summary>/// 对象锁/// </summary>private object _exeLock = new object();/// <summary>/// 移动到指定位置/// </summary>/// <param name="posname">位置名称</param>/// <returns></returns>public override bool MoveAbs(string posname){var isFinsh = false;lock (_exeLock){try{int dis = (int)(GetAxisPosList(posname) * Param.PulseRatio);SetAxisParam();//单轴运动函数//Dist 目标位置,单位:pulse,范围:-134217728~+134217728//posi_mode 运动模式,0:相对坐标模式,1:绝对坐标模式isFinsh = LTDMC.dmc_pmove(CardNum, AxisNum, dis, 1) == 0;}catch (Exception ex){isFinsh = false;WorkFlow.ShowMsgError("MoveAbs(string posname) 异常:" + ex.Message,"MoveAbs(string posname)");}}return isFinsh;}
}

代码差别不大就中对像锁中没有使用static关键字。

相关文章:

  • VMwareWorkstation16与Ubuntu 18.04.6 LTS下载与安装
  • Python的基础操作
  • 华为OD应聘感受
  • GUROBI之数学启发式算法Matheuristics
  • Python中的区块链技术与应用
  • Linux 网络套接字编程基础
  • 人工智能在未来的优势
  • SpringBoot使用log4j2将日志记录到文件及自定义数据库
  • Django快速入门
  • Kafka 技术指南:使用、特性、一致性保证与 Golang 中间件应用(下)
  • 【茶话数据结构】查找最短路径——Dijkstra算法详解(保姆式详细图解,步步紧逼,保你学会)
  • 【目标检测经典算法】R-CNN、Fast R-CNN和Faster R-CNN详解系列二:Fast R-CNN图文详解
  • 走进网络世界 了解一些基础知识
  • rabbitmq-spring-boot-start配置使用手册
  • 数字孪生10个技术栈:数据清洗-数据的洗衣机
  • 【个人向】《HTTP图解》阅后小结
  • Angular Elements 及其运作原理
  • codis proxy处理流程
  • Druid 在有赞的实践
  • JAVA并发编程--1.基础概念
  • Java知识点总结(JavaIO-打印流)
  • Just for fun——迅速写完快速排序
  • TypeScript实现数据结构(一)栈,队列,链表
  • 多线程 start 和 run 方法到底有什么区别?
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 类orAPI - 收藏集 - 掘金
  • 如何编写一个可升级的智能合约
  • 使用parted解决大于2T的磁盘分区
  • 问题之ssh中Host key verification failed的解决
  • 小程序测试方案初探
  • Prometheus VS InfluxDB
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • # Apache SeaTunnel 究竟是什么?
  • #android不同版本废弃api,新api。
  • #define、const、typedef的差别
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (规划)24届春招和25届暑假实习路线准备规划
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .apk文件,IIS不支持下载解决
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET 中的轻量级线程安全
  • //解决validator验证插件多个name相同只验证第一的问题
  • /boot 内存空间不够
  • @hook扩展分析
  • @Import注解详解
  • @reference注解_Dubbo配置参考手册之dubbo:reference
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [ 云计算 | AWS 实践 ] Java 如何重命名 Amazon S3 中的文件和文件夹
  • [AIGC] MySQL存储引擎详解
  • [C++]类和对象(中)
  • [CISCN 2019华东南]Web11
  • [Docker]十一.Docker Swarm集群raft算法,Docker Swarm Web管理工具
  • [Godot] 3D拾取