2

我有一个类似于这样的线程类:

class thr {
    void run() {
        for (;;) {
            // block on a queue
            // do some processing
            ++loops_;
        }
    }

    void get_metrics(int& qps) {
        std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
        double delta = std::chrono::duration<double>(now - last_metrics_time_).count();
        qps = std::round(loops_ / delta);
        loops_ = 0;
        last_metrics_time_ = now;
    }

    static std::atomic<int> loops_;
    static std::chrono::steady_clock::time_point last_metrics_time_;
};

std::atomic<int> thr::loops_ { 0 };
std::chrono::steady_clock::time_point thr::last_metrics_time_ {
    std::chrono::steady_clock::now() // initial value: when the program starts
};

有很多这样的运行实例。还有另一个线程不时调用 get_metrics()。

我想阻止run()访问last_metrics_time_,因为它不是原子的(只有一个指标收集器线程,所以没有问题)。

last_metrics_time_静态变量设为局部get_metrics似乎并不正确,因为它将在get_metrics第一次调用时初始化,而不是在程序启动时初始化。这将导致delta(因为now将非常接近last_metrics_time_) 的值接近于零,并为第一次调用返回一个巨大的值。

4

1 回答 1

10

不。

但是您可以将这个多重职责类拆分为两个单一职责类:一个运行循环、更新loops_并提供对其的只读访问权限,另一个计算指标并记录时间。然后每个函数将只能访问它需要的内容。

于 2015-05-14T14:28:21.373 回答