原子类对象方法用法

Ant*_*kov 2 c++ multithreading atomic c++11

我想从两个线程原子地调用某些类的方法.我有来自第三方库的非安全类,但需要像这样使用这个类:

主线程:

Foo foo;
foo.method1(); // while calling Foo::method1 object foo is locked for another threads
Run Code Online (Sandbox Code Playgroud)

第二个帖子:

foo.method2(); // wait while somewere calling another methods from foo
Run Code Online (Sandbox Code Playgroud)

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

And*_*owl 5

您不能使用std::atomic非易失性的用户定义类型,并且标准仅为某些基本类型提供一组有限的特化.在这里,您可以找到所有标准专业的列表std::atomic.

您可能需要考虑的一种方法是编写一个通用包装器,它允许您以可线程安全的方式在包装对象上提供可调用对象.Herb Sutter曾在其中一次会谈中提出了这些问题:

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;
};
Run Code Online (Sandbox Code Playgroud)

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

这是你如何使用它:

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

    s.thread_safe_invoke([&] (auto& s)
    {
        std::cout << s.size() << " " << (s + s);
    });
}
Run Code Online (Sandbox Code Playgroud)

有关更深入的分析和实施指南,您可以参考 有关此主题的本文以及主题.