我有一个 C 函数,由于各种 C 原因,它只能从某些类型的线程中调用。我正在尝试从 Rust 调用此函数。
我的想法是将输入数据传送到“正确的”线程,在该线程上调用 C 函数,然后在将其返回值传送回之前使用信号量在线程上等待。
线程不用于并发;这实际上是一个相当同步的执行流程。只是 C 函数对如何使用它很挑剔。
这是我的尝试:
use std::thread::Thread;
struct Foo {
x: std::sync::Semaphore,
}
//Not the real C function, of course.
fn my_great_c_function(i: i32) -> i32 {
println!("{}",i);
return 12;
}
impl Foo {
fn bar(&self) {
self.x = std::sync::Semaphore::new(0);
let input : i32 = 5;
let mut output : i32 = 10;
Thread::spawn(|:| {
//call out to our C function that only likes some threads
output = my_great_c_function(input);
self.x.release(); //our work is done; the parent thread can continue
});
self.x.acquire(); //wait for child thread to be done interacting with environment
println!("{}",input); //check input
println!("{}",output); //check output
}
}
Rust 编译器输出整页错误,解释它由于需求冲突无法推断出合适的生命周期
。
据我所知,我认为编译器担心闭包可能比堆栈帧还长,闭包对 input
和 output
的引用可能会被吹走而闭包仍在使用它们(我怀疑,这就是 lifetime parameter must outlive the static lifetime
的含义)。但实际上,信号量用于在闭包完成之前保持堆栈帧处于事件状态,因此不应该发生这种情况。
有没有办法让编译器平静下来?有没有其他方法可以解决这个问题?
最佳答案
Thread::spawn
是这样定义的:
fn spawn<F>(f: F) -> Thread where F: FnOnce(), F: Send + 'static
您传递给它的函数必须拥有它的所有数据('static
要求如此)。但是,您正在尝试使用 self
做一些绝对不是 'static
的事情。请记住,Rust 关心安全;不允许线程干扰其他线程的数据:您不能在多个线程上访问一个对象。
您想要的实际上比您尝试的更容易:使用 Thread::scoped
:
impl Foo {
fn bar(&self) {
let input = 5i32;
let output = Thread::scoped(|:| {
my_great_c_function(input)
}).join().unwrap();
println!("{}", input);
println!("{}", output);
}
}
关于multithreading - 将堆栈数据传入和传出闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28184317/