面试题答案
一键面试为什么const成员函数理论上更容易保证线程安全
- 概念理解:
const
成员函数承诺不修改对象的成员变量(除非这些成员变量被声明为mutable
)。这意味着在多线程环境下,const
成员函数不会改变对象的状态,从而减少了数据竞争的可能性。- 数据竞争通常发生在多个线程同时访问和修改同一数据时,而
const
成员函数的只读性质使得它不太可能引发这种竞争。例如,假设有一个类MyClass
:
在多线程环境下,多个线程可以安全地调用class MyClass { public: int getValue() const { return value; } private: int value; };
getValue
函数,因为它不会修改value
,不会产生数据竞争。
看似线程安全的const成员函数实际并非线程安全的场景及原因
- 场景:
- 考虑一个用于统计函数调用次数的类
CallCounter
:
这里class CallCounter { public: int getCallCount() const { return callCount; } private: mutable int callCount; };
getCallCount
是一个const
成员函数,因为它需要返回callCount
的值,而callCount
被声明为mutable
以便在const
成员函数中可以修改它。 - 考虑一个用于统计函数调用次数的类
- 原因:
- 在多线程环境下,虽然
getCallCount
是const
成员函数,但它读取的callCount
可能在其他线程中被修改。例如,如果一个线程正在调用getCallCount
读取callCount
的值,而另一个线程同时在增加callCount
的值,就会发生数据竞争。 - 这里
callCount
虽然是为了在const
函数中修改而设为mutable
,但它的并发访问没有进行同步保护(如使用互斥锁等机制),所以看似线程安全的const
成员函数getCallCount
实际上并非线程安全。
- 在多线程环境下,虽然