将堆栈数据传入和传出闭包

时间:2015-01-28 03:49:26

标签: multithreading synchronization thread-safety rust

我有一个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编译器输出一整页错误,解释它为cannot infer an appropriate lifetime due to conflicting requirements

从我可以拼凑到的东西,我认为编译器担心闭包可能比堆栈帧更长,并且闭包对inputoutput的引用可能会在闭包仍在使用时被吹走他们(我怀疑这是lifetime parameter must outlive the static lifetime的意思)。但事实上,信号量用于保持堆栈框架活着,直到闭包完成,因此不应该发生。

有没有办法让编译器平静下来?有没有不同的方法来解决这个问题?

1 个答案:

答案 0 :(得分:1)

因此定义了

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);
    }
}