gpt4 book ai didi

c++ - 将 shared_ptr 传递给线程

转载 作者:行者123 更新时间:2023-11-28 02:49:31 25 4
gpt4 key购买 nike

我有以下代码:

shared_ptr<A> a;
B b(a);
a.reset(new A());

在 B 类中,我创建了一个新线程并等待 a 准备就绪:

B(shared_ptr<A> a) {
_a = a;
//create thred here
}

//...

//in thread:
while (_this->_a == NULL) {}

问题是,即使在 a.reset(new A()); 行执行之后,在 B 中启动的线程仍然认为 _th​​is->_a是空的,永远不会离开 while 循环!

我尝试使用 a = make_shared(new A());a = shared_ptr(new A()); - 效果还是一样。我还尝试将 a 作为 const 引用 - 同样的事情。

最有趣的是,当我使用普通指针并将对该指针的引用传递给类 B 时,一切正常:

A* a;
B b(a);
a = new A();

//...

B(A*& a) {
_a = a;
//create thred here
}

//in thread:
while (_this->_a == NULL) {}
//In this case the loop is finished

我在这里错过了什么?

更新(2014 年 5 月 1 日):我用这样的代码解决了这个问题:

typedef shared_ptr<ClassA> ClassAPtr;
typedef shared_ptr<ClassB> ClassBPtr;
typedef shared_ptr<ClassC> ClassCPtr;

//...

ClassAPtr a(new ClassA());
ClassBPtr b( new ClassB() );
b->attachA(a);
a->attachB(b);
ClassCPtr c( new ClassC() );
c->attachB(b);
c->attachA(a);

c->run();
b->run();
a->run();

虽然在每个类中我都有原子变量 _running:

atomic<bool> _running;

我在每个线程循环中还有以下同步代码:

while (
_this->_a == NULL || !_this->_a->isRunning()
||
_this->_b == NULL || !_this->_b->isRunning()
)
std::this_thread::sleep_for(std::chrono::milliseconds(500));

最佳答案

您传递的是 shared_ptr<A>拷贝B 的实例.当您将新对象分配给 a 时调用reset ,存储在 b 中的拷贝不知道这已经发生了。这就是它永远看不到更新的原因。

调用 shared_ptr::reset生成 shared_ptr 的实例放弃被管理对象的所有权,这意味着递减 use_count如果该实例恰好是唯一所有者,则销毁该对象。如果不是唯一所有者,则其他shared_ptr管理那个对象变成负责管理它的生命周期。在任何一种情况下,您调用的实例 reset现在可以自由获取您可能已作为参数传递的另一个对象的所有权。在您的情况下,这要简单一些,因为最初没有管理对象,但适用相同的逻辑。存储在 b 中的拷贝与 a 没有任何关联在调用 reset 后.

说你的类(class) A实现两个成员函数,activate()is_active() ,具有明显的功能。还假设构建 A 的实例在你调用 activate() 之前让它处于停用状态.那么你可以按如下方式解决这个问题:

auto a = make_shared<A>();
B b(a);
a->activate();

// within the thread
while (!_this->_a->is_active()) {}

即便如此,您仍需要使用一些同步原语来防止数据竞争。例如,如果 activate()设置一个 bool 数据成员,该成员的类型应该是std::atomic<bool>std::atomic_flag ,而不是普通的 bool .这同样适用于可能从不同线程读取和写入的任何其他数据成员。

关于c++ - 将 shared_ptr 传递给线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23376774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com