4

我正在尝试在 Actix-Web 框架中使用Arc和实现共享状态Mutex。下面的代码可以编译,但是当我运行它时,计数器有时会一直回到 0。如何防止这种情况发生?

use actix_web::{web, App, HttpServer};
use std::sync::{Arc, Mutex};

// This struct represents state
struct AppState {
    app_name: String,
    counter: Arc<Mutex<i64>>,
}

fn index(data: web::Data<AppState>) -> String {
    let mut counter = data.counter.lock().unwrap();
    *counter += 1;
    format!("{}", counter)
}

pub fn main() {
    HttpServer::new(|| {
        App::new()
            .hostname("hello world")
            .register_data(web::Data::new(AppState {
                app_name: String::from("Actix-web"),
                counter: Arc::new(Mutex::new(0)),
            }))
            .route("/", web::get().to(index))
    })
    .bind("127.0.0.1:8088")
    .unwrap()
    .run()
    .unwrap();
}
4

1 回答 1

6

HttpServer::new为运行服务器的每个线程调用一个闭包。这意味着AppState创建了多个实例,每个线程一个。根据响应 HTTP 请求的线程,您将获得不同的实例,data因此会获得不同的计数器值。

为防止这种情况发生,web::Data<AppState>请在闭包外部创建并在闭包内使用克隆引用HttpServer::new

于 2019-12-29T16:25:55.080 回答