MUD服务器的Rust同步策略



因此,如果您有一个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个用户怎么样?我只是在寻找一个正确的方向。

Arc允许您访问多个任务中的值,但不允许您可变地借用该值。编译器无法静态验证一次只有一个任务会可变地借用值,并且在不同任务上同时更改值会导致数据竞赛

Rust的标准库提供了一些类型,允许安全地更改共享对象。这里有两个:

  • Mutex:这是一个简单的互斥锁Mutex封装受保护的值,因此访问该值的唯一方法是锁定互斥锁。一次只能有一个任务访问包装的值
  • RWLock:这是一个读写器锁。这种锁允许多个任务同时读取一个值,但写入程序必须具有独占访问权限。这与借用检查器和RefCell的规则基本相同(除了锁等待借用释放,而不是编译失败或恐慌)

您需要将MutexRWLock封装在Arc中,以使其可用于多个任务。

最新更新