CMPI中的内存管理及在Open Pegasus 中的实现
线程内的其他 CMPI 对象,则可以通过 pthread_getspecific 调用来得到该线程的 CMPI_ThreadContext 的地址.基于此种机制,不同线程内 CMPI 对象被分别管理成为可能.
Pegasus 使用专门的类来封装每种 CIM 的对象,例如 CIMInstance 、 CIMDateTime 等,然后将这些对象再次封装为 CMPI_Object . CMPI_Object 的主要的成员就是一个指向被封装对象的指针 hdl 和一个与其对应的函数表.另外就是用以构造一个 CMPI_Object 双向队列的指针 prev 和 next. CMPI_ThreadContext 中维护着指向这个 CMPI_Object 双向队列头尾的指针 CIMfirst 和 CIMlast .在该线程内创建的所有的 CMPI 对象都被记录在该队列中.为了能够自动释放该队列中所有的 CMPI 对象, CMPI_ThreadContext 在析构函数中(参见代码清单1),依次调用该队列中的对象的 release 方法.
代码清单1:CMPI_ThreadContext 的析构函数 在上面代码中,所有的 CMPI_Object 对象都转换成 CMPIInstance 对象后,再调用的 release 成员方法.通常而言这是错误的做法,这些 CMPI 对象并不能确保都是 CMPIInstance 对象.上面代码之可以这么做,是 release 方法总是所有的 CMPI 对象的函数表中的第一个成员函数.因此可以将一个 CMPI 对象转换成为任何一种 CMPI 对象并调用其 release 方法而保证不出现任何问题. 那么一个 CMPI_Object 对象是如何自动的加入到这个双向队列中呢? CMPI_Object 为每一种 CIM 对象定义了相应版本的构造函数.在每个构造函数中, CMPI_Object 都得到和当前线程关联的 CMPI_ThreadContext 对象,然后将自身的 this 指针加入到其所管理的 CMPI_Object 双向队列中. 当显式调用一个 CMPI_Object 对象的 release 方法被时,该对象所指向的实际 CIM 对象会被删除,然后 release 方法会将该 CMPI_Object 的 this 指针从所属的双向队列中移出并删除.
在 Provider 的代码中使用多线程 对于无需使用多线程的 Provider 开发中, Pegasus 所提供的关于线程以及内存管理方面的支持已经极大简化了程序员的工作量.但是如果实际需要, Provider 内部依然要求使用多线程,在所启动的线程内部还需要使用 CMPI 所提供的服务,那么只需要遵守如下三个步骤. 在创建新的线程之前调用 CMPI 定义的 prepareAttachThread 方法.该方法的目的是复制当前线程的一些上下文信息并传递给新创建的线程.从而保证新的线程可以继承当前线程中的一些上下文信息. 在新的线程中,调用 CMPI 定义的 attchThread 方法.在 attachThread 方法中会 new 一个新的 CMPI_ThreadContext 对象,使其管理该进程内部所有的 CMPI 对象. 在新的线程退出前,调用 CMPI 定义的 detachThread 方法.新的线程中的 CMPI_ThreadContext 对象是在堆上创建的,无法自动析构.因此需要在线程退出之前使用 detachThread 方法显式的去析构 CMPI_ThreadContext 对象. 总结 本文阐述了 CMPI 规范中关于线程安全及可重入性和内存管理方面的要求,并分析了其在 Pegasus 中的具体实现,分析了其中使用的关键数据结构.上面的阐述可以帮助 Provider 的开发人员能够更加清晰的认识 CMPI 对象的生存周期,在多线程的环境下正确的使用 CMPI 提供的各种方法. |
|
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |