#r @"../bin/FSharpx.Extras.dll"
open System
open System.Threading
open FSharpx.Stm
let test l1 l2 num_threads =
let q1 = ListQueue.ofList l1
let q2 = ListQueue.ofList l2
let move_item q1 q2 =
stm { let! x = ListQueue.dequeue q1
do! ListQueue.enqueue q2 x
return x }
let stop = newTVar false
let rnd = new Random()
let rec worker q1 q2 (fmt : string) =
let x =
stm { let! stop' = readTVar stop
return! if not stop'
then liftM Some (move_item q1 q2)
else stm.Return(None) } |> atomically
match x with
| Some x -> Console.WriteLine(fmt, Thread.CurrentThread.ManagedThreadId, x)
Thread.Sleep(rnd.Next(1000))
worker q1 q2 fmt
| None -> ()
let left_worker () = worker q1 q2 "Thread {0} moved item {1} left."
let right_worker () = worker q2 q1 "Thread {0} moved item {1} right."
let spawn (f : unit -> unit) = let t = new Thread(f) in t.Start(); t
let threads = [ for _ in [1..num_threads] -> [spawn left_worker; spawn right_worker] ]
let terminate () =
writeTVar stop true |> atomically
threads |> Seq.concat |> Seq.iter (fun t -> t.Join())
Console.WriteLine("Terminated.")
stm { let! l1 = ListQueue.toList q1
let! l2 = ListQueue.toList q2
return l1,l2 } |> atomically
terminate
let runTest () =
Console.WriteLine("Started.")
let t = test [1..50] [51..100] 10
Thread.Sleep(3000)
t () |> ignore
namespace System
namespace System.Threading
val test: l1: 'a -> l2: 'b -> num_threads: int -> (unit -> 'c)
val l1: 'a
val l2: 'b
val num_threads: int
val q1: obj
val q2: obj
val move_item: q1: 'd -> q2: 'e -> 'f
val q1: 'd
val q2: 'e
val stop: obj
val rnd: Random
Multiple items
type Random =
new: unit -> unit + 1 overload
member Next: unit -> int + 2 overloads
member NextBytes: buffer: byte array -> unit + 1 overload
member NextDouble: unit -> float
member NextInt64: unit -> int64 + 2 overloads
member NextSingle: unit -> float32
static member Shared: Random
<summary>Represents a pseudo-random number generator, which is an algorithm that produces a sequence of numbers that meet certain statistical requirements for randomness.</summary>
--------------------
Random() : Random
Random(Seed: int) : Random
val worker: q1: 'd -> q2: 'e -> fmt: string -> unit
val fmt: string
Multiple items
val string: value: 'T -> string
--------------------
type string = String
val x: obj option
union case Option.Some: Value: 'T -> Option<'T>
union case Option.None: Option<'T>
val x: obj
type Console =
static member Beep: unit -> unit + 1 overload
static member Clear: unit -> unit
static member GetCursorPosition: unit -> struct (int * int)
static member MoveBufferArea: sourceLeft: int * sourceTop: int * sourceWidth: int * sourceHeight: int * targetLeft: int * targetTop: int -> unit + 1 overload
static member OpenStandardError: unit -> Stream + 1 overload
static member OpenStandardInput: unit -> Stream + 1 overload
static member OpenStandardOutput: unit -> Stream + 1 overload
static member Read: unit -> int
static member ReadKey: unit -> ConsoleKeyInfo + 1 overload
static member ReadLine: unit -> string
...
<summary>Represents the standard input, output, and error streams for console applications. This class cannot be inherited.</summary>
Console.WriteLine() : unit
(+0 other overloads)
Console.WriteLine(value: uint64) : unit
(+0 other overloads)
Console.WriteLine(value: uint32) : unit
(+0 other overloads)
Console.WriteLine(value: string) : unit
(+0 other overloads)
Console.WriteLine(value: float32) : unit
(+0 other overloads)
Console.WriteLine(value: obj) : unit
(+0 other overloads)
Console.WriteLine(value: int64) : unit
(+0 other overloads)
Console.WriteLine(value: int) : unit
(+0 other overloads)
Console.WriteLine(value: float) : unit
(+0 other overloads)
Console.WriteLine(value: decimal) : unit
(+0 other overloads)
Multiple items
type Thread =
inherit CriticalFinalizerObject
new: start: ParameterizedThreadStart -> unit + 3 overloads
member Abort: unit -> unit + 1 overload
member DisableComObjectEagerCleanup: unit -> unit
member GetApartmentState: unit -> ApartmentState
member GetCompressedStack: unit -> CompressedStack
member GetHashCode: unit -> int
member Interrupt: unit -> unit
member Join: unit -> unit + 2 overloads
member Resume: unit -> unit
...
<summary>Creates and controls a thread, sets its priority, and gets its status.</summary>
--------------------
Thread(start: ParameterizedThreadStart) : Thread
Thread(start: ThreadStart) : Thread
Thread(start: ParameterizedThreadStart, maxStackSize: int) : Thread
Thread(start: ThreadStart, maxStackSize: int) : Thread
property Thread.CurrentThread: Thread with get
<summary>Gets the currently running thread.</summary>
<returns>A <see cref="T:System.Threading.Thread" /> that is the representation of the currently running thread.</returns>
property Thread.ManagedThreadId: int with get
<summary>Gets a unique identifier for the current managed thread.</summary>
<returns>An integer that represents a unique identifier for this managed thread.</returns>
Thread.Sleep(timeout: TimeSpan) : unit
Thread.Sleep(millisecondsTimeout: int) : unit
Random.Next() : int
Random.Next(maxValue: int) : int
Random.Next(minValue: int, maxValue: int) : int
val left_worker: unit -> unit
val right_worker: unit -> unit
val spawn: f: (unit -> unit) -> Thread
val f: (unit -> unit)
type unit = Unit
val t: Thread
Thread.Start() : unit
Thread.Start(parameter: obj) : unit
val threads: Thread list list
val terminate: unit -> 'd
module Seq
from Microsoft.FSharp.Collections
val concat: sources: #('T seq) seq -> 'T seq
val iter: action: ('T -> unit) -> source: 'T seq -> unit
Thread.Join() : unit
Thread.Join(timeout: TimeSpan) : bool
Thread.Join(millisecondsTimeout: int) : bool
val runTest: unit -> unit
val t: (unit -> obj)
val ignore: value: 'T -> unit