Использование мьютекса, доступ к которому осуществляется через указатель члена, для регулирования доступа потока к этому классу. - PullRequest
1 голос
/ 17 января 2020

Несмотря на то, что этот код работает, я просто хочу быть уверен, что для класса все в порядке, чтобы получить доступ / использовать мьютекс, доступ к которому осуществляется через указатель члена, для регулирования доступа потока к этому классу. Я хотел избежать использования общедоступного мьютекса:

#include <thread>
#include <mutex>
#include <memory>
#include <iostream>

class Foo {
    std::mutex mtx_;
public:
    Foo () : mtx_ {}, a_ {} {}
    std::mutex& get_mutex() { return mtx_; }
    void increment() {
        std::lock_guard<std::mutex> lock(mtx_);
        ++a_;
    }
    void print() { std::cout << a_ << '\n'; }
    int a_;
    // std::atomic_int a_;  // not used
};

class Bar {
public:
    std::shared_ptr<Foo> ptr;
    Bar() : ptr {} {}
    void increment() const {
        if (ptr) {
            std::lock_guard<std::mutex> lock(ptr->get_mutex());  // get Foo's mutex and lock it
            ++ptr->a_;
        }
    }
};

void loop1(Foo *f) {
    for (int i{}; i < 1000000; ++i) { f->increment(); }
}

void loop2(Bar *b) {
    for (int i{}; i < 1000000; ++i) { b->increment(); }
}

int main() {
    Bar b;
    Foo *f = new Foo;
    b.ptr.reset(f);

    std::thread th1(loop1, f);
    std::thread th2(loop2, &b);
    th1.join();
    th2.join();

    f->print();
    return 0;
}
...