【发布时间】:2018-06-09 05:04:36
【问题描述】:
我正在尝试创建一个小类,以便我促进两个线程之间的通信。
这些线程很可能会比创建上述类的上下文寿命更长,因为它们在线程池中排队。
到目前为止我所尝试的 (on coliru as well):
class A
{
public:
A(int maxVal) : maxValue(maxVal) {}
bool IsOverMax() const { return cur >= maxValue; }
void Increase() { cur++; }
private:
const int maxValue;
atomic_int cur{ 0 };
};
可能的用法:
void checking(const shared_ptr<A> counter)
{
while(!counter->IsOverMax())
{
cout<<"Working\n"; // do work
std::this_thread::sleep_for(10ms);
}
}
void counting(shared_ptr<A> counter)
{
while (!counter->IsOverMax())
{
cout<<"Counting\n";
counter->Increase(); // does this fall under `...uses a non-const member function of shared_ptr then a data race will occur`? http://en.cppreference.com/w/cpp/memory/shared_ptr/atomic
std::this_thread::sleep_for(9ms);
}
}
int main()
{
unique_ptr<thread> t1Ptr;
unique_ptr<thread> t2Ptr;
{
auto aPtr = make_shared<A>(100); // This might be out of scope before t1 and t2 end
t1Ptr.reset(new thread(checking, aPtr)); // To simbolize that t1,t2 will outlive the scope in which aPtr was originaly created
t2Ptr.reset(new thread(counting, aPtr));
}
t2Ptr->join();
t1Ptr->join();
//cout<< aPtr->IsOverMax();
}
我担心的原因是documentation 说:
如果多个执行线程在没有同步的情况下访问同一个 std::shared_ptr 对象,并且这些访问中的任何一个使用了 shared_ptr 的非 const 成员函数,那么将发生数据竞争,除非所有此类访问都是通过这些函数执行,它们是相应原子访问函数(std::atomic_load、std::atomic_store 等)的重载
- 所以
Increase是一个非常量函数,对于这种情况,aPtr 的副本是否是the same std::shared_ptr? - 此代码是线程安全的吗?
- 这对于非原子对象是否可行(例如使用 std::mutex 锁定对常规 int 的读取和写入)?
- 无论如何,为什么?
【问题讨论】:
标签: multithreading c++11 thread-safety atomic