Rust 是否可以在没有互斥的情况下从Fn调用Fn一次?

Rust 是否可以在没有互斥的情况下从Fn调用Fn一次?,rust,Rust,Fn可以通过通道发送,但是FnOnce还不能在稳定状态下发送。为了通过通道发送一次Fn,可以将其包装在Fn中,如下所示 但是,这需要一个互斥对象,当扩展到非常高的吞吐量时,这会带来恼人的开销(也就是说,当您经常这样做时,它的速度很慢) 是否有其他一些并发原语我可以在这里使用,这将是较轻的重量?可能使用std::sync::atomic?这可以不用锁吗 我对使用依赖于未定义行为的夜间功能或板条箱不感兴趣 use std::thread; use std::sync::Mutex; use std:

Fn
可以通过通道发送,但是
FnOnce
还不能在稳定状态下发送。为了通过通道发送一次
Fn
,可以将其包装在
Fn
中,如下所示

但是,这需要一个
互斥对象
,当扩展到非常高的吞吐量时,这会带来恼人的开销(也就是说,当您经常这样做时,它的速度很慢)

是否有其他一些并发原语我可以在这里使用,这将是较轻的重量?可能使用
std::sync::atomic
?这可以不用锁吗

我对使用依赖于未定义行为的夜间功能或板条箱不感兴趣

use std::thread;
use std::sync::Mutex;
use std::sync::mpsc;

struct RawFunc {
    data: Box<Fn() + Send + 'static>,
}

impl RawFunc {
    fn new<T>(inner: T) -> RawFunc
    where
        T: FnOnce() + Send + 'static,
    {
        let inner_lock = Mutex::new(Some(inner));
        return RawFunc {
            data: Box::new(move || match inner_lock.lock() {
                Ok(mut i) => (i.take().unwrap())(),
                Err(_) => {}
            }),
        };
    }

    fn invoke(self) {
        (self.data)()
    }
}

fn main() {
    // Local
    let x = RawFunc::new(move || {
        println!("Hello world");
    });
    x.invoke();

    // Via channel
    let (sx, rx) = mpsc::channel::<RawFunc>();
    sx.send(RawFunc::new(move || {
        println!("Hello world 2");
    })).unwrap();
    let output = rx.recv().unwrap();
    output.invoke();

    // In a thread
    let guard = thread::spawn(move || {
        let output = rx.recv().unwrap();
        output.invoke();
    });

    sx.send(RawFunc::new(move || {
        println!("Hello world 3!");
    })).unwrap();

    guard.join().unwrap();

    // Passing arbitrary data to a thread
    let (sx, rx) = mpsc::channel::<RawFunc>();
    let guard = thread::spawn(move || {
        let output = rx.recv().unwrap();
        output.invoke();
    });

    let bar = RawFunc::new(move || {
        println!("Moved func!");
    });
    let foo = String::from("Hello World 4");
    sx.send(RawFunc::new(move || {
        println!("Some moved data: {:?}", foo);
        bar.invoke();
    })).unwrap();

    guard.join().unwrap();
}
使用std::thread;
使用std::sync::Mutex;
使用std::sync::mpsc;
结构RawFunc{
数据:框(i.take().unwrap())(),
Err()=>{}
}),
};
}
fn调用(自我){
(自我数据)()
}
}
fn main(){
//本地的
设x=RawFunc::new(move | |){
println!(“你好世界”);
});
x、 调用();
//通过渠道
let(sx,rx)=mpsc::channel::();
发送(RawFunc::新建(移动| |){
println!(“你好,世界2”);
})).unwrap();
让输出=rx.recv().unwrap();
output.invoke();
//一线生机
让守卫=线程::繁殖(移动| |{
让输出=rx.recv().unwrap();
output.invoke();
});
发送(RawFunc::新建(移动| |){
println!(“你好,世界3!”);
})).unwrap();
防护罩。连接()。展开();
//向线程传递任意数据
let(sx,rx)=mpsc::channel::();
让守卫=线程::繁殖(移动| |{
让输出=rx.recv().unwrap();
output.invoke();
});
让bar=RawFunc::new(移动| |){
println!(“Moved func!”);
});
让foo=String::from(“Hello World 4”);
发送(RawFunc::新建(移动| |){
println!(“某些移动数据:{:?}”,foo);
bar.invoke();
})).unwrap();
防护罩。连接()。展开();
}
这本书的作者有着完全相同的问题,并以他们自己的特点解决了这个问题

/// Asynchronous callback function trait.
///
/// Every `FnOnce(&mut Cursive) -> () + Send` automatically
/// implements this.
///
/// This is a workaround only because `Box<FnOnce()>` is not
/// working and `FnBox` is unstable.
pub trait CbFunc: Send {
    /// Calls the function.
    fn call_box(self: Box<Self>, &mut Cursive);
}

impl<F: FnOnce(&mut Cursive) -> () + Send> CbFunc for F {
    fn call_box(self: Box<Self>, siv: &mut Cursive) {
        (*self)(siv)
    }
}
///异步回调函数特性。
///
///每个`FnOnce(&mut草书)->()+Send`自动
///实现这一点。
///
///这是一种变通方法,因为“Box”不是
///正在工作,“FnBox”不稳定。
发布功能:发送{
///调用函数。
fn调用框(self:box和mut草书);
}
函数的impl()+Send>CbFunc{
fn调用框(self:box、siv:&mut草书){
(*自我)(siv)
}
}


,这里介绍了代码。

也许这可以帮助您:@hellow,太好了,谢谢!你想把它作为一个答案吗?我很乐意接受。似乎效果很好,例如,为什么使用
Fn
而不是
FnMut
?您只需要
Send
而不需要
Sync
,这样就可以用
RefCell
替换
Mutex