Search code examples
c++multithreadingthread-safetyc++-chronostdatomic

Is it possible to restrict a member function from accessing a member variable?


I have a thread class similar to this:

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
};

There are many instances of this running. There is another thread which calls get_metrics() from time to time.

I would like to prevent run() from being able to access last_metrics_time_, because it's not atomic (there's only one metrics collector thread, so no problem there).

Making last_metrics_time_ a static variable local to get_metrics doesn't seem right, because it will get initialized when get_metrics is first called, rather than when the program starts. This would result in a near-zero value for delta (because now will be very close to last_metrics_time_) and a huge value returned for the first call.


Solution

  • No.

    But you could split this multiple-responsibility class into two single-responsibility classes: one running the loop, updating loops_, and providing read-only access to it, the other calculating the metrics and recording the time. Then each function will only have access to what it needs.