mirror of
https://github.com/c-cube/moonpool.git
synced 2025-12-06 03:05:30 -05:00
doc: add more to the readme
This commit is contained in:
parent
3676d1e28d
commit
76ec06942a
1 changed files with 81 additions and 0 deletions
81
README.md
81
README.md
|
|
@ -19,10 +19,55 @@ The user can create several thread pools. These pools use regular posix threads,
|
||||||
but the threads are spread across multiple domains (on OCaml 5), which enables
|
but the threads are spread across multiple domains (on OCaml 5), which enables
|
||||||
parallelism.
|
parallelism.
|
||||||
|
|
||||||
|
The function `Pool.run pool task` runs `task()` on one of the workers
|
||||||
|
of `pool`, as soon as one is available. No result is returned.
|
||||||
|
|
||||||
```ocaml
|
```ocaml
|
||||||
|
# #require "threads";;
|
||||||
# let pool = Moonpool.Pool.create ~min:4 ();;
|
# let pool = Moonpool.Pool.create ~min:4 ();;
|
||||||
val pool : Moonpool.Pool.t = <abstr>
|
val pool : Moonpool.Pool.t = <abstr>
|
||||||
|
|
||||||
|
# begin
|
||||||
|
Moonpool.Pool.run pool
|
||||||
|
(fun () ->
|
||||||
|
Thread.delay 0.1;
|
||||||
|
print_endline "running from the pool");
|
||||||
|
print_endline "running from the caller";
|
||||||
|
Thread.delay 0.3; (* wait for task to run before returning *)
|
||||||
|
end ;;
|
||||||
|
running from the caller
|
||||||
|
running from the pool
|
||||||
|
- : unit = ()
|
||||||
|
```
|
||||||
|
|
||||||
|
The function `Fut.spawn ~on f` schedules `f ()` on the pool `on`, and immediately
|
||||||
|
returns a _future_ which will eventually hold the result (or an exception).
|
||||||
|
|
||||||
|
The function `Fut.peek` will return the current value, or `None` if the future is
|
||||||
|
still not completed.
|
||||||
|
The functions `Fut.wait_block` and `Fut.wait_block_exn` will
|
||||||
|
block the current thread and wait for the future to complete.
|
||||||
|
There are some deadlock risks associated with careless use of these, so
|
||||||
|
be sure to consult the documentation of the `Fut` module.
|
||||||
|
|
||||||
|
```ocaml
|
||||||
|
# let fut = Moonpool.Fut.spawn ~on:pool
|
||||||
|
(fun () ->
|
||||||
|
Thread.delay 0.5;
|
||||||
|
1+1);;
|
||||||
|
val fut : int Moonpool.Fut.t = <abstr>
|
||||||
|
|
||||||
|
# Moonpool.Fut.peek fut;
|
||||||
|
- : int Moonpool.Fut.or_error option = None
|
||||||
|
|
||||||
|
# Moonpool.Fut.wait_block_exn fut;;
|
||||||
|
- : int = 2
|
||||||
|
```
|
||||||
|
|
||||||
|
Some combinators on futures are also provided, e.g. to wait for all futures in
|
||||||
|
an array to complete:
|
||||||
|
|
||||||
|
```ocaml
|
||||||
# let rec fib x =
|
# let rec fib x =
|
||||||
if x <= 1 then 1 else fib (x-1) + fib (x-2);;
|
if x <= 1 then 1 else fib (x-1) + fib (x-2);;
|
||||||
val fib : int -> int = <fun>
|
val fib : int -> int = <fun>
|
||||||
|
|
@ -46,6 +91,42 @@ Ok
|
||||||
514229; 832040; 1346269; 2178309; 3524578; 5702887; 9227465|]
|
514229; 832040; 1346269; 2178309; 3524578; 5702887; 9227465|]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Support for `await`
|
||||||
|
|
||||||
|
On OCaml 5, effect handlers can be used to implement `Fut.await : 'a Fut.t -> 'a`.
|
||||||
|
|
||||||
|
The expression `Fut.await some_fut`, when run from inside some thread pool,
|
||||||
|
suspends its caller task; the suspended task is then parked, and will
|
||||||
|
be resumed when the future is completed.
|
||||||
|
The pool worker that was executing this expression, in the mean time, moves
|
||||||
|
on to another task.
|
||||||
|
This means that `await` is free of the deadlock risks associated with
|
||||||
|
`Fut.wait_block`.
|
||||||
|
|
||||||
|
In the following example, we bypass the need for `Fut.join_array` by simply
|
||||||
|
using regular array functions along with `Fut.await`.
|
||||||
|
|
||||||
|
```ocaml
|
||||||
|
# let main_fut =
|
||||||
|
let open Moonpool.Fut in
|
||||||
|
spawn ~on:pool @@ fun () ->
|
||||||
|
(* array of sub-futures *)
|
||||||
|
let tasks: _ Moonpool.Fut.t array = Array.init 100 (fun i ->
|
||||||
|
spawn ~on:pool (fun () ->
|
||||||
|
Thread.delay 0.01;
|
||||||
|
i+1))
|
||||||
|
in
|
||||||
|
Array.fold_left (fun n fut -> n + await fut) 0 tasks
|
||||||
|
;;
|
||||||
|
val main_fut : int Moonpool.Fut.t = <abstr>
|
||||||
|
|
||||||
|
# let expected_sum = Array.init 100 (fun i->i+1) |> Array.fold_left (+) 0;;
|
||||||
|
val expected_sum : int = 5050
|
||||||
|
|
||||||
|
# assert (expected_sum = Moonpool.Fut.wait_block_exn main_fut);;
|
||||||
|
- : unit = ()
|
||||||
|
```
|
||||||
|
|
||||||
### More intuition
|
### More intuition
|
||||||
|
|
||||||
To quote [gasche](https://discuss.ocaml.org/t/ann-moonpool-0-1/12387/15):
|
To quote [gasche](https://discuss.ocaml.org/t/ann-moonpool-0-1/12387/15):
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue