【问题标题】:Boost shared_ptr container question提升 shared_ptr 容器问题
【发布时间】:2025-11-29 00:25:01
【问题描述】:

假设我有一个多线程应用程序使用的指针容器 (std::vector)。在向容器添加新指针时,代码使用临界区 (boost::mutex) 进行保护。一切都很好。代码应该能够将这些指针之一返回给线程进行处理,但另一个单独的线程可以选择删除这些指针之一,该指针可能仍在使用中。例如:

thread1()
{
    foo* p = get_pointer();
    ...
    p->do_something();
}

thread2()
{
    foo* p = get_pointer();
    ...
    delete p;
}

所以 thread2 可以在 thread1 使用指针时删除指针。讨厌。

所以我想使用 Boost 共享 ptrs 的容器。 IIRC 这些指针将被引用计数,因此只要我返回共享 ptrs 而不是原始指针,从容器中删除一个不会真正释放它,直到最后一次使用它超出范围。即

std::vector<boost::shared_ptr<foo> > my_vec;

thread1()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    sp->do_something();
}

thread2()
{
    boost::shared_ptr<foo> sp = get_ptr[0];
    ...
    my_vec.erase(my_vec.begin());
}

boost::shared_ptr<foo> get_ptr(int index)
{
    lock_my_vec();
    return my_vec[index];
}

在上面的例子中,如果thread1在thread2调用erase之前得到了指针,那么指向的对象是否仍然有效?当thread1完成时它实际上不会被删除? 请注意,将通过临界区访问全局向量。

我认为这就是 shared_ptrs 的工作方式,但我需要确定。

【问题讨论】:

    标签: c++ boost smart-pointers


    【解决方案1】:

    对于 boost::shared_ptr 的线程安全,您应该检查this link。它不能保证安全,但在许多平台上它都有效。修改 std::vector 是不安全的 AFAIK。

    【讨论】:

      【解决方案2】:

      在上面的例子中,如果thread1在thread2调用erase之前得到了指针,那么指向的对象是否仍然有效? thread1完成后实际上不会被删除?

      在您的示例中,如果 thread1 在 thread2 之前获得指针,则 thread2 将不得不在函数的开头等待(因为锁)。所以,是的,指向的对象仍然有效。但是,您可能需要确保 my_vec 在访问其第一个元素之前不为空。

      【讨论】:

        【解决方案3】:

        此外,如果您同步对向量的访问(如在您的原始原始指针提案中),则您的使用是安全的。否则,您可能会违反其他受访者提供的链接中的示例 4。

        【讨论】: