A rust crate to handle a set of worker threads, which need to communicate back their result to the main thread.
This crate implements a specialization of the actor model, with the following properties: - there is one manager and many workers - workers may work indefinitely - workers can send messages up to the manager; these messages must not be lost - the manager can broadcast messages to the workers - the manager can ask the workers to stop their work at any time, in which case the system should reach a normal state as fast as possible - the message queue can have a limit on its length - no deadlocks¹ and no livelocks
¹: unless specified in the documentation and under the assumption that every worker handles the Stop
message and stops some time after
Add this library to your Cargo.toml
:
toml
worker-pool = "0.1.0"
Then, create a new instance of worker_pool::WorkerPool
:
```rust use std::time::Duration; use worker_pool::{WorkerPool, DownMsg};
// Here, To start a new thread, use ```rust
fn is_prime(n: u64) -> bool {
for i in 2..n {
if n % i == 0 {
return false
}
}
true
} // Start a new thread, that will communicate with the manager
pool.execute(|tx, rx| {
tx.send(2).unwrap();
let mut n = 3;
loop {
match rx.try_recv() {
Ok(DownMsg::Stop) => break,
_ => {}
} });
``` Then, you can interact with the threads using the different methods of ```rust
// Give the worker(s) time to boot up
std::thread::sleep(Duration::new(0, 100000000)); // The iterator returned by pool.recvburst() only yields messages received before it was created and is non-blocking,
// so no livelock or deadlock can occur when using it.
for x in pool.recvburst() {
println!("{}", x);
std::thread::sleep(Duration::new(0, 10000000));
} // This project is dual-licensed under the MIT license and the Apache v2.0 license.
You may choose either of those when using this library. Any contribution to this repository must be made available under both licenses.u64
is the type of the messages from the workers to the manager
// ()
is the type of the messages from the manager to the workers
// 32
is the maximum length of the message queue
let pool: WorkerPoolWorkerPool::execute
or WorkerPool::execute_many
: while !is_prime(n) {
n += 2;
}
tx.send(n).unwrap(); // The program may block here; this will not cause a deadlock
}
WorkerPool
, notably recv_burst
, broadcast
and stop
:pool.stop()
also returns an iterator, which will send a Stop message
// and gather the worker's messages until they all finish. No deadlock can occur here,
// as long as the threads' only shared, critical resource are the worker/manager channels
// provided by WorkerPool and the threads eventually respond to the Stop
message.
for x in pool.stop() {
println!("{}", x);
}
```License