- 浏览: 399627 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (309)
- xaml C# wpf (0)
- scala java inner clas (1)
- Tools UML Eclipse UML2 (1)
- Timer .NET Framework (1)
- perl (6)
- python function paramter (1)
- Python Docstring (1)
- Python how to compare types (1)
- Python (8)
- java (5)
- C# (76)
- C# WPF (0)
- p4 (0)
- WPF (46)
- .net (6)
- xaml (1)
- javascript (40)
- windows (10)
- scala (4)
- winform (1)
- c++ (48)
- tools (12)
- cmd (1)
- os (0)
- CI (0)
- shell (0)
- C (2)
- haskell (49)
- functional (1)
- tool (1)
- gnu (1)
- linux (1)
- kaskell (0)
- svn (0)
- wcf (3)
- android (1)
最新评论
Reprint - atomicity, volatility and immutability are different, part one
- 博客分类:
- C#
There is one of the triplet of the Eric Lippert's blog on "Atomicity, volatility and Immutability" part I, the original post is availabe here : http://blogs.msdn.com/b/ericlippert/archive/2011/05/26/atomicity-volatility-and-immutability-are-different-part-one.aspx
Atomicity, volatility and immutability are different, part one
I get a fair number of questions about atomicity, volatility, thread safety, immutability and the like; the questions illustrate a lot of confusion on these topics. Let's take a step back and examine each of these ideas to see what the differences are between them.
First off, what do we mean by "atomic"? From the Greek ἄτομος, meaning "not divisible into smaller parts", an "atomic" operation is one which is always observed to be done or not done, but never halfway done. The C# specification clearly defines what operations are "atomic" in section 5.5. The atomic operations are reads and writes of variables of any reference type, or, effectively, any built-in value type that takes up four bytes or less, like int, short and so on. Reads and writes of variables of value types that take more than four bytes, like double, long and decimal, are not guaranteed to be atomic by the C# language.
What does it mean for a read and write of an int to be atomic? Suppose you have static variables of type int. X is 2, Y is 1, Z is 0. Then on one thread we say:
Z = X;
and on another thread:
X = Y
Each thread does one read and one write. Each read and write is itself atomic. What is the value of Z? Without any synchronization, the threads will race. If the first thread wins then Z will be 2. If the second thread wins then Z will be 1. But Z will definitely be one of those two values, you just can't say which.
David Corbin asks in a comment to my previous entry whether immutable structs are guaranteed to be written atomically regardless of their size. The short answer is no; why would they be? Consider:
struct MyLong
{
public readonly int low;
public readonly int high;
public MyLong(low, high)
{
this.low = low;
this.high = high;
}
}
Ignore for the moment the evil that is public fields. Suppose we have a fields Q, R and S of type MyLong initialized to (0x01234567, 0x0BADF00D), (0x0DEDBEEF, 0x0B0B0B0B) and (0, 0), respectively. On two threads we say:
S = Q;
and
Q = R;
We have two threads. Each thread does one read and one write, but the reads and writes are not atomic. They can be divided! This program is actually the same as if the two threads were:
S.low = Q.low;
S.high = Q.high;
and
Q.low = R.low;
Q.high = R.high;
Now, you can't do this because that's writing to a readonly field outside a constructor. But the CLR is the one enforcing that rule; it can break it! (We'll come back to this in the next episode; things are even weirder than you might think.) Value types are copied by value; that's why they're called value types. When copying a value type, the CLR doesn't call a constructor, it just moves the bytes over one atomic chunk at a time. In practice, maybe the jitter has special registers available that allow it to move bigger chunks around, but that's not a guarantee of the C# language. The C# language only goes so far as to guarantee that the chunks are not smaller than four bytes.
Now the threads can race such that perhaps first S.low = Q.low runs, then Q.low = R.low runs, then Q.high = R.high runs, and then S.high = Q.high runs, and hey, S is now (0x0DEDBEEF, 0x0BADF00D), even though that was neither of the original values. The values have been splinched, as Hermione Granger would say (were she a computer programmer).
(And of course, the ordering above is not guaranteed either. The CLR is permitted to copy the chunks over in any order it chooses; it could be copying high before low, for example.)
The name "MyLong" was of course no accident; in effect, a two-int readonly struct is how longs are implemented on 32 bit chips. Each operation on the long is done in two parts, on each 32 bit chunk. The same goes for doubles, the same goes for anything larger than 32 bits. If you try reading and writing longs or doubles in multiple threads on 32 bit operating systems without adding some sort of locking around it to make the operation atomic, your data are highly likely to get splinched.
The only operations that are guaranteed by the C# language to be atomic without some sort of help from a lock or other synchronization magic are those listed above: individual reads and writes of variables of the right size. In particular, operations like "increment" and "decrement" are not atomic. When you say
that's a syntactic sugar for "read i, increment the read value, write the incremented value back to i". The read and write operations are guaranteed to be atomic, but the entire operation is not; it consists of multiple atomic operations and therefore is not itself atomic. Two attempts to increment i on two different threads could interleave such that one of the increments is "lost".
There are many techniques for making non-atomic operations into atomic operations; the easiest is simply to wrap every access to the variable in question with a lock, so that it is never the case that two threads are messing with the variable at the same time. You can also use the Interlocked family of helper methods which provide atomic increment, atomic compare-and-exchange, and so on.
Have a lovely Memorial Day weekend, American readers. I'm spending my Memorial Day weekend marrying a close personal friend(*). Should be fun!
Next time: readonly inside a struct is the moral equivalent of cheque kiting, plus ways you can make the atomicity guarantees stronger or weaker.
(*) Actually, I am marrying *two* close personal friends. To each other, even!
发表评论
-
wpf - example to enhance ComboBox for AutoComplete
2014-09-19 15:56 1976first let’s see an example ... -
Investigate and troubleshoot possible memory leak issue of .NET application
2014-07-31 10:42 0Hi All, I would like to sh ... -
C# – CoerceValueCallback合并、替换元数据值
2013-08-05 21:59 1925Topic: C# – CoerceValueCallbac ... -
wpf – ListView交替背景色
2013-07-02 20:56 6551Wpf – Alternate background col ... -
C# - 简单介绍TaskScheduler
2013-06-29 17:18 12038标题: C# - 简单介绍TaskSchedulerTit ... -
c# - Get enum from enum attribute
2013-06-27 21:32 1244DescriptionAttribute gives the ... -
C# - PInvoke, gotchas on the RegisterClassEx and the CreateWindowEx
2013-06-24 13:49 2571I get an exception message li ... -
c# - Use PInvoke to create simple win32 Application
2013-06-24 11:59 10946In this post, .net platform h ... -
c# - Linq's Select method as the Map function
2013-06-19 18:47 1287If you comes from a functiona ... -
c# - Tips of Linq expression Any to determine if a collection is Empty
2013-06-19 18:29 938When you are @ the linq expres ... -
myth buster - typeof accepting array of types not acceptable
2013-06-19 17:17 813I have seen from some book whe ... -
windows - trying to create WIN32 application with PInvoke
2013-06-19 14:34 0While it is stupid to do such ... -
WPF - Setting foreground color of Entire window
2013-06-13 16:00 1918You might as well as I would s ... -
WPF - Enhanced TabControl - TabControlEx aka Prerendering TabControl
2013-06-13 13:12 5330As an opening word, let's che ... -
wpf - ControlTemplate and AddLogicChild/RemoveLogicalChild
2013-06-10 15:42 1185Recently I was trying to debug ... -
c# - P/Invoke, DllImport, Marshal Structures and Type conversions
2013-06-05 15:25 1712P/Invoke as in the following q ... -
c# - A study on the NativeWindow - encapsulate window handle and procedure
2013-06-05 14:40 6091NativeWindow gives you a way t ... -
WCF - Notify server when client connects
2013-06-03 18:19 1221It is sometimes very importan ... -
wcf - Debug to enable Server exception in Fault message
2013-06-03 15:47 1091WCF will be able to send back ... -
c# - determine if a type/object is serialzable
2013-05-30 16:35 867In WCF, primitives type are s ...
相关推荐
本资源"reprint-0.3.0.tar.gz"就是从PyPI官网获取的一个Python库——`reprint`的特定版本,版本号为0.3.0。 `reprint`库主要解决的是在Python程序中动态更新控制台输出的问题。在开发过程中,我们有时需要实时显示...
Gartner在2018年发布的研究笔记中,特别提到了应用安全测试(AST)市场的现状和发展趋势。研究笔记的标题为“应用安全测试市场的魔法象限”,它由分析师Ayal Tirosh、Dionisio Zumerle和Mark Horvath撰写,涉及...
最新版,2013版,英文原版,Highly readable paperback reprint of one of the great time-tested classics in the field of signal processing Together with the reprint of Part III and the new Part IV,...
Eliminates the need to deal with the different available Fingerprint APIs, including Imprint and Samsung Pass. Fixes undocumented bugs and idiosyncrasies in the underlying APIs. Supports more Imprint ...
Processing of signals is often facilitated by transforming to a representation in which individual components are statistically independent. In such a natural coordinate system, the components of the ...
reprint 是一个适用于 Python 2/3 的简易变量绑定与多行输出刷新的库
reprint 使用说明 直接从datasource,dbgrid,stringgrid导入数据, 只需简单设置,不用手工制作,即可生成您需要的报表,具有预览功能。即可自定义纸张,又可适应 打印机默认纸张。各种打印设置,功能更强大。 ...
This book contains information obtained from authentic and highly regarded sources. Reasonable efforts have been made to publish reliable data and information, but the author and publisher cannot ...
reprint 使用说明 本人长期使用delphi做数据库的开发,报表控件使用Quickrpt,在打印上经常遇到一些问题,于是自己经常编写一部分打印的程序,经过总结开发了这个控件。 本控件可打印 datasource,dbgrid,...
reprint是一个Python 2/3模块,用于绑定变量并刷新终端中的多行输出。 用于计算Unicode字符宽度的解决方案来自 特征 Python 2/3支持 简单的变量绑定和变量更改后自动刷新命令行 同时多行刷新,每行绑定到不同的...
- 本书的再版信息(Softcover reprint of the hardcover 2nd edition 2004)表明,该书不仅一次印刷,而且对之前的版本进行了更新和再版,说明其内容具有一定的时效性和持续的学术价值。 - 书的封面设计、排版印刷...
This book contains information obtained from authentic and highly regarded sources. Reasonable efforts have been made to publish reliable data and information, but the author and publisher cannot ...
Introduction to Finite and Spectral Element Methods Using MATLAB®Second ... If any copyright material has not been acknowledged please write and let us know so we may rectify in any future reprint.
不推荐使用请改用 ,它支持... 在您的Application.onCreate ,使用Reprint.initialize(this)初始化Reprint。 这将加载棉花糖模块和Spass模块(如果包含)。 然后,在代码中的任何位置,都可以调用Reprint.authenticate
The changes in this printing are mainly limited to the correction of typographical and other minor errors which I have become aware of since 1986. A couple of changes should be mentioned explicitly. ...