Atomic updates: Difference between revisions

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 23:
 
=={{header|8th}}==
<syntaxhighlight lang=Forth"forth">var bucket
var bucket-size
 
Line 130:
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Discrete_Random;
Line 231:
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang=AutoHotkey"autohotkey">Bucket := [], Buckets := 10, Originaltotal = 0
loop, %Buckets% {
Random, rnd, 0,50
Line 276:
{{works with|BBC BASIC for Windows}}
The BBC BASIC interpreter is single-threaded so the 'concurrent' tasks are implemented by timer events. In this context an 'atomic' update means one which takes place within a single BASIC statement, so it cannot be 'interrupted'. Two (or more) buckets can be updated atomically by making them RETURN parameters of a procedure.
<syntaxhighlight lang="bbcbasic"> INSTALL @lib$+"TIMERLIB"
DIM Buckets%(100)
Line 335:
 
{{libheader|pthread}}
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
Line 449:
===With OpenMP===
Compiled with <code>gcc -std=c99 -fopenmp</code>. The <code>#pragma omp critical</code> ensures the following block is entered by one thread at a time.
<syntaxhighlight lang=C"c">#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
Line 499:
 
return 0;
}</syntaxhighlight>Output:<syntaxhighlight lang="text">1000 1000 1000 1798 1000 1000 1000 1000 202 1000 Sum: 10000
595 800 2508 2750 470 1209 283 314 601 470 Sum: 10000
5 521 3339 1656 351 1038 1656 54 508 872 Sum: 10000
Line 515:
- The previous implementation tracked a "swapped" state - which seems a harder way to tackle the problem. You need to acquire the locks in the correct order, not swap i and j
 
<syntaxhighlight lang="csharp">
using System; //Rand class
using System.Threading; //Thread, Mutex classes
Line 657:
 
{{works with|C++11}}
<syntaxhighlight lang="cpp">#include <algorithm>
#include <array>
#include <chrono>
Line 752:
=={{header|Clojure}}==
Function returning a new map containing altered values:
<syntaxhighlight lang="lisp">(defn xfer [m from to amt]
(let [{f-bal from t-bal to} m
f-bal (- f-bal amt)
Line 760:
(assoc m from f-bal to t-bal))))</syntaxhighlight>
Since clojure data structures are immutable, atomic mutability occurs via a reference, in this case an atom:
<syntaxhighlight lang="lisp">(def *data* (atom {:a 100 :b 100})) ;; *data* is an atom holding a map
(swap! *data* xfer :a :b 50) ;; atomically results in *data* holding {:a 50 :b 150}</syntaxhighlight>
Now for the test:
<syntaxhighlight lang="lisp">(defn equalize [m a b]
(let [{a-val a b-val b} m
diff (- a-val b-val)
Line 788:
=={{header|Common Lisp}}==
Depends on libraries in Quicklisp. STMX is a library that provides Software Transactional Memory.
<syntaxhighlight lang="lisp">(ql:quickload '(:alexandria :stmx :bordeaux-threads))
 
(defpackage :atomic-updates
Line 826:
(bt:make-thread (lambda () (runner (lambda () (random 1.0))))))</syntaxhighlight>
{{out}}
<syntaxhighlight lang="lisp">ATOMIC-UPDATES> (scenario)
#<SB-THREAD:THREAD "Anonymous thread" RUNNING {10058441D3}>
ATOMIC-UPDATES> (loop repeat 3 do (print-buckets) (sleep 1))
Line 840:
This implements a more scalable version than most of the other languages, by using a lock per bucket instead of a single lock for the whole array.
 
<syntaxhighlight lang="d">import std.stdio: writeln;
import std.conv: text;
import std.random: uniform, Xorshift;
Line 981:
This example uses a Java AWT window to display the current state of the buckets.
 
<syntaxhighlight lang="e">#!/usr/bin/env rune
pragma.syntax("0.9")
 
Line 1,120:
[0,11,7,0,4,16,7,0,10,0] = 55
</pre>
<syntaxhighlight lang=Erlang"erlang">
-module( atomic_updates ).
-export( [buckets/1, buckets_get/2, buckets_get_all/1, buckets_move_contents/4, task/0] ).
Line 1,212:
 
=={{header|Euphoria}}==
<syntaxhighlight lang="euphoria">function move(sequence s, integer amount, integer src, integer dest)
if src < 1 or src > length(s) or dest < 1 or dest > length(s) or amount < 0 then
return -1
Line 1,313:
The Buckets class is thread safe and its private higher-order Lock function ensures that locks are taken out in order (to avoid deadlocks):
 
<syntaxhighlight lang="fsharp">
open System.Threading
 
Line 1,391:
This program performs a million concurrent transfers. Typical output is:
 
<syntaxhighlight lang="fsharp">
[|100; 100; 100; 100; 100; 100; 100; 100; 100; 100|] = 1000
[|119; 61; 138; 115; 157; 54; 82; 58; 157; 59|] = 1000
Line 1,454:
=={{header|FreeBASIC}}==
{{trans|Run Basic}}
<syntaxhighlight lang="freebasic">Randomize Timer
Dim Shared As Uinteger cubo(1 To 10), a, i
For i As Uinteger = 1 To 10
Line 1,498:
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
Line 1,661:
=={{header|Groovy}}==
Solution:
<syntaxhighlight lang="groovy">class Buckets {
 
def cells = []
Line 1,771:
So, at any given time, the current value map is either in the MVar or being examined or replaced by one thread, but not both. The IntMap held by the MVar is a pure immutable data structure (<code>adjust</code> returns a modified version), so there is no problem from that the ''display'' task puts the value back before it is done printing.
 
<syntaxhighlight lang="haskell">module AtomicUpdates (main) where
 
import Control.Concurrent (forkIO, threadDelay)
Line 1,861:
The following only works in Unicon:
 
<syntaxhighlight lang="unicon">global mtx
 
procedure main(A)
Line 1,914:
=={{header|Java}}==
{{works with|Java|8+}}
<syntaxhighlight lang="java">import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
 
Line 2,037:
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using StatsBase
 
function runall()
Line 2,119:
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.2.0
 
import java.util.concurrent.ThreadLocalRandom
Line 2,222:
=={{header|Lasso}}==
Lasso thread objects are thread-safe by design.
<syntaxhighlight lang="lasso">define atomic => thread {
data
private buckets = staticarray_join(10, void),
Line 2,310:
=={{header|Logtalk}}==
The following example can be found in the Logtalk distribution and is used here with permission. Works when using SWI-Prolog, XSB, or YAP as the backend compiler.
<syntaxhighlight lang="logtalk">
:- object(buckets).
 
Line 2,422:
Sample output:
 
<syntaxhighlight lang="logtalk">
?- buckets::start.
Sum of all bucket values: 52
Line 2,440:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">transfer[bucks_, src_, dest_, n_] :=
ReplacePart[
bucks, {src -> Max[bucks[[src]] - n, 0],
Line 2,473:
The program must be compiled with option <code>--threads:on</code>.
 
<syntaxhighlight lang=Nim"nim">import locks
import math
import os
Line 2,617:
Uses a lock for every bucket. Enforces a locking order to avoid deadlocks.
 
<syntaxhighlight lang="oz">declare
%%
%% INIT
Line 2,717:
 
Sample output:
<syntaxhighlight lang="oz">buckets(50 50 50 50 50 50 50 50 50 50 ,,,) sum: 5000
buckets(24 68 58 43 78 85 43 66 14 48 ,,,) sum: 5000
buckets(36 33 59 38 39 23 55 51 43 45 ,,,) sum: 5000
Line 2,729:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
use 5.10.0;
 
Line 2,783:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">(notonline)-->
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (no threads or critical sections in JavaScript)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">nBuckets</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">20</span>
Line 2,853:
child processes to handle the tasks, as this is the standard way
for general PicoLisp applications.
<syntaxhighlight lang=PicoLisp"picolisp">(seed (in "/dev/urandom" (rd 8)))
 
(de *Buckets . 15) # Number of buckets
Line 2,932:
 
=={{header|PureBasic}}==
<syntaxhighlight lang=PureBasic"purebasic">#Buckets=9
#TotalAmount=200
Global Dim Buckets(#Buckets)
Line 3,022:
This code uses a ''threading.Lock'' to serialize access to the bucket set.
 
<syntaxhighlight lang="python">from __future__ import with_statement # required for Python 2.5
import threading
import random
Line 3,109:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">#lang racket
 
(struct bucket (value [lock #:auto])
Line 3,234:
{{trans|Ruby}}
{{works with|Rakudo|2016.07}}
<syntaxhighlight lang=perl6"raku" line>#| A collection of non-negative integers, with atomic operations.
class BucketStore {
Line 3,314:
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Atomic updates
 
Line 3,366:
 
=={{header|Ruby}}==
<syntaxhighlight lang=Ruby"ruby">require 'thread'
 
# A collection of buckets, filled with random non-negative integers.
Line 3,468:
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">DIM bucket(10)
FOR i = 1 TO 10 : bucket(i) = int(RND(0)*100) : NEXT
 
Line 3,508:
=={{header|Rust}}==
{{libheader|rand}}
<syntaxhighlight lang="rust">extern crate rand;
 
use std::sync::{Arc, Mutex};
Line 3,583:
 
=={{header|Scala}}==
<syntaxhighlight lang=Scala"scala">
object AtomicUpdates {
 
Line 3,662:
=={{header|Smalltalk}}==
{{works with|Smalltalk/X}}
<syntaxhighlight lang=Smalltalk"smalltalk">NUM_BUCKETS := 10.
"create and preset with random data"
buckets := (1 to:NUM_BUCKETS)
Line 3,746:
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
final class AtomicBuckets: CustomStringConvertible {
Line 3,848:
<br>
{{works with|Tcl|8.5}}
<syntaxhighlight lang="tcl">package require Thread
package require Tk
 
Line 3,958:
 
Fibers are cooperatively (rather than preemptively) scheduled and only one fiber can run at a time. Consequently, simultaneous operations are impossible and all operations are therefore atomic by their nature.
<syntaxhighlight lang="ecmascript">import "random" for Random
import "scheduler" for Scheduler
import "timer" for Timer
Line 4,058:
=={{header|zkl}}==
Threads and thread safe objects (locks, lists, ints, etc) are built in.
<syntaxhighlight lang="zkl">class B{
const N=10;
var [const]
Line 4,087:
fcn threadA(b){ while(1) { b.transferArb(); } }
fcn threadE(b){ while(1) { b.transferEq(); } }</syntaxhighlight>
<syntaxhighlight lang="zkl">b:=B();
do(10){ threadA.launch(b); } do(10){ threadE.launch(b); }
 
Line 4,112:
</pre>
Another solution, using a Pipe as a "holding tank". Pipes are thread safe queues. This code just moves the values to and from the pipe to synchronize changes. The use of this class is the same as above, just change b:=B() to b:=C();
<syntaxhighlight lang="zkl">class C{
const N=10;
var [const]
Line 4,151:
{{omit from|LaTeX}}
{{omit from|M4}}
{{omit from|ML/I}}
{{omit from|Make}}
{{omit from|ML/I}}
{{omit from|PlainTeX}}
{{omit from|TI-89 BASIC}} <!-- Does not have concurrency or background processes. -->
10,327

edits