最近,我遇到了赫伯·萨特的视频关于const和mutable的含义在C++11中是如何改变为按位const (以及线程安全的结果)的,而不是传统的逻辑const。
五年后,程序员们是否迁移到了const这个新的含义?
我在编写一个新的应用程序时尝试使用这个方法,但似乎我将每个私有成员标记为可变的,因为它们要么受到互斥对象的保护,要么受到线程的安全保护(通过它们的实现)--这感觉不对(我没有经验,也没有这方面的基础)。
当设计一个线程安全应用程序来标记每个成员函数const和每个成员变量mutable时,这是一个好的实践吗?
发布于 2018-10-06 08:46:13
你引用的视频是为先进和专业的观众。赫伯·萨特试图让观众们对如何最好地将这些关键词的意图传达给其他人达成共识,在这个一切都渴望线程安全的时代。
因此,不要期望这个视频包含了所有你需要知道的,以编写完美的线程安全代码。
我将每个私有成员标记为可变的,因为它们要么受到互斥对象的保护,要么受到线程安全(通过它们的实现)的保护--这感觉不对(我没有经验,也没有这方面的基础)。
下面是一个假设的例子,说明什么是明目张胆的错误:
class Size
{
mutable int x;
mutable int y;
// ...
public:
void setSize(int newX, int newY) const // (first scream)
{
// modify members "x" and "y", "SAFELY!" (second scream)
}
};函数签名尖叫错误,因为名为setSize的函数不可能是const。函数代码的实现最终需要将成员"x“和"y”标记为mutable,这也会导致错误。
setSize函数中的代码并不重要。如果函数的名称意味着该函数将更改对象的状态,则不应该用const标记它。让我们假设我们从函数中删除const关键字。现在,我们发现不需要在成员"x“和"y”上使用mutable关键字。问题解决了。
换句话说,如果const和mutable的使用都违背直觉,如果这种尴尬的用法成对发生,那么人们应该怀疑它们的用法是错误的。
然而,视频提到了一个例外情况。如果类包含std::mutex成员,则将其标记为mutable成员几乎总是正确的。有关解释,请参阅录影带。
一旦你有了正确的经验,你就可以依靠你的直觉来判断它是否看上去是自然的,而自然的方法是正确的。
如果函数的名称意味着它不应该更改对象的状态,那么应该用const标记它,并且需要通过不执行线程不安全的操作,使内部的代码成为线程安全的。
这就是上面链接的视频中所表达的心态。当谈到线程安全时,您的代码的用户(您自己或您的队友)有一定的期望,某些功能不应该做某些事情。
视频提到了以下几个例子:
bool operator == (const T& other) const不应该修改this或other,因为没有人会期望比较会修改任何东西。(这被称为“无副作用”。)class T { public: T(const T& other) {...} };不应该修改other,因为相同的other实例可能被传递到两个线程中,每个线程都将其传递到复制构造函数中。这个密码怎么样?
class Size
{
const int x;
const int y;
// ...
public:
Size(int init_x, int init_y)
: x(init_x), y(init_y)
{
}
};这个代码甚至更好。它演示了const在成员上的正确使用。
但是,它确实阻止了一个人以某种方式使用Size类。例如,不能使用赋值运算符覆盖Size的现有实例。换句话说,按照实现Size类时的最佳实践,可能需要重新设计使用Size的其他源代码。这是一个“传染性问题”,使得const-ness成为C++项目的一个重要考虑因素。
发布于 2018-10-06 08:46:03
在设计线程安全应用程序以标记每个成员函数const和每个成员变量可变时,是否有良好的实践?
不,这不是很好的做法。
const成员函数指示该函数不会修改所调用的对象。因为对象不会被修改,所以在没有外部锁定的情况下从多个线程调用函数是安全的。
然而,const成员函数不是唯一的线程安全函数.任何其他函数也可以是线程安全的。
使用const修饰符将变异函数标记为线程安全是错误的信号.
发布于 2021-04-21 18:48:33
正如其他人已经指出的,const函数意味着同时从多个线程调用它应该是线程安全的,而不同时调用非const函数。正如草本萨特 (29:43)自己说的那样,这意味着一个const函数应该是按位的const或内部同步的,如果可以同时调用其他非const函数,这并不是真正的线程安全。
线程安全绝对不意味/暗示const。
请注意,以下旧威胁仍然相关:在C++11中,const意味着线程安全吗?,但请记住,线程安全一词经常被滥用(参见根据C++11 (语言/库)标准,线程安全函数的定义是什么?),即在这种情况下,线程安全用于按位连接或内部同步。
https://softwareengineering.stackexchange.com/questions/379516
复制相似问题