50万奖金+官方证书,深圳国际金融科技大赛正式启动,点击报名 了解详情
写点什么

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

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

关注

评论

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

uni-app黑魔法:小程序自定义组件运行到H5平台

崔红保

小程序 uni-app

芋道 Spring Cloud Alibaba 介绍

艿艿

阿里巴巴 分布式 微服务 Spring Cloud Spring Boot

Flink初体验

数据社

大数据 flink 流计算

人们喜欢彼此制造困难让大家难过

Fenng

用声音在一起,听荔枝CTO丁宁聊UGC声音互动平台的技术世界

ONES 王颖奇

内容 企业架构 互联网

OKR实践中的痛点(1):老板的KR我的O,怎么办?

大叔杨

OKR Scrum 敏捷

初入响应式编程(上)

CD826

spring 微服务 Spring Cloud 响应式编程 reactor

Linux 性能诊断:负载评估入门

RiboseYim

Linux 性能优化

电子书:《Linux Perf Master》

RiboseYim

Linux 性能优化

为什么你的创业公司应该运行在Kubernetes上

云原生

云原生 k8s

近两年影响我的两个重要原则

Selina

一文讲清楚 MySQL 事务隔离级别和实现原理,开发人员必备知识点

古时的风筝

MySQL 数据库 事务隔离级别 mysql事务 数据库事务

对话 CTO〡和 PingCAP CTO 黄东旭聊开源数据库新蓝海

ONES 王颖奇

数据库 分布式 开发者

业务代码必须要做的事情

程序员劝退师

此为开卷

X.F

走出舒适区最好办法别走了,扩大它

乐少

翻译: Effective Go (1)

申屠鹏会

翻译 Go 语言

一个创业者的途中思考

非著名程序员

创业 读书笔记 程序员 重新理解创业 思考

从流程、认知上做稳定的系统演进

Skysper

系统设计 质量管理

【gRPC】Python调用Java的gRPC服务

遇见

Java Python gRPC

写一个开源的 macOS 程序可以赚多少钱?

子骅 luin

node.js redis GitHub 开源 赚钱

WebSphere Application Server运维实践 --从入门到监控

rafe

Java WAS perfservlet visualVM JMX

【Vue3.0 Beta】尝鲜

德育处主任

CSS Java html5 Vue 大前端

业务系统开发程序员常用linux知识

程序员劝退师

Linux

浅谈汽车行业嵌入式软件发布的流程有多复杂

WB

程序员 软件

寻找伴侣最重要的是什么?

二爷

【数据结构】双向链表插入操作的时间复杂度分析

遇见

数据结构 算法 时间复杂度

2020了,各家小程序发展的怎么样?

崔红保

小程序 uni-app

分享多年积累的 macOS 效率工具

张晓辉

macos

毕竟,一生很短,少有圆满

霍太稳@极客邦科技

创业 身心健康 个人成长

测试

Chonge

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