moonpool/moonpool/Moonpool/Ws_pool/index.html
2024-03-05 01:52:16 +00:00

9 lines
14 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Ws_pool (moonpool.Moonpool.Ws_pool)</title><meta charset="utf-8"/><link rel="stylesheet" href="../../../_odoc-theme/odoc.css"/><meta name="generator" content="odoc 2.4.1"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> <a href="../../index.html">moonpool</a> &#x00BB; <a href="../index.html">Moonpool</a> &#x00BB; Ws_pool</nav><header class="odoc-preamble"><h1>Module <code><span>Moonpool.Ws_pool</span></code></h1><p>Work-stealing thread pool.</p><p>A pool of threads with a worker-stealing scheduler. The pool contains a fixed number of threads that wait for work items to come, process these, and loop.</p><p>This is good for CPU-intensive tasks that feature a lot of small tasks. Note that tasks will not always be processed in the order they are scheduled, so this is not great for workloads where the latency of individual tasks matter (for that see <a href="../Fifo_pool/index.html"><code>Fifo_pool</code></a>).</p><p>This implements <a href="../Runner/index.html#type-t"><code>Runner.t</code></a> since 0.3.</p><p>If a pool is no longer needed, <a href="#val-shutdown"><code>shutdown</code></a> can be used to signal all threads in it to stop (after they finish their work), and wait for them to stop.</p><p>The threads are distributed across a fixed domain pool (whose size is determined by <code>Domain.recommended_domain_count</code> on OCaml 5, and simply the single runtime on OCaml 4).</p></header><div class="odoc-content"><div class="odoc-include"><details open="open"><summary class="spec include"><code><span><span class="keyword">include</span> <span class="keyword">module</span> <span class="keyword">type</span> <span class="keyword">of</span> <a href="../Runner/index.html">Runner</a></span></code></summary><div class="odoc-spec"><div class="spec type anchored" id="type-task"><a href="#type-task" class="anchor"></a><code><span><span class="keyword">type</span> task</span><span> = <span>unit <span class="arrow">&#45;&gt;</span></span> unit</span></code></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> t</span></code></div><div class="spec-doc"><p>A runner.</p><p>If a runner is no longer needed, <a href="#val-shutdown"><code>shutdown</code></a> can be used to signal all worker threads in it to stop (after they finish their work), and wait for them to stop.</p><p>The threads are distributed across a fixed domain pool (whose size is determined by <code>Domain.recommended_domain_count</code> on OCaml 5, and simple the single runtime on OCaml 4).</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-size"><a href="#val-size" class="anchor"></a><code><span><span class="keyword">val</span> size : <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> int</span></code></div><div class="spec-doc"><p>Number of threads/workers.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-num_tasks"><a href="#val-num_tasks" class="anchor"></a><code><span><span class="keyword">val</span> num_tasks : <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> int</span></code></div><div class="spec-doc"><p>Current number of tasks. This is at best a snapshot, useful for metrics and debugging.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-shutdown"><a href="#val-shutdown" class="anchor"></a><code><span><span class="keyword">val</span> shutdown : <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> unit</span></code></div><div class="spec-doc"><p>Shutdown the runner and wait for it to terminate. Idempotent.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-shutdown_without_waiting"><a href="#val-shutdown_without_waiting" class="anchor"></a><code><span><span class="keyword">val</span> shutdown_without_waiting : <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> unit</span></code></div><div class="spec-doc"><p>Shutdown the pool, and do not wait for it to terminate. Idempotent.</p></div></div><div class="odoc-spec"><div class="spec exception anchored" id="exception-Shutdown"><a href="#exception-Shutdown" class="anchor"></a><code><span><span class="keyword">exception</span> </span><span><span class="exception">Shutdown</span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-run_async"><a href="#val-run_async" class="anchor"></a><code><span><span class="keyword">val</span> run_async : <span><span class="optlabel">?ls</span>:<a href="../Task_local_storage/index.html#type-t">Task_local_storage.t</a> <span class="arrow">&#45;&gt;</span></span> <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> <span><a href="#type-task">task</a> <span class="arrow">&#45;&gt;</span></span> unit</span></code></div><div class="spec-doc"><p><code>run_async pool f</code> schedules <code>f</code> for later execution on the runner in one of the threads. <code>f()</code> will run on one of the runner's worker threads/domains.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">ls</span> <p>if provided, run the task with this initial local storage</p></li></ul><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <a href="#exception-Shutdown"><code>Shutdown</code></a> <p>if the runner was shut down before <code>run_async</code> was called.</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-run_wait_block"><a href="#val-run_wait_block" class="anchor"></a><code><span><span class="keyword">val</span> run_wait_block : <span><span class="optlabel">?ls</span>:<a href="../Task_local_storage/index.html#type-t">Task_local_storage.t</a> <span class="arrow">&#45;&gt;</span></span> <span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> <span><span>(<span>unit <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'a</span>)</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>run_wait_block pool f</code> schedules <code>f</code> for later execution on the pool, like <a href="#val-run_async"><code>run_async</code></a>. It then blocks the current thread until <code>f()</code> is done executing, and returns its result. If <code>f()</code> raises an exception, then <code>run_wait_block pool f</code> will raise it as well.</p><p><b>NOTE</b> be careful with deadlocks (see notes in <a href="../Fut/index.html#val-wait_block"><code>Fut.wait_block</code></a> about the required discipline to avoid deadlocks).</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <a href="#exception-Shutdown"><code>Shutdown</code></a> <p>if the runner was already shut down</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-dummy"><a href="#val-dummy" class="anchor"></a><code><span><span class="keyword">val</span> dummy : <a href="#type-t">t</a></span></code></div><div class="spec-doc"><p>Runner that fails when scheduling tasks on it. Calling <a href="#val-run_async"><code>run_async</code></a> on it will raise Failure.</p></div></div><h3 id="implementing-runners"><a href="#implementing-runners" class="anchor"></a>Implementing runners</h3><div class="odoc-spec"><div class="spec module anchored" id="module-For_runner_implementors"><a href="#module-For_runner_implementors" class="anchor"></a><code><span><span class="keyword">module</span> <a href="For_runner_implementors/index.html">For_runner_implementors</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div><div class="spec-doc"><p>This module is specifically intended for users who implement their own runners. Regular users of Moonpool should not need to look at it.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-get_current_runner"><a href="#val-get_current_runner" class="anchor"></a><code><span><span class="keyword">val</span> get_current_runner : <span>unit <span class="arrow">&#45;&gt;</span></span> <span><a href="#type-t">t</a> option</span></span></code></div><div class="spec-doc"><p>Access the current runner. This returns <code>Some r</code> if the call happens on a thread that belongs in a runner.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.5</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-get_current_storage"><a href="#val-get_current_storage" class="anchor"></a><code><span><span class="keyword">val</span> get_current_storage : <span>unit <span class="arrow">&#45;&gt;</span></span> <span><a href="../Task_local_storage/index.html#type-t">Task_local_storage.t</a> option</span></span></code></div><div class="spec-doc"><p><code>get_current_storage runner</code> gets the local storage for the currently running task.</p></div></div></details></div><div class="odoc-spec"><div class="spec type anchored" id="type-create_args"><a href="#type-create_args" class="anchor"></a><code><span><span class="keyword">type</span> <span>('a, 'b) create_args</span></span><span> =
<span><span class="optlabel">?on_init_thread</span>:<span>(<span><span class="label">dom_id</span>:int <span class="arrow">&#45;&gt;</span></span> <span><span class="label">t_id</span>:int <span class="arrow">&#45;&gt;</span></span> <span>unit <span class="arrow">&#45;&gt;</span></span> unit)</span> <span class="arrow">&#45;&gt;</span></span>
<span><span class="optlabel">?on_exit_thread</span>:<span>(<span><span class="label">dom_id</span>:int <span class="arrow">&#45;&gt;</span></span> <span><span class="label">t_id</span>:int <span class="arrow">&#45;&gt;</span></span> <span>unit <span class="arrow">&#45;&gt;</span></span> unit)</span> <span class="arrow">&#45;&gt;</span></span>
<span><span class="optlabel">?on_exn</span>:<span>(<span>exn <span class="arrow">&#45;&gt;</span></span> <span><a href="../../../ocaml/Stdlib/Printexc/index.html#type-raw_backtrace">Stdlib.Printexc.raw_backtrace</a> <span class="arrow">&#45;&gt;</span></span> unit)</span> <span class="arrow">&#45;&gt;</span></span>
<span><span class="optlabel">?around_task</span>:<span>(<span>(<span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'b</span>)</span> * <span>(<span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <span class="arrow">&#45;&gt;</span></span> unit)</span>)</span> <span class="arrow">&#45;&gt;</span></span>
<span><span class="optlabel">?num_threads</span>:int <span class="arrow">&#45;&gt;</span></span>
<span><span class="optlabel">?name</span>:string <span class="arrow">&#45;&gt;</span></span>
<span class="type-var">'a</span></span></code></div><div class="spec-doc"><p>Arguments used in <a href="#val-create"><code>create</code></a>. See <a href="#val-create"><code>create</code></a> for explanations.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-create"><a href="#val-create" class="anchor"></a><code><span><span class="keyword">val</span> create : <span><span>(<span>unit <span class="arrow">&#45;&gt;</span></span> <a href="#type-t">t</a>, <span class="type-var">_</span>)</span> <a href="#type-create_args">create_args</a></span></span></code></div><div class="spec-doc"><p><code>create ()</code> makes a new thread pool.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">on_init_thread</span> <p>called at the beginning of each new thread in the pool.</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">num_threads</span> <p>size of the pool, ie. number of worker threads. It will be at least <code>1</code> internally, so <code>0</code> or negative values make no sense. The default is <code>Domain.recommended_domain_count()</code>, ie one worker thread per CPU core. On OCaml 4 the default is <code>4</code> (since there is only one domain).</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">on_exit_thread</span> <p>called at the end of each thread in the pool</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">around_task</span> <p>a pair of <code>before, after</code>, where <code>before pool</code> is called before a task is processed, on the worker thread about to run it, and returns <code>x</code>; and <code>after pool x</code> is called by the same thread after the task is over. (since 0.2)</p></li></ul><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">name</span> <p>a name for this thread pool, used if tracing is enabled (since NEXT_RELEASE)</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-with_"><a href="#val-with_" class="anchor"></a><code><span><span class="keyword">val</span> with_ : <span><span>(<span>unit <span class="arrow">&#45;&gt;</span></span> <span><span>(<span><a href="#type-t">t</a> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'a</span>)</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'a</span>, <span class="type-var">_</span>)</span> <a href="#type-create_args">create_args</a></span></span></code></div><div class="spec-doc"><p><code>with_ () f</code> calls <code>f pool</code>, where <code>pool</code> is obtained via <a href="#val-create"><code>create</code></a>. When <code>f pool</code> returns or fails, <code>pool</code> is shutdown and its resources are released.</p><p>Most parameters are the same as in <a href="#val-create"><code>create</code></a>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 0.3</li></ul></div></div></div></body></html>