c++ - 原子类对象方法的用法

标签 c++ multithreading c++11 atomic

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

主线程:

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::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关于这个主题以及this one .

关于c++ - 原子类对象方法的用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28051472/

相关文章:

c++ - XML 在 ListView 中没有改变

C++ 链表的合并排序不对前两个索引进行排序

c++ - 没有用于调用 FMOD::Studio::System::setListenerAttributes() 的匹配函数

android - 在单独的线程中从服务中获取 AutoCompleteTextView 建议

java - Java 中每个键的线程池

c++ - 如何将可调用对象放入 C++ 中的映射中?

multithreading - boost ASIO IO_SERVICE 实现?

c++ - 为什么总是调用 `static_assert`?

字符串作为键和类型作为值的 C++ 映射

c++ - 模板、decltype 和非类类型