Стратегия синхронизации ржавчины для сервера MUD
Так что, если у вас был сервер 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}
}
}
Будет ли Арк путь?
let shared_server = Arc::new(server);
let server = shared_server.clone();
spawn(proc() {
// Work with server
});
Как насчет масштабирования до 100 или 1000 пользователей? Я просто ищу толчок в правильном направлении.
1 ответ
Arc
позволит вам получить доступ к значению из нескольких задач, но не позволит вам позаимствовать значение изменчиво. Компилятор не может статически проверить, что только одна задача заимствует значение изменчиво за раз, а изменение значения одновременно в разных задачах приводит к гонкам данных.
Стандартная библиотека Rust предоставляет некоторые типы, которые позволяют безопасно изменять общий объект. Вот два из них:
Mutex
: Это простая блокировка взаимного исключения.Mutex
оборачивает защищенное значение, поэтому единственный способ получить доступ к значению - заблокировать мьютекс. Только одна задача за раз может получить доступ к перенесенному значению.RWLock
: Это блокировка чтения-записи. Этот тип блокировки позволяет нескольким задачам читать значение одновременно, но авторы должны иметь монопольный доступ. Это в основном те же правила, что и проверка заимствования иRefCell
иметь (за исключением блокировки ожидает освобождения заимствования, вместо сбоя компиляции или паники).
Вам нужно будет обернуть Mutex
или RWLock
в Arc
сделать его доступным для нескольких задач.