Content deleted Content added
Add new source for section on C# |
Bluelink 2 books for verifiability (prndis)) #IABot (v2.0.1) (GreenC bot |
||
Line 235:
In [[C Sharp (programming language)|C#]], <code>volatile</code> ensures that code accessing the field is not subject to some thread-unsafe optimizations that may be performed by the compiler, the CLR, or by hardware. When a field is marked <code>volatile</code>, the compiler is instructed to generate a "memory barrier" or "fence" around it, which prevents instruction reordering or caching tied to the field. When reading a <code>volatile</code> field, the compiler generates an ''acquire-fence'', which prevents other reads and writes to the field, including those in other threads, from being moved ''before'' the fence. When writing to a <code>volatile</code> field, the compiler generates a ''release-fence''; this fence prevents other reads and writes to the field from being moved ''after'' the fence.<ref name="Albahari">{{cite web |last1=Albahari |first1=Joseph |title=Part 4: Advanced Threading |url=http://www.albahari.com/threading/part4.aspx#_Nonblocking_Synchronization |website=Threading in C# |publisher=O'Reilly Media |accessdate=9 December 2019 |archiveurl=http://www.albahari.info/threading/threading.pdf|archivedate=27 April 2011|url-status=live}}</ref>
Only the following types can be marked <code>volatile</code>: all reference types, <code>Single</code>, <code>Boolean</code>, <code>Byte</code>, <code>SByte</code>, <code>Int16</code>, <code>UInt16</code>, <code>Int32</code>, <code>UInt32</code>, <code>Char</code>, and all enumerated types with an underlying type of <code>Byte</code>, <code>SByte</code>, <code>Int16</code>, <code>UInt16</code>, <code>Int32</code>, or <code>UInt32</code>.<ref>{{cite book |last1=Richter |first1=Jeffrey |title=CLR Via C# |url=https://archive.org/details/clrviac00rich_000 |url-access=limited |publisher=Microsoft Press |date=February 11, 2010 |pages=[https://archive.org/details/clrviac00rich_000/page/n200 183] |chapter=Chapter 7: Constants and Fields |isbn=978-0-7356-2704-8}}</ref> (This excludes value [[struct]]s, as well as the primitive types <code>Double</code>, <code>Int64</code>, <code>UInt64</code> and <code>Decimal</code>.)
Using the <code>volatile</code> keyword does not support fields that are [[Evaluation strategy#Call by reference|passed by reference]] or [[Closure (computer programming)|captured local variables]]; in these cases, <code>Thread.VolatileRead</code> and <code>Thread.VolatileWrite</code> must be used instead.<ref name="Albahari"/>
In effect, these methods disable some optimizations usually performed by the C# compiler, the JIT compiler, or the CPU itself. The guarantees provided by <code>Thread.VolatileRead</code> and <code>Thread.VolatileWrite</code> are a superset of the guarantees provided by the <code>volatile</code> keyword: instead of generating a "half fence" (ie an acquire-fence only prevents instruction reordering and caching that comes before it), <code>VolatileRead</code> and <code>VolatileWrite</code> generate a "full fence" which prevent instruction reordering and caching of that field in both directions.<ref name="Albahari"/> These methods work as follows:<ref>{{cite book |last1=Richter |first1=Jeffrey |title=CLR Via C# |url=https://archive.org/details/clrviac00rich_000 |url-access=limited |publisher=Microsoft Press |date=February 11, 2010 |pages=
*The <code>Thread.VolatileWrite</code> method forces the value in the field to be written to at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to <code>VolatileWrite</code> and any later program-order loads and stores must occur after the call.
*The <code>Thread.VolatileRead</code> method forces the value in the field to be read from at the point of the call. In addition, any earlier program-order loads and stores must occur before the call to <code>VolatileRead</code> and any later program-order loads and stores must occur after the call.
|