Created
February 4, 2018 00:24
-
-
Save mwolicki/ea9c2c551801b060f2ba6d1dcd2e63d9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open System.Threading | |
open System.Collections.Concurrent | |
type ThreadPool () = | |
let jobs = System.Collections.Concurrent.ConcurrentQueue<unit->unit> () | |
let semaphore = new Semaphore (0, System.Int32.MaxValue) | |
let threads = ConcurrentBag<Thread>() | |
let postJob job = | |
jobs.Enqueue job | |
semaphore.Release () |> ignore | |
do | |
let threadLoop _ = | |
{ new SynchronizationContext () with | |
override __.Post (f, x) = postJob (fun () -> f.Invoke x) | |
override __.Send (f, x) = | |
use s = new Semaphore (0, 1) | |
postJob (fun () -> f.Invoke x; s.Release () |> ignore) | |
s.WaitOne () |> ignore } | |
|> SynchronizationContext.SetSynchronizationContext | |
let rec loop () = | |
semaphore.WaitOne () |> ignore | |
match jobs.TryDequeue () with | |
| true, x -> x () | |
| _ -> () | |
loop () | |
loop () | |
for i in 0..4 do | |
let t = Thread(ParameterizedThreadStart threadLoop) | |
t.Name <- sprintf "Custom Thread Pool/%i" i | |
threads.Add t | |
t.Start () | |
member __.QueueJob f = postJob f | |
let pool = ThreadPool () | |
for _ in 1..100 do | |
pool.QueueJob (fun () -> | |
let synch = SynchronizationContext.Current | |
let a = System.Threading.Thread.CurrentThread.Name | |
async { | |
let b = System.Threading.Thread.CurrentThread.Name | |
do! Async.SwitchToContext synch | |
printfn "%s vs %s vs %s" a b System.Threading.Thread.CurrentThread.Name | |
} |> Async.Start) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment