2011-08-01 47 views
1

在我使用ATL的免费线程进程内COM对象中,我想添加一个仅在FinalConstruct()中设置的成员变量,并且只能在FinalRelease()中只读。没有其他代码会操纵该成员变量。FinalConstruct()/ FinalRelease()中需要同步吗?

我怀疑当访问该成员变量时是否需要同步。我仔细阅读ATL源代码,看起来像那些方法总是被调用不超过一次,因此只能从一个线程中调用。

这是正确的假设吗?我可以省略同步吗?

回答

3

是的,这个假设是正确的。可以把它看作C++构造函数和析构函数的扩展。从理论上讲,你可以从另一个线程调用一个COM对象的方法,而FinalRelease()正在执行。虽然这是未定义的行为,而不是预期的发生。你不应该试图保护自己,就像你不会试图保护自己免受析构函数中的其他线程一样。如果你必须在析构函数中保护自己,那么设计通常会被破坏(这将表明你的线程之间没有适当的终止协议)。

可以从另一个线程调用FinalRelease()的唯一方法是客户端代码没有对象的有效引用计数,或者代码的某些其他部分释放两次。这是一个严重错误,并且可能最终会在崩溃中崩溃,与您可能遇到的任何同步错误完全无关。用于管理对象引用计数的ATL代码是线程安全的,不会打开任何争用条件。

至于FinalConstruct(),在FinalConstruct()已成功返回代码之前,该对象的引用不会返回给任何客户端。