因此,如果你有一个MUD服务器在一个单独的进程中处理每个tcp连接,
for stream in acceptor.incoming() {
match stream {
Err(e) => { /* connection failed */ }
Ok(stream) => spawn(proc() {
handle_client(stream)
})
}
}
为该服务器共享可变世界数据的策略是什么?我可以想象n个连接响应来自用户的命令。每个命令都需要访问并可能修改世界。
pub struct Server<'a> {
world: World<'a>
}
pub struct World<'a> {
pub chat_rooms: HashMap<&'a str, ChatRoom<'a>>
}
impl<'a> World<'a> {
pub fn new() -> World<'a> {
let mut rooms = HashMap::new();
rooms.insert("General", ChatRoom::new("General"));
rooms.insert("Help", ChatRoom::new("Help"));
World{chat_rooms: rooms}
}
}
Arc会成为可行的方式吗?
let shared_server = Arc::new(server);
let server = shared_server.clone();
spawn(proc() {
// Work with server
});
如何扩展到100或1000个用户?我只是想朝着正确的方向努力。
答案 0 :(得分:4)
Arc
将允许您从多个任务中访问值,但它不允许您可变地借用该值。编译器无法静态验证一次只有一个任务可以可变地借用值,并且在不同任务上同时改变值会导致数据竞争。
Rust的标准库提供了一些允许安全地改变共享对象的类型。以下是其中两个:
Mutex
:这是一个简单的互斥锁。 Mutex
包装受保护的值,因此访问该值的唯一方法是锁定互斥锁。一次只能有一个任务访问包装的值。RWLock
:这是一个读者 - 作者锁。这种锁允许多个任务同时读取值,但编写者必须具有独占访问权限。这基本上与借用检查器和RefCell
具有相同的规则(除了锁等待释放借用,而不是编译或恐慌失败)。您需要在Mutex
中包含RWLock
或Arc
,以使其可以访问多个任务。