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