Έχουν δημοσιευτεί Κυριακή, 11 Ιουλίου 2010 7:49 μμ από το μέλος PALLADIN

Clojure's Atoms in F#

Μελετώντας την Clojure, την προσοχή μου τράβηξε ένα απλό αλλά πολύ χρήσιμο construct, το Atom.
Το Atom φαίνεται να είναι το πάντρεμα των ref cells της ML με lock free CAS concurrency semantics.
Επειδή τέτοια constructs είναι πολύ χρήσιμα στην F#, σκέφτηκα να υλοποιήσω κάτι ανάλογο.
My attempt:

type Atom<'a when 'a : not struct>(value : 'a) =
    let refCell = ref value
    
    let rec swap f = 
        let currentValue = !refCell
        let result = Interlocked.CompareExchange<'a>(refCell, f currentValue, currentValue)
        if obj.ReferenceEquals(result, currentValue) then ()
        else Thread.SpinWait 20; swap f
        
    member self.Value with get() = !refCell
    member self.Swap (f : 'a -> 'a) = swap f
        
    

let atom value = 
    new Atom<_>(value)
    
let (!) (atom : Atom<_>) =  
    atom.Value
    
let swap (atom : Atom<_>) (f : _ -> _) =
    atom.Swap f
Και ως παράδειγμα χρήσης, σκέφτηκα έναν απλό multithreaded counter.
(Σημείωση: βάζω το int μέσα στο lambda επειδή πρέπει να δώσω στο Atom ένα reference type)

let counter = atom (fun () -> 0)

let listOfIncrementAsync = [ for _ in [1..1000000] -> async { swap counter (fun f -> (fun result () -> result + 1) <| f()) } ]

listOfIncrementAsync |> Async.Parallel |> Async.Run |> ignore 

printfn "%d" ((!counter)()) //1000000


Share


Ενημέρωση για Σχόλια

Αν θα θέλατε να λαμβάνετε ένα e-mail όταν γίνονται ανανεώσεις στο περιεχόμενο αυτής της δημοσίευσης, παρακαλούμε γίνετε συνδρομητής εδώ

Παραμείνετε ενήμεροι στα τελευταία σχόλια με την χρήση του αγαπημένου σας RSS Aggregator και συνδρομή στη Τροφοδοσία RSS με σχόλια

Σχόλια:

Χωρίς Σχόλια

Ποιά είναι η άποψή σας για την παραπάνω δημοσίευση;

(απαιτούμενο)
απαιτούμενο
προαιρετικό
απαιτούμενο
ÅéóÜãåôå ôïí êùäéêü:
CAPTCHA Image