10 月 23 - 25 日,QCon 上海站即将召开,现在购票,享9折优惠 了解详情
写点什么

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:522481
用户头像

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

关注

评论

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

不要小看一个Redis!阿里最新开源Redis核心原理+应用实践,涵盖了Redis的所有操作

程序员小毕

面试 程序人生 中间件 Java后端 redis 底层原理

从零开始学Graph Database:什么是图

华为云开发者联盟

人工智能 华为云 图数据库 图计算引擎 企业号十月 PK 榜

算法统治者!打破传统方式,即将爆火的Leetcode刷题指南

Geek_0c76c3

Java 数据库 开源 程序员 开发

【Java深入学习】join再理解

Geek_65222d

10月月更

Java的跨平台和环境搭建

共饮一杯无

jdk java基础 10月月更 java环境搭建

Java 隐藏 Word 文档中的特定段落

在下毛毛雨

如何使用流程 中的 DataObject 并为流程设置租户

江南一点雨

Java springboot workflow flowable

【LeetCode】优势洗牌Java题解

Albert

LeetCode 10月月更

欢迎奥看科技加入openGauss社区

“智领医疗 数创未来”活动成功举办,海量数据携手openGauss为医疗数字化创新赋能

openGauss 3.1.0版本正式发布 | 七个方面全面增强

云图说丨带你了解GaussDB(for Redis)双活解决方案

华为云开发者联盟

数据库 数据资产 云数据库 企业号十月 PK 榜

openGauss 社区 2022 年 9 月运作报告

携手武汉白鱀豚保护基金会,英特尔以责任为先多举推动环保公益

科技之家

Node.js TLSSocket 库里涉及到的证书链的概念简介

汪子熙

JavaScript node.js 后端开发 SAP 10月月更

欢迎新大陆软件加入openGauss社区

如何实时、高效地处理如此海量的路况数据

华为云开发者联盟

人工智能 华为云 图片处理 智慧交通 企业号十月 PK 榜

DDD 建模案例分享

Bright

敏捷 DDD TDD

云和恩墨大讲堂 x openGauss Meetup x 鲲鹏生态孵化营(上海站)圆满落幕

首份把架构三原则拆开来讲的“架构师宝典”,电子版已上线

Geek_0c76c3

Java 数据库 开源 程序员 开发

企业社会责任先行,公益课程推动环保科普教育

科技之家

说说 Spring 定时任务如何大规模企业级运用

阿里巴巴云原生

spring 阿里云 云原生

【活动报名】共建云原生开源生态 PolarDB × Curve 线下 Meetup 来袭!(杭州站)

阿里云数据库开源

数据库 阿里云 开源 polarDB

OpenHarmony有氧拳击之应用端开发

OpenHarmony开发者

OpenHarmony

defi质押挖矿存币生息理财系统开发

开发微hkkf5566

欢迎海天起点加入openGauss社区

Github 访问量过百万!阿里内部springcloud手册, 实至名归

Geek_0c76c3

Java 数据库 程序员 开发

cuda+cudnn ubuntu20安装

Ayosh

欢迎数造科技加入openGauss社区

带你认识什么是“回流重绘”

华为云开发者联盟

html 前端 浏览器 企业号十月 PK 榜

啃完这些Spring知识点,我竟吊打了阿里面试官(附面经+笔记)

Geek_0c76c3

Java 数据库 开源 面试 开发

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