在我使用ATL的免费线程进程内COM对象中,我想添加一个仅在FinalConstruct()
中设置的成员变量,并且只能在FinalRelease()
中只读。没有其他代码会操纵该成员变量。FinalConstruct()/ FinalRelease()中需要同步吗?
我怀疑当访问该成员变量时是否需要同步。我仔细阅读ATL源代码,看起来像那些方法总是被调用不超过一次,因此只能从一个线程中调用。
这是正确的假设吗?我可以省略同步吗?
在我使用ATL的免费线程进程内COM对象中,我想添加一个仅在FinalConstruct()
中设置的成员变量,并且只能在FinalRelease()
中只读。没有其他代码会操纵该成员变量。FinalConstruct()/ FinalRelease()中需要同步吗?
我怀疑当访问该成员变量时是否需要同步。我仔细阅读ATL源代码,看起来像那些方法总是被调用不超过一次,因此只能从一个线程中调用。
这是正确的假设吗?我可以省略同步吗?
是的,这个假设是正确的。可以把它看作C++构造函数和析构函数的扩展。从理论上讲,你可以从另一个线程调用一个COM对象的方法,而FinalRelease()
正在执行。虽然这是未定义的行为,而不是预期的发生。你不应该试图保护自己,就像你不会试图保护自己免受析构函数中的其他线程一样。如果你必须在析构函数中保护自己,那么设计通常会被破坏(这将表明你的线程之间没有适当的终止协议)。
可以从另一个线程调用FinalRelease()
的唯一方法是客户端代码没有对象的有效引用计数,或者代码的某些其他部分释放两次。这是一个严重错误,并且可能最终会在崩溃中崩溃,与您可能遇到的任何同步错误完全无关。用于管理对象引用计数的ATL代码是线程安全的,不会打开任何争用条件。
至于FinalConstruct()
,在FinalConstruct()
已成功返回代码之前,该对象的引用不会返回给任何客户端。