2016-10-05 102 views
1

我写一个多线程的Web服务器,基本上我需要跨多个线程的用户提供的处理程序对象的Vec<Handler>复制服务器上启动。我尝试几种方法:如何在线程之间共享处理程序?

1)定义处理程序为具有fn process(&mut self, Request) -> Response方法的性状。用户将为每个处理程序结构实现它。这种方法在C++或python等语言中很常见。问题是生锈不允许我复制或克隆特质对象,因为它暗示了禁止在特质对象上绑定的特征对象Sized

2)定义处理程序作为Box<FnMut(Request) -> Response>。这不起作用,因为关闭不可复制。

3)我可以线程之间共享同一个对象,但这种让人很没有意义我,因为我需要一个互斥体,其将引入的时候我其实只需要在线程单独副本无用的争论。

我怎样才能正确地实现这一点?

回答

1

最简单的解决方案是要求用户定义的克隆方法。

trait Handler { 
    fn process(&mut self, r: Request) -> Response; 
    fn duplicate(&self) -> Box<Handler>; 
} 

然后你可以很容易地复制你的Vec<Box<Handler>>

+0

感谢您的建议。不幸的是,它似乎不适用于线程。给定的线程拥有Box ,但不包含Handler,这意味着Handler需要实现Send。 Rust无法弄清楚Handler对象在线程之外没有引用。这迫使我使Handler线程安全。 – ElefEnt

+0

复制和线程安全是不同的问题,事实上,如果你希望通过线程发送处理程序,你需要添加绑定到Handler的'Send'(也可能是静态绑定),或者你可以添加它们到Box中,如Box '。为了方便,我会推荐前者。 –

+0

命名该方法'克隆'可能会造成混淆。 – mcarton