COM套间

com之套间 com之套间参考资料:《Essential COM》、《MSDN》 什么是套间    套间(Apartment),形象点,他就是一个用来装com对象的容器,一个套间内可以有多个Com对象,但是对于每个com对象在某一时刻只能够属于某一个套间。 套间用途和存在意义    假设你使用过Com。我们在一个线程A里创建了一个COM对象,那么在线程A里我们就可以访问该COM对象的 阅读详情
理解COM套间(第一部分) (2010-12-18 11:51:43)
套间通常用来描述一个带有支持COM对象的 消息队列的线程。(来自百度百科)
 

编写拙作《关于COM组件线程模型的实验》的过程中,发现自己无法合理解释特定情况下程序的运行情况。为更深入理解COM的线程模型,合理解释程序运行情况,找了一些资料看。发现一篇英文文章不错,特地翻译出来。关于对STA中对象的回调处理、其他套间中的线程对MTA中的对象的调用是通过RPC线程池里的线程进行的,以及不应该在自由线程和双线程模型的组件中使用线程局部存储这三点,是我在这篇文章中首次看到的,也是这篇文章比其他资料深入的地方,很值得学习和思考。

原文出处:http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm

COM引入了一种并发机制,可以截获并串行化对于设计为只能一次处理一个方法调用的对象的并发调用。这种机制以称为“套间(apartments)”的抽象边界概念为中心。在解决不能正确工作的COM系统的问题时,我发现大约40%问题的原因是缺乏对于套间的理解。这种知识的缺乏并不意外,因为套间是COM中最复杂的领域,而且也没有很好地文档化。微软的目的是好的,但是在Windows NT 3.51中为COM引入套间的时候,他们为粗心的开发者建立了一个雷区。遵守规则就可以避免踩到地雷,但是如果不知道规则是什么,就很难遵守规则。

本文是一个两部分系列文章的第一部分。系列文章将解释什么是套间、套间存在于什么地方,以及如何避免套间引入的问题。文章的第一部分将介绍COM基于套间的并发机制;第二部分将介绍一些规则,以避免隐藏而又令人讨厌的Bug。

1 套间基础

套间是一个并发边界,一个在对象和客户线程之间的假想的盒子,用以隔离具有不兼容线程特性的COM客户和COM对象。套间存在的主要目的是让COM可以串行化对于非线程安全对象的方法调用。如果没有告诉COM对象是线程安全的,则COM不会允许多个调用同时到达对象。相反地,如果告诉COM对象是线程安全的,则COM会让对象处理多个线程中的并发调用。

每个使用COM的线程,以及这些线程创建的每个对象,都被分配到某个套间中。套间不能跨越进程边界,所以如果对象和其客户位于不同的进程中,则它们也在不同的套间中。客户创建进程内对象的时候,COM必须决定将其放在创建者套间中,还是放在客户进程中的另一个套间里。如果COM将对象和创建对象的线程放在同一个套间中,则客户将直接访问对象。如果COM将对象放在另一个不同的套间中,则创建对象的线程对对象的调用将被列集(marshaled)。

图1展示了线程和对象共享套间,以及线程和对象位于不同套间时二者的关系。线程1中的调用将直接访问线程创建的对象;线程2中的调用将通过代理(proxy)和桩基(stub)进行。COM在将接口指针列集到线程2的套间时创建代理/桩基对。跨越套间边界传递接口指针时必须对指针进行列集,这是一条规则。这意味着,如果涉及到定制接口,即使是进程内对象,如果需要与位于其他套间中的客户通信,也还是需要提供与跨进程和跨机器方法调用时一样的,用于列集支持的代理/桩基DLL(或者选择类型库列集时的类型库)。

翻译:理解COM套间(第一部分)

图1:对其他套间中对象的调用被列集,即使对象和调用者属于同一个进程

Windows NT 4.0支持两种类型的套间,Windows 2000则支持三种类型。这三种类型的套间是:

l 单线程套间(Single-threaded apartments,STA)(Windows NT 4.0和Windows 2000)

l 多线程套间(Multithreaded apartments,MTA)(Windows NT 4.0和Windows 2000)

l 线程中立套间(Neutral-threaded apartments,NTA)(仅Windows 2000)

每个线程只能有一个单线程套间,但是可以容纳的对象个数是无限的。而且,COM不限制进程中STA的个数。进程中第一个创建的STA称为进程的主STA。对STA中对象的调用在投递前都先传递到STA线程中。因为所有对对象的调用都在同一个线程中执行,所以基于STA的对象不能同时执行多个调用。COM使用STA来串行化对于非线程安全对象的调用。如果不明确告诉COM对象是线程安全的,则COM将把对象放到STA中,从而让对象不会被并发访问。

关于STA操作的一个有趣方面是:COM如何将对基于STA的对象的调用传递到STA线程中。COM创建STA的时候,会同时创建一个隐藏窗口,这个窗口的窗口过程知道如何处理代表方法调用的私有消息。目标是STA的方法调用离开COM的RPC通道时,COM将向STA窗口投递一个代表这个调用的消息。STA中的线程收到消息后,将消息分发到隐藏窗口,隐藏窗口的窗口过程将调用投递给桩基,桩基将最终执行对对象的调用。因为线程一次只能接收、分发和处理一个消息,STA自然而有效地成为调用串行机制。如图2所示,如果同时发起n个对基于STA的对象的调用,则调用将被排队,然后依次投递给对象。

翻译:理解COM套间(第一部分)

图2:进入STA的调用被转化为消息,投递到消息队列。消息队列中的消息被STA中运行的线程依次转化回方法调用。

调用离开STA时的情形也同样重要。COM不能让线程阻塞在RPC通道中,因为回调可能导致死锁:想象一下当STA线程调用其他套间中的对象,而这个对象反过来调用STA中的另一个对象时会发生什么。如果STA线程阻塞在RPC通道中,则调用永远不会返回,因为唯一一个可以处理回调的线程正在RPC通道中等待最初的调用返回。因此,调用离开STA时,COM会阻塞STA线程,但是让STA线程仍然可以处理回调。为了让回调可以发生,COM会跟踪每个方法调用的因果关系,以便能够识别何时应该释放正在RPC通道中等待某方法调用返回的STA线程,让其处理另一个进入的调用。默认情况下,STA入口有调用到达时,如果STA线程正在等待出调用返回,而且到达的入调用与正在等待返回的出调用不属于同一个因果链,则到达的入调用将阻塞。编写消息过滤器可以改变这个默认行为,下一部分对此进行讨论。

多线程套间完全不同。COM限制每个进程只能有一个MTA,但是没有限制MTA中线程和对象的个数。MTA没有隐藏窗口和消息队列。对MTA中对象的调用被随机地传递给RPC线程池里的线程,不会串行化(见图3)。这意味着MTA中的对象最好是线程安全的,因为没有外部机制保证基于MTA的对象一次只接收一个调用,对象可能被不同的RPC线程并发地调用。

翻译:理解COM套间(第一部分)

图3:进入MTA的调用被传递到RPC线程而不会被串行化

对于离开MTA的调用,COM不会进行特别处理。调用线程可以阻塞在RPC通道中,如果发生回调,不会产生死锁,因为回调会被传递给另一个RPC线程。

Windows 2000引入了第三种套间类型:线程中立套间,即NTA。COM限制每个进程只能有一个NTA。不会给NTA分配线程;NTA仅用于容纳对象。对基于NTA的对象的调用不会引起线程切换,调用线程会进入NTA。也就是说,从STA或者MTA发起对同一个进程中NTA的调用时,调用线程会暂时离开其套间,直接执行NTA中的代码。这和基于STA和MTA的对象是不同的:其他套间对基于STA和MTA的对象的调用总是会导致线程切换的。在不同套间之间列集调用的时候,线程切换会占用大量开销。排除线程切换会改进性能,所以NTA是让跨套间方法调用执行更高效的优化。Windows 2000支持基于活动的外部同步机制,可以指定是否串行化对基于NTA的对象的调用。基于活动的串行化比基于消息的串行化更有效,它可以在对象到对象级别进行。

2如何为线程分配套间

以任何方式使用COM的线程必须首先调用CoInitialize或者CoInitializeEx初始化COM。调用这两个函数时,线程将被放入到套间中。放入到什么类型的套间决定于线程调用哪个函数以及如何调用。

l 如果线程调用CoInitialize,则COM创建新的STA并且将线程放入其中:

翻译:理解COM套间(第一部分)

l 如果线程调用CoInitializeEx并且传递参数COINIT_APARTMENTTHREADED,则线程也被放入到一个STA中:

翻译:理解COM套间(第一部分)

l 如果调用CoInitializeEx并且传递参数COINIT_MULTITHREADED,则线程被放入到进程里唯一的MTA中:

翻译:理解COM套间(第一部分)

从大的范围来看,进程的套间配置取决于进程中的线程如何调用CoInitialize[Ex]。存在不调用CoInitialize[Ex]函数而COM创建套间的情况,但是为了让问题简单,暂时不讨论这种情况(but for now we won't muddy the water by considering such circumstances)。

作为一个例子,假设启动了一个新进程,进程中的线程1调用CoInitialize:

翻译:理解COM套间(第一部分)

随后,线程1启动线程2,3,4和5,这些线程使用下列语句初始化COM:

翻译:理解COM套间(第一部分)

图4展示了最终的套间配置。线程1,2和5被分配到单独的STA中,因为每个STA中只能有一个线程。另一方面,线程3和4被分配到进程的MTA中。记住:COM不会为进程创建多个MTA,而是在唯一的一个MTA中放置任何数量的线程。

翻译:理解COM套间(第一部分)

图4:进程有五个线程,分布于三个STA和一个MTA中。

如果你喜欢刨根问底(if you're a nuts and bolts person),你可能好奇地想知道套间的物理性质,也就是COM如何在内部表示套间。创建新套间时,COM会在堆上分配套间对象,并且用套间ID、套间类型等重要信息进行初始化。为线程分配套间的时候,COM会在线程本地存储(TLS)中记录相应的套间对象的地址。因此,COM在线程中执行时,如果想知道线程是否属于某个套间,只需要在线程本地存储中查找套间对象的地址就可以了。

3 如何为进程内对象分配套间

现在该介绍如何为对象分配套间了。COM用于决定在哪个套间中创建对象的算法对于进程内对象和进程外对象是不同的。进程内对象更有趣,因为只有进程内对象是可以创建于创建者套间中的。我们首先讨论进程内对象,然后讨论进程外对象。

COM通过从注册表中读取对象的ThreadingModel值来决定在哪个套间中创建进程内对象。ThreadingModel是分配给用以标识对象DLL的InprocServer32子键的命名值。下面以REGEDIT格式显示的注册表条目标识了CLSID为99999999-0000-0000-0000-111111111111、DLL为MyServer.dll,ThreadingModel为Apartment的对象:

翻译:理解COM套间(第一部分)

Apartment是Windows NT 4.0支持的四种线程模型之一,也是Windows 2000支持的五种线程模型之一。五种线程模型以及支持线程模型的操作系统如下:

翻译:理解COM套间(第一部分)

Apartment Type列指示COM如何处理具有指定ThreadingModel值的对象。比如说,COM限制没有ThreadingModel值(ThreadingModel=None)的对象位于进程的主STA中;ThreadingModel=Apartment允许在任何STA(不仅仅是主STA)中创建对象;ThreadingModel=Free限制对象在MTA中;ThreadingModel=Neutral限制对象在NTA中;ThreadingModel=Both让COM可以在STA或者MTA中创建对象。

COM尽量放置进程内对象到创建者线程所属的套间中。比如说,如果STA线程创建标识为ThreadingModel=Apartment的对象,COM将在创建者线程的STA中创建对象。如果MTA线程创建ThreadingModel=Free的对象,COM将会把对象放置在MTA中。然而,有时候COM不能将对象放置在创建者的套间中。比如说,如果STA线程创建标识为ThreadingModel=Free的对象,则对象将在进程的MTA中创建,创建者线程将通过代理和桩基访问对象。类似地,如果MTA线程创建ThreadingModel=None或者ThreadingModel=Apartment的对象,则来自创建者线程的调用将从MTA列集到对象的STA中。下表显示了STA和MTA线程创建具有任何有效的ThreadingModel值(或者没有ThreadingModel值)的对象时的情况:

翻译:理解COM套间(第一部分)

为什么ThreadingModel=None限制对象在进程的主STA中?因为只有这样COM才能在不知道对象是否是线程安全时让多个对象安全地执行。假设从同一个DLL创建两个ThreadingModel=None的对象。如果这两个对象访问DLL中的任何全局变量,则COM必须在相同线程中执行所有对这两个对象的调用,否则两个对象可能试图同时读或者写同一个全局变量。限制对象在主STA中就是COM让对象在相同线程中执行的方式。

线程模型对于编码有重要的指导意义。比如说,标记为ThreadingModel=Free或者ThreadingModel=Both的对象必须是线程安全的,因为对基于MTA的对象的调用时不会被串行化。即使是ThreadingModel=Apartment的对象,也应该是部分线程安全的,因为ThreadingModel=Apartment不能阻止从同一个DLL创建多个对象,从而在共享数据上发生冲突。本文的下一部分将讨论这个问题。

4 如何为进程外对象分配套间

进程外对象没有ThreadingModel值,因为COM使用完全不同的算法为进程外对象分配套间。简而言之,COM将进程外对象放到与创建对象的服务器进程相同的套间中。大多数进程外(EXE)COM服务器以调用CoInitialize或者CoInitializeEx将主线程放入到STA中开始。然后服务器为其可以创建的对象类型创建类对象并使用CoRegisterClassObject进行注册。激活请求到达以这种方式初始化的服务器时,请求在进程的STA中被处理。结果,服务器进程创建的对象也在进程的STA中。

可以将进程外对象移动到MTA中,只要将注册类对象的线程放置在MTA中就可以了。这样进入的激活请求会到达在服务器进程的MTA中执行的RPC线程。为响应请求创建的对象也将位于MTA中。

要点是,在EXE类型的COM服务器里,调用CoRegisterClassObject的线程所在的套间,也是服务器创建的对象所在的套间。当然也存在例外:使用ATL的CComAutoThreadModule和CComClassFactoryAutoThread编写的EXE COM服务器将在服务器进程中创建多个STA,在其中均匀地分布对象。不过这只占现存的EXE COM服务器的很小一部分,可以认为是例外情况,而不是通常的规则。

继续下一部分

这就完了?本文展示的很多细节看起来很神秘,没什么实际价值。然而,要避免大多数常见的、折磨着COM程序员的危险陷阱,理解COM套间绝对是必要的。在下一部分你会明白我的意思的。

ROS1集群通信的可靠升级方案:为什么在无线环境下我选择了swarm_ros_bridge而非原生DDS 本文探讨了ROS1集群通信在无线环境下的可靠升级方案,重点分析了swarm_ros_bridge相较于原生DDS的优势。通过实际案例和性能对比,展示了ZeroMQ在无线通信中的稳定性和高效性,特别适合无人机编队和移动机器人集群等场景。 阅读详情

相关推荐

【机器学习】Anaconda安装后打不开jupyter notebook(网页不自动跳出)

anaconda安装成功以后,jupyter notebook可以出现打开的路径,能够手动复制粘贴地址路径打开,却不能自动跳转到网页。解决的办法是在配置文件中加入指定的浏览器配置信息。

weixin_43416960的博客 4万+

翻译:理解COM套间(第一部分)

最近在写一个 oledb provider,涉及到线程套间的问题,搜到下面的文章,感觉说的透彻,转了过来。 这个oledb provider是为了在asp.net程序中供ado.net使用,通过System.Threading.Thread.CurrentThread.Apar

hurtmanzc的专栏 1111

Windows本地部署Ollama+qwen本地大语言模型Web交互界面并实现公网访问

本文主要介绍如何在Windows系统快速部署Ollama开源大语言模型运行工具,并安装Open WebUI结合cpolar内网穿透软件,实现在公网环境也能访问你在本地内网搭建的大语言模型运行环境。近些年来随着ChatGPT的兴起,大语言模型 LLM(Large Language Model)也成为了人工智能AI领域的热门话题,很多大厂也都推出了自己的大语言模型,并或多或少的开源了自己的大语言模型,今天就来分享一个最近很火,且对于小白来说比较好上手本地部署的运行本地LLM的工具Ollama。

迪之的博客 1651

COM组件以及套间

COM组件的特点: 1. COM组件是以WIN32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行代码组成。 2. COM组件是遵循COM规范编写的   COM组件是一些小的二进制可执行文件 3. COM组件可以给应用程序、操作系统以及其他组件提供服务 4. 自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序 5. COM组件可以动态的插入或卸出应用 6. COM组件必须...

SpringDou的博客 1386

Dify平台+Excel批量分析实战:5分钟搞定大模型数据处理(附完整代码)

本文详细介绍了如何利用Dify平台的数据集功能,结合Excel和Python脚本,快速构建大模型批量数据处理流水线。通过实战案例演示,读者可在5分钟内完成客户反馈情感分析、产品文案生成等任务,实现从原始数据到结构化洞察的高效转化,极大提升工作效率。

3a9bq4r8t2y的博客 316

RK3399外设驱动之MIPI

RK3399外设驱动之MIPI 文章目录RK3399外设驱动之MIPIMIPI命令解析入口代码mipi显示配置实例rk3399mipi驱动rk mipi驱动注册过程rk32_mipi_dsi.c解析 内核版本 Linux4.4 平台 rk3399 作者 nineyole MIPI命令解析入口代码 MIPI的入口代码如下:kernel\drivers\video\rockchip\screen\lcd_mipi.c static int __init rk_mipi_screen_in

学无止境 2227

COM和套间(Apartments)

COM技术过时了吗?这句话也对也不对。从技术上讲,确实COM的使用率在下降,但是从思想上来说,COM的面向接口的思想正在被Java和.NET发扬光大。那我们还需要和COM打交道吗?这取决于你工作的领域。虽然现在微软的平台在慢慢向着.NET迁移,不过,在维护原有非托管代码,编写和Windows系统组件打交道的程序,以及使用CLR调用非托管代码的时候,COM或多或少都是不可避免的。与COM打交道就没法

kingofbird的专栏 1249

【华为OD技术面试真题 - 技术面】- C++面试题(1)

2024华为OD面试手撕代码真题目录以及八股文真题目录

算法大师! 3398

COM——套间

理解 COM 套间junguo下载源代码 简序   大学毕业前的最后一学期,在一家公司实习,当时的工作需要用到一些操作系统提供的组件。那时候只知道COM这个名词,并不知道到底是怎么回事,只知道上网到处找别人的源码解决自己的问题;那段日子到现在回忆起来都是灰色的,每天呆坐在电脑前,一个网站一个网站的查找自己需要的源码。但并不清楚自己到底在做什么;那时候对自己能不能成为一个程序员充满了怀疑。在实习

feijj2002_的专栏 2653

基于 ESP32-CAM 与 TinyML 的食堂餐盘自动识别与营养分析终端

【代码】基于 ESP32-CAM 与 TinyML 的食堂餐盘自动识别与营养分析终端。

weixin_42300449的博客 165

Modelsim:LPDDR5仿真(含美光仿真模型官方sv&vcs代码)

虽然,三星在设计跟量产上,早于其他家存储产商,但是镁光后来居上了,是业界首家支持全速 LPDDR5 的供应商,并且开发者在做开发的时候,也是用美光颗粒比较多,所以这里就先以美光的仿真模型为主进行仿真。 本工程为美光官方工程,支持Modelsim、VCS、ncverilog三种仿真器仿真。模型破解过,为完整system-verilog代码。

千歌叹尽执夏的博客 1280

COM原理之套间

1.    COM套间的由来 为了解决COM组件在多线程环境下临界资源的访问。 2.    COM套间的类型 1)    客户端程序创建的COM线程模型 a)     单线程套间(STA) 单线程套间可以保证,调用COM对象的方法被顺序执行,COM库所做的幕后工作是在我们调用CoInitializeEx(NULL,COINIT_APARTMENTTHREADED)的时候,会生成一个隐藏窗

xsh_123321的专栏 1825

Python实现将pdf,docx,xls,doc,wps,zip,xlsx,ofd链接下载并将文件保存到本地

本文是该专栏的第31篇,后面会持续分享python的各种干货知识,值得关注。在工作上,尤其是在处理爬虫项目中,会遇到这样的需求。访问某个网页或者在采集某个页面的时候,正文部分含有docx,或pdf,或xls,或doc,或wps等链接。需要你使用python自动将页面上含有的这些信息链接下载并保存到指定文件夹。遇到这种情况需要怎么做呢?别担心,跟着笔者直接往下看正文的详细解决方法。(附完整代码)在有些网页的正文中,有时会有如下图中的doc链接。比如爬虫在采集正文数据的时候,像标题,正文内容,作者,发布时间等等

Python进阶专栏《爬虫实战进阶》,《Pyppeteer从入门到精通》原创作者 4145

理解 COM 套间

简序  Don Box 在《COM 本质论》中说,对接口,类对象和套间有了彻底的理解,那么使用COM,没有翻不过去的山头。如果你对C++有深入的理解,那么《COM本质论》中对接口和类对象的阐述很清晰,理解并不困难。但套间是一个比较抽象的概念,而书上对这部分只是理论的叙述,没有提供具体的例子,理解起来就更困难了。在此我把自己找到的一些例子和自己的理解总结以下,以期给初学者提供一些入门的方法。闲话

蜗牛档案室 2229

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

[转]COM套间

本文讲解COM提出的各个类型的线程模型,再说明COM运行时期库是如何实现它们的 线程模型是一种数学模型,专门针对多线程编程而提供的算法,但也仅是算法,不是实现。本文讲解COM提出的各个类型的线程模型,再说明COM运行时期库是如何实现它们的,就像说明Windows是如何实现线程这个数学模型的一样,最后指明一下跨套间调用和各种类型套间编写的要求以帮助理解。希望读者对于Windows操作系统的线程这个概

wjzhang_1983的专栏 768

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

翻译:理解COM套间(第二部分)

转自:http://blog.sina.com.cn/s/blog_56dee71a0100ntr9.html 英文原版:http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understand

hurtmanzc的专栏 997

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

关于COM套间的一点总结

一提起COM的线程调用,就不得不提套间。这里我稍微做一点

无忘无往 978

COM和套间(Apartments) 1 - 基本知识

OverviewCOM技术过时了吗?这句话也对也不对。从技术上讲,确实COM的使用率在下降,但是从思想上来说,COM的面向接口的思想正在被Java和.NET发扬光大。那我们还需要和COM打交道吗?这取决于你工作的领域。虽然现在微软的平台在慢慢向着.NET迁移,不过,在维护原有非托管代码,编写和Windows系统组件打交道的程序,以及使用CLR调用非托管代码的时候,COM或多或少都是不可避免的。

张羿的优快云专栏 6630
上一篇: IInternetProtocolRoot
下一篇: IInternetProtocol
hellochenlian
博客等级 码龄17年 629粉丝 295原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值