写点什么

C# 4.0“修复了”死锁问题

  • 2009-03-22
  • 本文字数:1085 字

    阅读完需:约 4 分钟

几年前,Eric Lippert 注意到根据同样源代码进行优化构建和非优化构建会导致不同的潜在死锁。这个问题会在 C# 4.0 中被“修复”。“修复”放在引号当中,是因为解决方式也有它自己的问题。

最初的问题可能来自于编译器在把 IL 转化为机器代码的时候,根据你是否打开或关闭优化器和调试器,以非一致的行为插入了 no-op 指令。Lippert 提道:

回想一下,lock(obj){body}实际上就是下面代码的语法:> var temp = obj;

Monitor.Enter(temp);
try { body }
finally { Monitor.Exit(temp); }

这里的问题是,如果编译器在 Monitor.Enter 和受 try 保护的区域之间生成了 no-op 指令,那么运行时就有可能 在 Monitor.Enter 之后和 try 之前抛出线程终止异常。在这样的情形下,finally 不会执行,那么也就产生了程序锁泄漏,程序有可能出现死 锁。如果在非优化和优化构建中不存在差异,就不存在这个问题。

不过。这个解决方案 [译注:C# 4.0 是将 Monitor.Enter() 移入到 try 子句中,并在 Enter 的时候会传递一个引用值,标识锁是否被占用。在 finnally 子句中,会首先判断锁是否被占用,如果被占用,则释放锁。] 也有它自己的问题。据 Eric 说,“保持一致与不一致相比,完全就是五十步笑百步。它仍然存在很大的问 题…这样生成的代码所 [译注:生成的代码是指编译器将 lock 转换为 IL,实际上就相当于使用 Monitor 的语法] 隐含的意义就是认为死锁程序是可能 发生的最糟糕的事情。这种说法未必准确。”

锁的目的是为了保护可变资源,或者换句话说,是为了避免可变资源的多个潜在用户访问资源已被破坏的版本。4.0 版本的现有解决方案并没有包含回滚到原始状态的功能,也没有保证可变资源的完整性。强行进入 lock 语句的 finally 子句、释放锁以及允许访问任意等待 线程(该线程占用了已被破坏的资源),都有可能引发异常。这一解决方案在结果的一致性、降低死锁的可能性和对访问被破坏状态可能付出的代价方面,做出了折 衷。该问题尤其在多线程编程中会存在风险。

这个特定的折衷是对两种糟糕结果的选择:程序死锁,还是不再保护重要资源的状态。所谓“两害相权取其轻”,当我们进行多线程编程时,就必须在多个设计决策与权衡中做出一个选择。

这篇文章反响热烈, 一些开发人员认为这类设计问题不只限于多线程,在“安全锁”和“安全异常”之间也存在不同之处。Lippert 也同意多线程只会让难处理的问题更难,“正 确获得锁仅仅是万里长征的第一步”,你的设计还需要考虑其他各种异常,以及在异常发生后如何处理它们。大量的回复者指出终止线程的危险性,并部分同意 Lippert 所说的“终止异常纯粹就是找死”。

查看英文原文: C# 4.0 “Fixes” Deadlock Issue

2009-03-22 21:522266
用户头像

发布了 254 篇内容, 共 61.5 次阅读, 收获喜欢 2 次。

关注

评论

发布
暂无评论
发现更多内容

独家!阿里技术人限产的MySQL高级笔记及面试宝典,简直开挂

996小迁

Java MySQL 架构 面试 技术宅

连续一个月每天加班到凌晨三点,终于把Java程序员必知必会的计算机底层操作系统知识和网络知识整理出来了,已整理成文档!

Java架构之路

Java 程序员 架构 编程语言 操作系统

在网上被MG坑审过却一直延迟无法取出到账怎么解决 (LGF微7998)

Geek_db0f9e

独家!阿里技术人限产的MySQL高级笔记及面试宝典,学完简直开挂

Java架构追梦

Java MySQL 数据库 架构 面试

spring-boot-route(二十一)quartz实现动态定时任务

Java旅途

Java Spring Boot quartz

美腻了!Java资深架构师带你深度学习字节跳动的亿级流量+高并发

Java架构追梦

Java 学习 架构 面试 微服务

BIGDATA+AI Meetup 2020第二季·上海站开启报名!

Apache Flink

大数据 AI

视频面试跟传统面试的区别及优点

anyRTC开发者

ios 音视频 WebRTC RTC 安卓

解锁华为云AI如何助力无人车飞驰“新姿势”,大赛冠军有话说

华为云开发者联盟

AI 无人驾驶

MySQL-技术专题-MySQL的主从同步

码界西柚

【运维思考】运维对象快速扩展,监控如何精准实时的覆盖?

嘉为蓝鲸

PaaS 运维自动化 监控管理平台 监控系统 监控告警

一套完整的后台管理系统(附源码),非常实用!

程序员生活志

管理系统

Java程序员还在为没有项目经验感到苦恼?快来看看GitHub上最火的SpringCloud微服务商城系统开源项目,附全套教程!

Java架构之路

Java 程序员 架构 面试 编程语言

华为云瑶光:打通云边端界限,为企业云上业务带来最优解

华为云开发者联盟

华为 云服务

云原生在京东丨云原生时代下的监控:如何基于云原生进行指标采集?

京东科技开发者

云原生

身为程序员你们经历过大厂面试吗?本文为大家解决大厂必问的MySQL调优问题

Java架构师迁哥

杂谈:一文了解工业4.0

soolaugust

工业互联网 工业4.0

基于注解的参数校验器Hibernate Validator

HelloLittleRain

Java springboot 参数校验 Hibernate-Validator

WebSocket硬核入门:200行代码,教你徒手撸一个WebSocket服务器

JackJiang

html5 网络编程 websocket 即时通讯

最火的HTAP数据库 京东智联云新一代分布式数据库TiDB架构揭秘

京东科技开发者

数据库 #TiDB

1分钟带你入门Redux、React-Redux

Leo

大前端 React Redux React-Redux

原来AI也可以如此简单!教你从0到1开发开源知识问答机器人

华为云开发者联盟

开源 AI 机器人

vivo 基于原生 RabbitMQ 的高可用架构实践

vivo互联网技术

高可用 RabbitMQ 中间件

iOS 性能优化实践:头条抖音如何实现 OOM 崩溃率下降50%+

iOSer

性能优化 OOM ios开发 头条抖音 OOM崩溃

技术实操丨HBase 2.X版本的元数据修复及一种数据迁移方式

华为云开发者联盟

数据 数据迁移 原数据

Java程序员想要进阶,想了解Java服务器的深层高阶知识,Netty绝对是一个必须要过的门槛。

Java架构之路

Java 程序员 架构 编程语言 随笔杂谈

膜拜!阿里技术总监纯手打的《MySQL笔记》内部资料限时分享

Java架构师迁哥

【活动预告】2020中国系统架构师大会:即构受邀分享实时音视频服务架构实践

ZEGO即构

架构师 高并发系统设计 技术分享

LeetCode题解:98. 验证二叉搜索树,递归中序遍历完成后再判断,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

1分钟带你入门 Redux 中间件

Leo

大前端 中间件 Redux Redux中间件

让核显大展拳脚:Intel Iris Xe显卡

E科讯

C# 4.0“修复了”死锁问题_.NET_David West_InfoQ精选文章