使用指针线程化共享模型

Posted

技术标签:

【中文标题】使用指针线程化共享模型【英文标题】:Threading a Shared Model with pointers 【发布时间】:2011-03-05 00:10:06 【问题描述】:

我有一个指向用 new 创建的对象的指针向量。多个线程使用各种获取/设置以安全的方式访问此向量。但是,一个线程可能会删除其中一个对象,在这种情况下,另一个线程指向该对象的指针不再有效。方法如何知道指针是否有效?选项 1 和 2 实际上似乎运作良好。我不知道他们将如何扩展。最好的方法是什么?有便携版 3 吗?

测试有效的指针有效性示例:

1. 使用整数而不是指针。哈希 (std::map) 检查指针是否仍然有效。公共方法如下所示:

get(size_t iKey)

   if((it = mMap.find(iKey)) != mMap.end())
   
       TMyType * pMyType = it->second;
       // do something with pMyType
   

2.有一个shared_ptr的向量。每个线程都尝试在其 weak_ptr 上调用 lock()。如果返回的 shared_ptr 为 null,我们知道有人在我们等待时删除了它。公共方法如下所示:

get(boost::weak_ptr<TMyType> pMyType)

    boost::shared_ptr<TMyType> pGOOD = pMyType.lock();
    if (pGOOD  != NULL)
    
         // Do something with pGOOD
    
 

3. 在纯原始指针上测试 null 吗?这可能吗?

get(TMyType * pMyType)

    if(pMyType != NULL) //do something 

【问题讨论】:

【参考方案1】:

#3 将不起作用。删除指针并将其设置为 NULL 不会影响指向同一对象的其他指针。您无法使用原始指针来检测对象是否被删除。

#1 实际上是一个指向指针的指针。如果您始终通过该指针访问它并能够锁定它。如果没有,如果你成功获取后在另一个线程中删除了会怎样?

#2 是这种想法的标准实现,该模式在很多库中都有使用。锁定一个把手,得到一个指针。如果你得到它,使用它。如果没有,它就消失了。

【讨论】:

关于#3,是的,我应该知道...关于#1,它是一个数字,而不是一个指针。一个线程调用 get() 并获得一个数字,一小时后它调用 set(1234) 并且该方法检查地图中是否仍然存在 1234。地图只能通过线程安全调用访问,所以它工作得很好。当另一个线程删除某些东西时,下面的序列化线程发现它的键不再有效。但是一直在哈希中查找可能无法很好地扩展。 与 #1 数字类似,如果您将其设为指向指针的指针,则 #3 将起作用。 那么如果我把指针指向一个指针,它会起作用吗?如果你不介意的话,告诉我你说什么。 @pcunite,如果你(正确地)使用指向指针的指针,你可以使目标指针为空,你可以检查 *P == NULL。 @stefan,好吧,当对指针调用 delete 时,它​​不知道谁在观察它,因此稍后,当再次使用该内存地址时,双指针会认为事情很好。我需要一个对象,这就是weak_ptr 的真正含义,只是一个观察另一个类的类。我认为...

以上是关于使用指针线程化共享模型的主要内容,如果未能解决你的问题,请参考以下文章

std::async 与共享指针模板化成员函数

线程之间是不是共享指针? [复制]

MapViewOfFile 与线程之间的指针

Qt 5.1 带有共享 QGLWidgets 的线程化 OpenGL

Java内存模型和线程安全

Java内存模型和线程安全