在具有vtable实现的c ++虚拟调用中怀疑多线程竞争条件

时间:2010-07-06 16:48:20

标签: c++ boost race-condition vtable dynamic-dispatch

4 个答案:

答案 0 :(得分:0)

我不太明白,但我认为你可能有两种可能性:

A)“O”在将其传递到同步队列到“B”之前完全构造(返回构造函数)。在这种情况下没有问题,因为对象是完全构造的,包括vtable指针。该位置的内存将具有vtable,因为它都在一个进程内。

B)“O”尚未完全构造,但是例如,您将this从构造函数传递到同步队列中。在这种情况下,仍然必须在线程“A”中调用构造函数体之前设置vtable指针,因为从构造函数调用虚函数是有效的 - 它只调用当前Class的方法版本,不是最衍生的。因此,我不希望在这种情况下看到竞争条件。如果您实际上是将this从其构造函数中传递给另一个线程,您可能需要重新考虑您的方法,因为可能对未完全构造的对象进行调用似乎很危险。

答案 1 :(得分:0)

如果我试着理解你的文章,我相信你会这样问: -

线程“A”在堆上构造对象“O”而没有外部同步

// global namespace
SomeClass* pClass = new SomeClass;

同时你说线程''A'将上面的实例传递给thread-'B'。这意味着实例SomeClass是完全构造的或者您是否尝试将this指针从SomeClass的ctor传递给thread-'B'?如果是的话,你肯定有麻烦w.r.t虚函数。但这与竞争条件毫无关系。

如果你在线程'''中访问全局实例变量而没有线程'''传递它,那么就有可能出现竞争条件。 “新”指令由大多数编译器构成,如....

pClass = // Step 3
operator new(sizeof(SomeClass)); // Step 1
new (pClass ) SomeClass; // Step 2

如果只有Step-1完成,或者只完成了Step-1和Step-2,那么访问pClass是未定义的。

HTH

答案 2 :(得分:0)

答案 3 :(得分:0)

在没有同步的情况下,你认为vtable上可能存在争用条件,因为线程A中的构造函数对内存的写入可能对线程B不可见。

但是,用于线程间通信的队列通常包含同步以准确解决此问题。因此,我希望getMonitorFromSharedQueuepassMonitorToSharedQueue引用的队列能够处理这个问题。如果他们不这样做,那么您可能会考虑使用替代队列实现,例如我在博客上写的那个:

http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html