gpt4 book ai didi

c++ - boost::shared_ptr 和多线程访问

转载 作者:搜寻专家 更新时间:2023-10-31 00:49:33 25 4
gpt4 key购买 nike

我正在尝试实现一个多线程框架,其中在我的网络线程运行的每一帧的末尾创建输出对象,以便另一个线程可以在其帧的开头获得最近的“完成output"指针,并且知道它对存储在输出对象中的任何数据具有安全和完整的只读访问权限。

我的(很早的)方法主要涉及以下代码块:

网络处理程序 -

void NetworkHandler::Tick()
{
// Tick on our io_service
m_ios.poll();

// Assemble new output data
this->AssembleOutput();
}

客户端网络处理程序 -

void ClientNetworkHandler::AssembleOutput()
{
std::tr1::shared_ptr<crusade::task::TaskOutput> newOutput(new crusade::task::TaskOutput());
newOutput->m_outputElements["connected"] = std::tr1::shared_ptr<crusade::task::TaskOutputElement>(new NetworkConnectedTaskOutputElement(this->m_isConnected));
this->m_latestOutput.swap(newOutput);
}

PyCruHandler-

void PyCruHandler::Tick()
{
printf("PyCruHandler\n");
// Get any necessary inputs from other threads
m_latestNetworkOutput.swap(crusade::task::THManager::GetInstance()->GetTaskHandler(crusade::task::THManager::TH_NETWORK)->GetLatestOutput());
// Other unrelated processing to go here
}

基本上,ClientNetworkHandler 和 PyCruHandler 在不同的线程上独立运行。 PyCruHandler 实际上从未对它的 m_latestNetworkOutput 拷贝做任何事情;我已经注释掉了以任何方式访问它的所有其他实例,但我仍然遇到以下问题:

如果我允许两个线程调用 swap(或 operator= 等价物),那么最终(通常在运行后 2 秒内,但有时需要几分钟)我将在 operator new 或 allocator 上收到以下错误某种删除:

“HEAP:释放堆 block 2bab3b0 在释放后在 2bab3dc 修改Windows 已触发断点。

这可能是由于堆的损坏,这表明存在错误……等等。”

我只是一个新手,但对我来说,这似乎表明 shared_ptr 对象之间存在某种线程安全和时间敏感访问问题。然而,我对 shared_ptr 线程安全的细微差别的解释(在这里和其他地方)感到尴尬 - 一篇文章表明引用计数是线程安全的,所以复制 shared_ptr 是安全的(但它们的内部对象不会是线程安全的),其他读物表明在 shared_ptr 中实际上没有任何有用的线程安全。我已经阅读了关于 shared_ptrs 线程安全的 boost 文档,但我仍然没有弄清楚这是否应该是我的代码中的问题。

我的问题是,这里的任何人都可以发现我所做的任何明显缺陷吗?我的目标是我可以访问仍然由拥有线程存储的最新输出对象,然后该对象不会被删除(即使在拥有线程已经移动到后面的输出之后)直到输出的每个用户都完成了它以及。在我看来,共享指针似乎很适合这个……但是在我的头撞了 3 个小时之后,我开始怀疑……

在此先感谢您,如果我以某种方式发布不正确,我深表歉意;这是我第一次来这里,就协议(protocol)而言,常见问题解答似乎很随意!

最佳答案

这里最好的资源可能是 the documentation :

Thread Safety

shared_ptr objects offer the samelevel of thread safety as built-intypes. A shared_ptr instance can be"read" (accessed using only constoperations) simultaneously by multiplethreads. Different shared_ptrinstances can be "written to"(accessed using mutable operationssuch as operator= or reset)simultaneosly by multiple threads(even when these instances are copies,and share the same reference countunderneath.)

Examples:

shared_ptr<int> p(new int(42));

//--- Example 1 ---

// thread A
shared_ptr<int> p2(p); // reads p

// thread B
shared_ptr<int> p3(p); // OK, multiple reads are safe

//--- Example 2 ---

// thread A
p.reset(new int(1912)); // writes p

// thread B
p2.reset(); // OK, writes p2

//--- Example 3 ---

// thread A
p = p3; // reads p3, writes p

// thread B
p3.reset(); // writes p3; undefined, simultaneous read/write

//--- Example 4 ---

// thread A
p3 = p2; // reads p2, writes p3

// thread B
// p2 goes out of scope: undefined, the destructor is considered a "write access"

//--- Example 5 ---

// thread A
p3.reset(new int(1));

// thread B
p3.reset(new int(2)); // undefined, multiple writes

我假设您代码中的 m_latestOutput 是一个 shared_ptr - 在这种情况下,您遇到的示例最接近数字 5(多次写入) .

关于c++ - boost::shared_ptr 和多线程访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1151100/

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