说说上古时代的主线程模式

说说上古时代的主线程模式

作者:BlogUpdater |  时间:2021-03-25 |  浏览:71 |  评论已关闭 条评论

史上(可能)让你最疑惑的词:marshal
在COM世界,曾经有着一个颇为神秘的东西:主线程模型(main threading model)。
它主要用在显式COM线程模型还没有发明的时期,可以说,主线程模型是多线程正式来临之前的那一段时期的特殊产物。

进程的第一个线程会初始化COM库并被称之为”主”线程。(可能它是在套件模型中第一个初始化COM库的线程,我不太记得了。) 当一个主线程对象被创建后,COM将创建调用列集(marshal)到主线程,然后创建对象,然后将执行结果列集回创建者线程。类似的,当你调用COM对象的方法时,调用会被列集到主线程,然后主线程执行调用,最后,执行结果会被列集回调用方。

换句话说,一个主线程对象就有点像套件线程对象,
换句话说,一个“主”线程对象就像一个套间线程对象,另外一个约束是,唯一可以使用它的套间就是“主”线程所属的套间。

可以想象,在任何多线程应用程序中,这都是可怕的性能损失,因为要进行大量的列集操作。更糟糕的是,它完全阻塞了主线程,因为现在必须在该线程上服务所有这些对象,而没有其他线程。

更糟糕的是,所有这些列集工作为重新进入创造了新的机会。在等待主线程执行其操作时,调用线程可能会处理消息,这意味着你可能会意外地收到窗口消息。

那么,这个可怕的线程模型存在的意义是什么呢?

为了向后兼容向COM添加多线程支持之前编写的COM对象。那时,只有一个线程,因此COM对象的同步可能非常懒惰。实际上,它们不需要任何东西!如果只有一个线程,那么你肯定不需要与其他线程协调操作,因为没有线程。

这就是为什么“主”线程模型是默认的原因。将多线程支持添加到COM时,发明了线程模型。在此之前,没有线程,因此也没有线程模型。因此,所有旧对象均未在其注册中指定线程模型。

首先,你甚至应该了解这种古老的线程模型的唯一原因是,如果你忘记在对象注册中指定线程模型,则默认情况下将获得可怕的“主”线程模型。

然后你会想知道为什么应用程序的性能如此糟糕,为什么还要遇到所有这些奇怪的重新进入问题。

总结
都过去了,全新的,现代化的COM线程模型已经来了。
但是,我还是不太懂这其中的工作原理,太深奥。
还是API实在。

最后
Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一,里面有很多关于Windows的小知识,对于广大Windows平台开发者来说,确实十分有帮助。
本文来自:《The dreaded “main” threading model》

评论已关闭。