具有不同功能的 Vector 的多线程
Multithreading with a Vector of different functions
我正在尝试 运行 在不同线程上执行多个函数。我写了这个有效的(最小)代码
use std::thread;
fn f1(count: usize) {
for i in 0..count { /*do something*/ }
}
fn f2(count: usize) {
for i in 0..count { /*do something*/ }
}
fn run(ops: &Vec<impl Fn(usize) + Sync + Send + Copy + 'static>) {
for i in 0..ops.len() {
let func = ops[i];
thread::spawn(move || func(1000));
}
}
fn main() {
let ops = vec![f1, f1]; // putting the same function twice
run(&ops);
}
但是,一旦我发送不同的函数
let ops = vec![f1, f2];
编译失败。据我了解,我不能在同一个向量中保存不同的类型(我猜,函数有不同的内存要求,尽管我不太确定函数指针是如何工作的)。
我尝试在 SO 上浏览类似问题,并尝试了这个解决方案
let ops: Vec<&dyn Fn(usize)> = vec![&f1, &f2];
我收到这个错误
`dyn Fn(usize)` cannot be shared between threads safely
the trait `Sync` is not implemented for `dyn Fn(usize)`
我在努力理解基本问题时陷入困境。你对我应该如何理解这个问题有什么见解,以及如何解决它的任何指示吗?
谢谢!
正如你可以用 impl
添加 Sync
标记一样,你也可以用 &dyn
添加它,但你可能需要括号来消除歧义:
fn run(ops: &Vec<&'static (dyn Fn(usize) + Sync)>)
两条小评论:
- 一般来说,使用
&[…]
而不是 &Vec<…>
更灵活,更受青睐。
- 不需要在 rust 中做
for i in 0…foos.len()
,for foo in foos
就可以了。 (您可能偶尔需要使用 for foo in &foos
或 for foo in foos.iter()
。如果确实需要索引,.enumerate()
很方便。)
- 如果
'static
很麻烦(例如因为你想传入一些捕获局部变量的闭包并且不能是 'static
),你可以使用作用域线程(example),或将拥有的 Fn
s 作为 Vec<Box<dyn Fn(usize) + Sync>>
.
我正在尝试 运行 在不同线程上执行多个函数。我写了这个有效的(最小)代码
use std::thread;
fn f1(count: usize) {
for i in 0..count { /*do something*/ }
}
fn f2(count: usize) {
for i in 0..count { /*do something*/ }
}
fn run(ops: &Vec<impl Fn(usize) + Sync + Send + Copy + 'static>) {
for i in 0..ops.len() {
let func = ops[i];
thread::spawn(move || func(1000));
}
}
fn main() {
let ops = vec![f1, f1]; // putting the same function twice
run(&ops);
}
但是,一旦我发送不同的函数
let ops = vec![f1, f2];
编译失败。据我了解,我不能在同一个向量中保存不同的类型(我猜,函数有不同的内存要求,尽管我不太确定函数指针是如何工作的)。
我尝试在 SO 上浏览类似问题,并尝试了这个解决方案
let ops: Vec<&dyn Fn(usize)> = vec![&f1, &f2];
我收到这个错误
`dyn Fn(usize)` cannot be shared between threads safely
the trait `Sync` is not implemented for `dyn Fn(usize)`
我在努力理解基本问题时陷入困境。你对我应该如何理解这个问题有什么见解,以及如何解决它的任何指示吗?
谢谢!
正如你可以用 impl
添加 Sync
标记一样,你也可以用 &dyn
添加它,但你可能需要括号来消除歧义:
fn run(ops: &Vec<&'static (dyn Fn(usize) + Sync)>)
两条小评论:
- 一般来说,使用
&[…]
而不是&Vec<…>
更灵活,更受青睐。 - 不需要在 rust 中做
for i in 0…foos.len()
,for foo in foos
就可以了。 (您可能偶尔需要使用for foo in &foos
或for foo in foos.iter()
。如果确实需要索引,.enumerate()
很方便。) - 如果
'static
很麻烦(例如因为你想传入一些捕获局部变量的闭包并且不能是'static
),你可以使用作用域线程(example),或将拥有的Fn
s 作为Vec<Box<dyn Fn(usize) + Sync>>
.