In the previous post , we talked a bit about the State Monad , what it is and how you could use it today

By on 1/6/2010 10:47 PM ()

In the previous post , we talked a bit about the State Monad , what it is and how you could use it today

By on 1/6/2010 10:32 PM ()

I'm not sure that the reader monad really contributes much here - you don't gain much by "threading" the lock through, and the effect on the synax seems much worse than using "(fun () -> ...)" (also, I find "<| fun () ->" to work quite well).

I'm teaching concurrency in F# at the moment, and I find a better way is just to define a function that generates the appropriate lock operations, like:

1
2
3
4
  let lockOps obj = 
                  let wait () = ignore(Threading.Monitor.Wait obj)
                  let wakeWaiters () = Threading.Monitor.PulseAll obj
                  (lock obj, wait, wakeWaiters)

Here's an example of how to use this - no Monitor class, and no reproducing the locked object, and now no curly braces either!

1
2
3
4
5
6
7
8
9
10
let inc, dec =
    let count = ref 0
    let lockIt, wait, wakeWaiters = lockOps count

    let inc() = lockIt <| fun () ->
        count := !count + 1

    let dec() = lockIt <| fun () ->
        count := !count - 1
    inc,dec

Also, your last example isn't generally what you want - the enqueue and dequeue only work correctly if every use of them for a particular queue use the same lock. This should be bound when the queue is created - having a function like move that takes a queue and then decides what lock to use is just asking for trouble. If you want to parameterize with respect to the lock, just use a function parameter (probably before the q argument) and return appropriate functions using that lock:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let enqDeq lockObj (q : Queue<_>) x =

    let lockIt, wait, wakeWaiters = lockOps lockObj

    let enq = lockIt <| fun()-> 

         if q.Count = 0 then wakeWaiters()

         q.Enqueue(x)

    let deq = lockIt <| fun()-> 

        while q.Count = 0 do wait()

        q.Dequeue()

    enq,deq   
By on 4/15/2009 8:18 AM ()

Monader i F#

By on 9/29/2008 4:05 PM ()

Introduction

F# has the async computation expression for writing parallel programs. Async achieves concurrency...

By on 8/3/2008 2:54 AM ()
By on 2/17/2008 8:56 AM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper