OCaml Thread uses threads of a real system (kernel). The total number of threads is limited by the kernel:
cat /proc/sys/kernel/threads-max
251422
, ,
echo 100000 > /proc/sys/kernel/threads-max
.
let rec whisper count init_val =
let rec aux n t chan =
if n >= count then chan
else
let new_chan = Event.new_channel () in
let t' = Thread.create chan_trans (chan, new_chan) in
Thread.join t;
aux (n+1) t' new_chan in
let leftest_chan = Event.new_channel () in
let t = Thread.create post (leftest_chan, init_val) in
let rightest_chan = aux 0 t leftest_chan in
get_chan rightest_chan
. :
$ ocamlbuild -use-ocamlfind -tag thread -pkg threads ev.native
$ time ./ev.native
100001
real 0m1.581s
. ( ). Lwt Async. .
Lwt
Go , , OCaml ( , ).
open Lwt.Infix
let whispers n =
let rec whisper i p =
if i < n then
Lwt_mvar.take p >>= fun x ->
whisper (i+1) (Lwt_mvar.create (x+1))
else Lwt_mvar.take p in
whisper 0 (Lwt_mvar.create 1)
let () = print_int @@ Lwt_main.run (whispers 100000)
:
$ ocamlbuild -use-ocamlfind -tag thread -pkg lwt.unix lev.native
$ time ./lev.native
100001
real 0m0.007s
Go :
$ go build whispers.go
$ time ./whispers
100001
real 0m0.952s
""
Go. , , , OCaml Lwt , 100_000 100_001, , whisper , , . , . 50 .
, . Go.
100_001 100_000 , . , . , Go .
let whispers n =
let rec loop i p =
if i < n then
let p' = Lwt_mvar.create_empty () in
let _t =
Lwt_mvar.take p >>= fun x ->
Lwt_mvar.put p' (x+1) in
loop (i+1) p'
else Lwt_mvar.take p in
let p0 = Lwt_mvar.create_empty () in
let t = loop 1 p0 in
Lwt_mvar.put p0 1 >>= fun () -> t
$ time ./lev.native
100001
real 0m0.111s
, , 20 ( 1 ), - 10 , Go.