I'm trying to implement a simple work-stealing task scheduler, and I'm having some problems with fn items.
Here's a minimal example that recreates the situation:
use std::thread;
struct Context<Function, Data> {
global_task_queue: Vec<Task<Function, Data>>,
}
struct Task<Function, Data> {
function: Function,
data: Data,
}
impl<'scope, 'env: 'scope, Function: Send + 'static> Context<Function, &'env i32>
where
Function: Fn(&'env i32),
{
fn run(self) {
let a = vec![1, 2, 3];
let mut x = 0;
thread::scope(|s| {
let new_task = Task { function: func, data: &x };
self.global_task_queue.push(new_task);
s.spawn(|| {
println!("hello from the first scoped thread");
dbg!(&a);
});
});
}
}
fn func(_number: &i32) {}
fn main() {
let b = 2;
let task = Task { function: func, data: &b };
let context = Context {
global_task_queue: vec![task],
};
context.run();
}
I've got a Task
struct that represents a unit of work, which contains a function to do the work and som input data to operate on. I want to run these tasks in separate threads, but I also want them to have an immutable reference to data located in the main thread (represented by x
in the example). I'm using thread::scope
for this, since it allows passing references with non-'static
lifetimes to the threads.
The reason I'm storing the Task
s inside global_task_queue
is because I'm actually using crossbeam::deque and it is a global work queue which the worker threads take tasks from when they need more work.
It doesn't compile, though:
error[E0308]: mismatched types
--> src/main.rs:22:41
|
12 | impl<'scope, 'env: 'scope, Function: Send + 'static> Context<Function, &'env i32>
| -------- this type parameter
...
22 | self.global_task_queue.push(new_task);
| ---- ^^^^^^^^ expected type parameter `Function`, found fn item
| |
| arguments to this function are incorrect
|
= note: expected struct `Task<Function, &'env i32>`
found struct `Task<for<'a> fn(&'a i32) {func}, &{integer}>`
note: associated function defined here
--> /rustc/d5a82bbd26e1ad8b7401f6a718a9c57c96905483/library/alloc/src/vec/mod.rs:1831:12
For more information about this error, try `rustc --explain E0308`.
Is there a more fitting way of representing the Task
s, or is there a way to make this work?