原子 class 对象方法用法

Atomic class object methods usage

我想从两个线程中自动调用某些 class 的方法。 我有来自第三方库的非头部安全 class,但需要像那样使用此 class:

主线程:

Foo foo;
foo.method1(); // while calling Foo::method1 object foo is locked for another threads

第二个线程:

foo.method2(); // wait while somewere calling another methods from foo

这种情况下如何使用std::atomic?或者可能是另一种解决方案(排除在从 foo 调用方法之前使用互斥锁和锁定以及在调用方法之后解锁)?

分享一个std::mutex between the different threads. Where ever you use foo, wrap the calls with a std::unique_lock

您不能将 std::atomic 与不可简单复制的用户定义类型一起使用,并且标准仅为某些基本类型提供了一组有限的专用化。 Here 您可以找到 std::atomic 的所有标准专业的列表。

您可能要考虑的一种方法是编写一个通用包装器,它允许您提供可调用对象,以便在包装对象上以线程安全的方式执行。 Herb Sutter 曾在 one of his talks:

中介绍过类似的内容
template<typename T>
class synchronized
{
public:
    template<typename... Args>
    synchronized(Args&&... args) : _obj{std::forward<Args>(args)...} { }

    template<typename F>
    void thread_safe_invoke(F&& f)
    {
        std::lock_guard<std::mutex> lock{_m};
        (std::forward<F>(f))(_obj);
    }

    // ...

private:
    T _obj;
    std::mutex _m;
};

如果您只想以线程安全的方式调用单个函数,这会产生一些语法开销,但它也允许实现必须以原子方式执行的事务,并且可能包含多个同步函数调用对象。

您可以这样使用它:

int main()
{
    synchronized<std::string> s{"Hello"};

    s.thread_safe_invoke([&] (auto& s)
    {
        std::cout << s.size() << " " << (s + s);
    });
}

更深入的分析和实施指导,可参考this article on the subject as well as this one