gpt4 book ai didi

c++ - boost::shared_ptr 直接替换

转载 作者:行者123 更新时间:2023-11-28 03:22:10 25 4
gpt4 key购买 nike

最近我开始处理一个遗留项目并尝试修复段错误(双重删除)。其中许多发生在 boost::shared_ptr 析构函数或 operator=(在包含 shared_ptr 的对象上)。该代码包含大量使用 shared_ptr-s,包括复制、重置 ()、分配等。根据 boost docs我们没有有效的用法 - 在许多线程中破坏/复制/重置相同的 shared_ptr 是不安全的。

每次都锁定似乎是不可能的,所以我正在寻找 boost::shared_ptr 的直接替代品。所以问题是:如果我将所有 boost::shared_ptr 替换为 std::shared_ptrstd::tr1::shared_ptr 将解决这个问题?似乎 tr1 是更安全的版本,但我不清楚。第二个问题——c++0x 版本比 tr1 好吗? (注意我们有 gcc 4.4.6,不能升级)

根据gcc docs , c++11 std::shared_ptr 应该解决这个问题,但我不确定 gcc4.4 版本...

UPD:刚刚做了实验,现在我知道所有 3 种实现都在这段代码(gcc 4.4)上做段错误。看来我应该制作自定义类或其他解决方法......

#include <iostream>
#include <boost/thread.hpp>
#include <boost/shared_ptr.hpp>

typedef boost::shared_ptr<int> ptrtype;

ptrtype p(new int);

void test() {
for(long i=0; i<1000000; ++i) {
ptrtype p1 = p;
p = ptrtype();
p.reset( new int );
}
}

int main() {
boost::thread_group tg;
for(int i=0; i<100; ++i) tg.add_thread( new boost::thread(test) );
tg.join_all();
std::cout << "Normal exit\n";
return 0;
}

最佳答案

第 1 步:构建一个这样的类,并替换 boost::shared_ptr<T> 的用法与它。

template<typename T>
struct trivial_ptr {
T* t;
template<typename U>
void reset( U* p ) {t=p;}
void reset( T* p = NULL ) { t=p; }
template<typename U>
trivial_ptr<T>& operator=(trivial_shared_ptr<U>const& o) {
t = o.t;
return *t;
}
explicit trivial_ptr( T* p ):t(p) {}
...
};

这个类不是用来运行的,只是为了编译出正确的接口(interface)。编译后,您可以确保知道 boost::shared_ptr 的哪些部分你正在使用的界面。 (您是否在使用自定义删除器?等等——问题可能更难,也可能更容易,以上内容可以帮助测试)

一旦你到了那里,你就会知道写一个 shared_ptr<T> 有多难。处理同时访问同一变量的多个线程。

现在,这非常困惑。如果一个线程reset给定shared_ptr当另一个线程从中读取时,从中读取的指针可能在读取线程访问它时完全无效。实际上,您需要保护对互斥体中底层指针的所有访问,这是完全不切实际的。

另一方面,如果您拥有多个读者,而不是读者和作者,那么情况会更好——理论上,您可以通过在引用计数代码上使用适当的锁来解决问题.

但是,您实际描述的内容似乎涉及多个线程同时读取和写入同一个变量。这从根本上被打破了,即 shared_ptr 上的线程安全性变量不会修复。

关于c++ - boost::shared_ptr 直接替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15120603/

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