设计线程安全的可复制类

编程入门 行业动态 更新时间:2024-10-26 12:33:21
本文介绍了设计线程安全的可复制类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

使线程安全的简单方法是添加一个mutex属性,并在访问器方法中锁定互斥体。

cMyClass { boost :: mutex myMutex; cSomeClass A; public: cSomeClass getA(){ boost :: mutex :: scoped_lock lock(myMutex); return A; } };

问题是这会使类不可复制。

我可以通过使互斥量是静态的工作。但是,这意味着当访问任何其他实例时,类的每个实例都会阻塞,因为它们都共享相同的互斥体。

我想知道是否有更好的方法?

我的结论是没有更好的方法。使类私有静态mutex属性的线程安全是'最好的': - 它很简单,它的工作,它隐藏尴尬的细节。

class cMyClass { static boost :: mutex myMutex; cSomeClass A; public: cSomeClass getA(){ boost :: mutex :: scoped_lock lock(myMutex); return A; } };

缺点是类的所有实例共享相同的互斥量,因此不必要地互相阻塞。这不能通过使mutex属性非静态(因此给每个实例自己的mutex)来解决,因为复制和赋值的复杂性是噩梦,如果做得好。

如果需要,个别互斥体必须由外部不可复制的单例管理,并在创建时与每个实例建立链接。

感谢所有回应。

有几个人提到写我自己的副本构造函数和赋值运算符。我试过这个。问题是,我的真正的类有许多属性,在开发过程中总是改变。维护副本构造函数和assignmet运算符是冗长乏味的,并且容易出错,造成很难找到错误。让编译器为复杂类生成这些是一个非常大的节省时间和减少bug的方法。

许多响应都关注使复制构造函数和赋值运算符线程安全。这个要求给整个事情增加了更多的复杂性!幸运的是,对我来说,我不需要它,因为所有的复制是在设置过程中在一个单线程。

我现在认为最好的办法是构建一个小类来保存一个互斥体和关键属性。然后,我可以为关键类编写一个小的拷贝构造函数和赋值运算符,并让编译器来管理主类中的所有其他属性。

class cSafe { boost :: mutex myMutex; cSomeClass A; public: cSomeClass getA(){ boost :: mutex :: scoped_lock lock(myMutex); return A; } (复制构造函数)(赋值op) }; class cMyClass { cSafe S; (... other attributes ...) public: cSomeClass getA(){ return S.getA(); } };

解决方案

简单的事实是, / em>通过发出互斥体在问题上使类线程安全。你无法使这项工作的原因是因为不起作用, ,而不是因为你这样做错了。这是每个人都注意到,当多线程第一次来开始屠杀COW字符串实现。

线程设计发生在应用程序级别,而不是每个类的基础。只有特定的资源管理类在这个级别上应该有线程安全 - 对于他们,你需要写明确的拷贝构造函数/赋值操作符。

The straightforward way to make a class threadsafe is to add a mutex attribute and lock the mutex in the accessor methods

class cMyClass { boost::mutex myMutex; cSomeClass A; public: cSomeClass getA() { boost::mutex::scoped_lock lock( myMutex ); return A; } };

The problem is that this makes the class non-copyable.

I can make things work by making the mutex a static. However, this means that every instance of the class blocks when any other instance is being accessed, because they all share the same mutex.

I wonder if there is a better way?

My conclusion is that there is no better way. Making a class thread-safe with private static mutex attribute is ‘best’: - it is simple, it works, and it hides the awkward details.

class cMyClass { static boost::mutex myMutex; cSomeClass A; public: cSomeClass getA() { boost::mutex::scoped_lock lock( myMutex ); return A; } };

The disadvantage is that all instances of the class share the same mutex and so block each other unnecessarily. This cannot be cured by making the mutex attribute non-static ( so giving each instance its own mutex ) because the complexities of copying and assignment are nightmarish, if done properly.

The individual mutexes, if required, must be managed by an external non-copyable singleton with links established to each instance when created.

Thanks for all the responses.

Several people have mentioned writing my own copy constructor and assignment operator. I tried this. The problem is that my real class has many attributes which are always changing during development. Maintaining both the copy constructor and assignmet operator is tedious and error-prone, with errors creating hard to find bugs. Letting the compiler generate these for complex class is an enormous time saver and bug reducer.

Many responses are concerned about making the copy constructor and assignment operator thread-safe. This requirement adds even more complexity to the whole thing! Luckily for me, I do not need it since all the copying is done during set-up in a single thread.

I now think that the best approach would be to build a tiny class to hold just a mutex and the critical attributes. Then I can write a small copy constructor and assignment operator for the critical class and leave the compiler to look after all the other attributes in the main class.

class cSafe { boost::mutex myMutex; cSomeClass A; public: cSomeClass getA() { boost::mutex::scoped_lock lock( myMutex ); return A; } (copy constructor) (assignment op ) }; class cMyClass { cSafe S; ( ... other attributes ... ) public: cSomeClass getA() { return S.getA(); } };

解决方案

The simple fact is that you cannot make a class thread safe by spewing mutexes at the problem. The reason that you can't make this work is because it doesn't work, not because you're doing this technique wrong. This is what everyone noticed when multithreading first came and started slaughtering COW string implementations.

Thread design occurs at the application level, not on a per-class basis. Only specific resource management classes should have thread-safety on this level- and for them you need to write explicit copy constructors/assignment operators anyway.

更多推荐

设计线程安全的可复制类

本文发布于:2023-10-30 03:36:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1541649.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!