原子类对象方法用法
Atomic class object methods usage
我想从两个线程以原子方式调用某个类的方法。我有来自第三方库的非头安全类,但需要像这样使用这个类:
主线程:
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
用于不可复制的用户定义类型,并且标准仅为某些基本类型提供了一组有限的专用化。在这里,您可以找到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;
};
如果您只想以线程安全的方式调用单个函数,这会产生一些语法开销,但它也允许实现必须以原子方式执行的事务,并且可能包含对同步对象的多个函数调用。
这是您可以使用它的方式:
int main()
{
synchronized<std::string> s{"Hello"};
s.thread_safe_invoke([&] (auto& s)
{
std::cout << s.size() << " " << (s + s);
});
}
有关更深入的分析和实施指南,您可以参考有关该主题的这篇文章以及本文。
在不同的线程之间共享一个std::mutex
。无论您在哪里使用foo
,请用std::unique_lock
包装呼叫
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 通过方法访问结构
- 最小硬币更换问题(自上而下方法)
- C++为构建时间获取QDateTime的可靠方法
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 有什么方法可以遍历结构吗
- 当类在C++中定义时,有什么方法可以"register"类吗?
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 复制构造函数方法的用法
- 为什么"Warning X4000: use of potentially uninitialized variable"显示多个常用方法的用法?
- 原子类对象方法用法
- Recv 方法用法
- 命名参数习惯用法,使用指向类私有方法的指针
- 获取源代码树中 boost:shared_ptr get 方法的所有用法的列表
- 指针和方法的奇怪用法
- "GetObjectClass"方法和"FindClass"方法的区别和用法