2

Hyper有以下实现的示例HandlerSync

use std::sync::Mutex;
use std::sync::mpsc::{channel, Sender};
use hyper::server::{Handler, Server, Request, Response};

struct SenderHandler {
    sender: Mutex<Sender<&'static str>>
}

impl Handler for SenderHandler {
    fn handle(&self, req: Request, res: Response) {
        self.sender.lock().unwrap().send("start").unwrap();
    }
}

并声明Handler必须实现Sync,因为Handler可以从不同的线程调用。

对我来说,这听起来像是不必要的性能损失。我更愿意为每个线程设置一个SenderHandler,每个线程都是独立的,这将消除对实现Sync.

我是否误解了 Hyper,Rust 的类型系统,或者这不可能?

4

2 回答 2

4

这是剪纸问题。

Sync对于任何无状态处理程序都可以轻松实现;相反,有一个Clone界限意味着有多个并发状态彼此独立发展(请求被随机分派)。我什至不确定是否可以保证在处理请求期间等待时会调用同一个线程并使用结果。

通过使用Sync,作者迫使您思考跨查询(甚至查询内)共享状态意味着什么。


在提供的示例中,我很想删除保护 Sender 的 Mutex,因为 Sender 已经为无锁线程内消息传递而设计。它所需要的只是每个线程的克隆。

如果是,您可以拥有Sender实现Sync(显然,仔细考虑),然后删除Mutex.

尽管不太优雅,但也可以使用thread_local!宏为每个线程创建一个实例,然后蹦床处理程序Sender在调用时将工作分派给本地线程。


最后,请注意 hyper 目前正在重新设计中;它应该移动到Future可能会或可能不会在这里引起一些重新考虑的地方。

于 2016-10-15T15:14:53.420 回答
3

好的,所以目前这在 Hyper 中似乎是不可能的。它在issue 248中进行了讨论,开发人员更Sync喜欢Clone

我们在 IRC 上讨论了这个问题。简单的概要是,如果它是 Clone,用户可以很容易地在他们的处理程序上拥有他们认为每个请求都会修改的状态,但是相反,它会被克隆多次并且不会修改他们希望的内容。相反,最好强制用户确保他们的状态是同步的。

于 2016-10-15T15:06:05.593 回答