<p>HPC-GAP provides a number of atomic object types. These can be accessed by multiple threads concurrently without requiring explicit synchronization, but can have non-deterministic behavior for complex operations. Atomic lists are fixed-size lists; they can be assigned to and read from like normal plain lists. Atomic records are atomic versions of plain records. Unlike plain records, though, it is not possible to delete elements from an atomic record. The primary use of atomic lists and records is to facilitate storing the result of idempotent operations and to support certain low-level operations. Atomic lists and records can have three different replacement policies: write-once, strict write-once, and rewritable. The replacement policy determines whether an already assigned element can be changed. The write-once policy allows elements to be assigned only once, with subsequent assignments being ignored; the strict write-once policy allows elements also to be assigned only once, but subsequent assignments will raise an error; the rewritable policy allows elements to be assigned different values repeatedly. The default for new atomic objects is to be rewritable. Thread-local records are variants of plain records that are replicated on a per-thread basis.</p>
<p>Atomic lists are created using the <code class="code">AtomicList</code> or <code class="code">FixedAtomicList</code> functions. After creation, they can be used exactly like any other list, except that atomic lists created with <code class="code">FixedAtomicList</code> cannot be resized. Their contents can also be read as normal plain lists using <code class="code">FromAtomicList</code>.</p>
<p>Because multiple threads can read and write the list concurrently without synchronization, the results of modifying the list may be non-deterministic. It is faster to write to fixed atomic lists than to a resizable atomic list.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ AtomicList</code>( <var class="Arg">list</var> )</td><td class="tdright">( function )</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ AtomicList</code>( <var class="Arg">count</var>, <var class="Arg">obj</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">AtomicList</code> is used to create a new atomic list. It takes either a plain list as an argument, in which case it will create a new atomic list of the same size, populated by the same elements; or it takes a count and an object argument. In that case, it creates an atomic list with <var class="Arg">count</var> elements, each set to the value of <var class="Arg">obj</var>.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ MakeFixedAtomicList</code>( <var class="Arg">list</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">MakeFixedAtomicList</code> turns a resizable atomic list into a fixed atomic list.</p>
<div class="example"><pre>
<span class="GAPprompt">gap></span> <span class="GAPinput">a := AtomicList([99]);</span>
<atomic list of size 1>
<span class="GAPprompt">gap></span> <span class="GAPinput">a[2] := 100;</span>
100
<span class="GAPprompt">gap></span> <span class="GAPinput">MakeFixedAtomicList(a);</span>
<fixed atomic list of size 2>
<span class="GAPprompt">gap></span> <span class="GAPinput">a[3] := 101;</span>
Error, Atomic List Element: <pos>=3 is an invalid index for <list>
</pre></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ FromAtomicList</code>( <var class="Arg">atomic_list</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">FromAtomicList</code> returns a plain list containing the same elements as <var class="Arg">atomic_list</var> at the time of the call. Because other threads can write concurrently to that list, the result is not guaranteed to be deterministic.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ ATOMIC_ADDITION</code>( <var class="Arg">atomic_list</var>, <var class="Arg">index</var>, <var class="Arg">value</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">ATOMIC_ADDITION</code> is a low-level operation that atomically adds <var class="Arg">value</var> to <var class="Arg">atomic_list[index]</var>. It returns the value of <var class="Arg">atomic_list[index]</var> after the addition has been performed.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ COMPARE_AND_SWAP</code>( <var class="Arg">atomic_list</var>, <var class="Arg">index</var>, <var class="Arg">old</var>, <var class="Arg">new</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">COMPARE_AND_SWAP</code> is an atomic operation. It atomically compares <var class="Arg">atomic_list[index]</var> to <var class="Arg">old</var> and, if they are identical, replaces the value (in the same atomic step) with <var class="Arg">new</var>. It returns true if the replacement took place, false otherwise.</p>
<p>The primary use of <code class="func">COMPARE_AND_SWAP</code> is to implement certain concurrency primitives; most programmers will not need to use it.</p>
<h4>5.2 <span class="Heading">Atomic records and component objects</span></h4>
<p>Atomic records are atomic counterparts to plain records. They support assignment to individual record fields, and conversion to and from plain records.</p>
<p>Assignment semantics can be specified on a per-record basis if the assigned record field is already populated, allowing either an overwrite, keeping the existing value, or raising an error.</p>
<p>It is not possible to unbind atomic record elements.</p>
<p>Like plain records, atomic records can be converted to component objects using <code class="code">Objectify</code>.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ AtomicRecord</code>( <var class="Arg">capacity</var> )</td><td class="tdright">( function )</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ AtomicRecord</code>( <var class="Arg">record</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">AtomicRecord</code> is used to create a new atomic record. Its single optional argument is either a positive integer, denoting the intended capacity (i.e., number of elements to be held) of the record, in which case a new empty atomic record with that initial capacity will be created. Alternatively, the caller can provide a plain record with which to initially populate the atomic record.</p>
<p>Any atomic record can later grow beyond its initial capacity. There is no limit to the number of elements it can hold other than available memory.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ FromAtomicRecord</code>( <var class="Arg">record</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">FromAtomicRecord</code> returns a plain record copy of the atomic record <var class="Arg">record</var>. This copy is shallow; elements of <var class="Arg">record</var> will not also be copied.</p>
<p>There are three functions that set the replacement policy of an atomic object. All three can also be used with plain lists and records, in which case an atomic version of the list or record is first created. This allows programmers to elide <code class="func">AtomicList</code> (<a href="chap5.html#X7F1353B58414D4C3"><span class="RefLink">5.1-1</span></a>) and <code class="func">AtomicRecord</code> (<a href="chap5.html#X87EA343179BE4BFE"><span class="RefLink">5.2-1</span></a>) calls when the next step is to change their policy.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ MakeWriteOnceAtomic</code>( <var class="Arg">obj</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">MakeWriteOnceAtomic</code> takes a list, record, atomic list, atomic record, atomic positional object, or atomic component object as its argument. If the argument is a non-atomic list or record, then the function first creates an atomic copy of the argument. The function then changes the replacement policy of the object to write-once: if an element of the objectis already bound, then further attempts to assign to it will be ignored.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ MakeStrictWriteOnceAtomic</code>( <var class="Arg">obj</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">MakeStrictWriteOnceAtomic</code> works like <code class="func">MakeWriteOnceAtomic</code> (<a href="chap5.html#X7B76F2AD818492BC"><span class="RefLink">5.3-1</span></a>), except that the replacement policy is being changed to being strict write-once: if an element is already bound, then further attempts to assign to it will raise an error.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ MakeReadWriteAtomic</code>( <var class="Arg">obj</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">MakeReadWriteAtomic</code> is the inverse of <code class="func">MakeWriteOnceAtomic</code> (<a href="chap5.html#X7B76F2AD818492BC"><span class="RefLink">5.3-1</span></a>) and <code class="func">MakeStrictWriteOnceAtomic</code> (<a href="chap5.html#X806C3F0681B847A0"><span class="RefLink">5.3-2</span></a>) in that the replacement policy is being changed to being rewritable: Elements can be replaced even if they are already bound.</p>
<p>Thread-local records allow an easy way to have a separate copy of a record for each individual thread that is accessed by the same name in each thread.</p>
<p>As can be seen above, even though <code class="code">r.x</code> is overwritten in the second thread, it does not affect the value of <code class="code">r.x| in the first thread</code></p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ ThreadLocalRecord</code>( [<var class="Arg">defaults</var>[, <var class="Arg">constructors</var>]] )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">ThreadLocalRecord</code> creates a new thread-local record. It accepts up to two initial arguments. The <var class="Arg">defaults</var> argument is a record of default values with which each thread-local copy is initially populated (this happens on demand, so values are not actually read until needed). The second argument is a record of constructors; parameterless functions that return an initial value for the respective element. Constructors are evaluated only once per thread and only if the respective element is accessed without having previously been assigned a value.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ SetTLDefault</code>( <var class="Arg">record</var>, <var class="Arg">name</var>, <var class="Arg">value</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">SetTLDefault</code> can be used to set the default value of a record field after its creation. Here, <var class="Arg">record</var> is a thread-local record, <var class="Arg">name</var> is the string of the field name, and <var class="Arg">value</var> is the value.</p>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ SetTLConstructor</code>( <var class="Arg">record</var>, <var class="Arg">name</var>, <var class="Arg">func</var> )</td><td class="tdright">( function )</td></tr></table></div>
<p><code class="func">SetTLConstructor</code> can be used to set the constructor of a thread-local record field after its creation, similar to <code class="func">SetTLDefault</code> (<a href="chap5.html#X788AF1CC8111798C"><span class="RefLink">5.4-2</span></a>).</p>
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.