付剑珑 邓凯
摘 要:近年来电力系统的机房动力环境监控系统的应用范围不断扩展,系统规模迅速扩大,接入站点大量增加,对监控主站的软件硬件提出了更高的要求。介绍在监控主站升级改造中,运用的新一代网络通讯解决方案与策略,探讨ACE网络库及IOCP通讯模式在通讯软件中的应用。
关键词:ACE网络库 IOCP模式 动环监控系统
中图分类号:TM76 文献标识码:A 文章编号:1007-3973(2013)006-081-02
在电力系统大运行体系实施中,建设变电站及通信机房监控系统,在传统“四遥”的基础上,安装包含交直流电源子系统、遥视图像子系统、安防周界子系统、环境子系统、照明子系统等综合辅助监控系统,全面提升对变电站机房的“感知”, 减轻运行维护人员负担,提高电网运行可靠性成为一种必须。
在机房环境系统建设的初期,接入对象主要是电力局大楼的机房、500kV220kV高电压等级变电站机房。接入的站点数量较少,一般在10个以下,通讯对象也只有几十个。近几年,随着电力系统自动化程度不断提高,大量110kV及以下的变电站,都实现了无人值班,在变电站机房的自动化设备大量增加的同时,操作维护人员大量减少。另外,大量的社区或乡镇供电所实现网络接入,联网收费。大量的110kV及以下的变电站、社区或乡镇供电所都需要接入集中的机房监控系统,接入的站点数量和通讯对象几何倍数增加,很多地区供电局的机房监控系统接入站点需求量达到200个以上,通讯对象超过1000个。
通讯对象的几何倍数增加对动环监控系统的通讯服务器提出了极高的要求。是对现有服务器系统进行软件升级,还是投入巨资升级硬件、增加服务器数量?成为各电力局安排建设资金面临的重要问题。
机房监控系统的通信服务器的主要工作就是进行网络通讯。目前常用的网络通讯编程模型有以下几种:
(1)blocking I/O阻塞模式:与通讯对象网络连接时,在连接过程中一直等待,效率极低。只要有多个通讯对象就不能有效的工作了。
(2)nonblocking I/O非阻塞模式:与通讯对象网络连接时,在启动连接后,就可以进行其它工作,效率较高。但每个网络连接工作中仍需一到两个线程,因此连接数达到几十上百后,大量线程经常切换,效率大幅下降。
(3)Select模式(I/O multiplexing):一个线程可以管理64个网络连接。此模式在达到1000个以上的网络连接后,也会由于线程太多,效率大幅下降。
(4)signal driven I/O (SIGIO):只有UNIX系统支持。我们暂不考虑。
(5)asynchronous I/O模式(IOCP模式是其中一种):一个线程可以管理成千上万个网络连接。在多连接,大数据量下,可获得理想的CPU响应。此模式适应于网络服务器这类需要处理大量连接的应用。
图1是以上五种模型的比较。
图1 五种模型的比较
从图1可以看出,越往后,阻塞越少,理论上效率也是最优。
从机房环境系统的长远发展看,我们选取asynchronous I/O(IOCP)模式进行网络通讯编程。为提高系统建设进度,少走弯路,我们采取借鉴前人成功经验的方式,下载国内外程序员的开源代码库加以修改。
ACE自适配通信环境(Adaptive Communication Environment)是一种面向对象(OO)的工具包,它实现了通信软件的大量基本的设计模式。ACE的目标用户是在UNIX和Win32平台上开发 高性能通信服务和应用的开发者。ACE简化了使用进程间通信、事件多路分离、显式动态链接和并发的OO网络应用和服务的开发。
ACE是目前最具代表的开源网络通讯类软件库,授权是免费的,可以自由使用,它正在被用于大量商业项目中(包括国际知名的大公司:诺基亚、摩托罗拉等),以及许多学院和工业研究项目。ACE已被移植到多种操作系统平台上,包括Win32和大多数的UNIX/POSIX实现。此外,同时有C++和Java版本的ACE可用。
ACE库版本很多,更新升级比较快。我们根据机房环境监控系统的需要,选用的是基于VC2005的Windows平台版本,版本号为5.8.2,这个版本的库支持VC2005(VC8)、WinCE(VC2005)、VC2008(VC9),适用范围比较宽。
ACE 中的Proactor框架可以实现IOCP功能。Proactor很多文档翻译为前摄器。
Proactor使用了异步的I/O工厂类收发消息,read/write方法都是异步进行的,调用完成后立即返回给Proactor主框架,然后进行其它事件的处理。后台的程序负责收发消息,真正收到消息或者发送消息完成时才通知Proactor的事件处理器去进行处理。这种异步I/O机制使得Proactor的主线程更专注于我们业务逻辑的处理,而不会将时间浪费在对网络数据I/O的处理上。
我们应用ACE库,通过ACE_Proactor实现IOCP模式的实现方式如下:
1 创建服务处理器
Proactor框架中服务处理器均派生自ACE_Service_Handler,它和Reactor框架的事件处理器非常类似。当发生IO操作完成事件时,会触发相应的事件完成会调函数。
2 实现服务处理器IO操作
Proactor框架中所有的IO操作都由相应的异步操作类来完成,这些异步操作类都继承自ACE_Asynch_Operation。常用的有以下几种:
ACE_Asynch_Read_Stream, 提供从TCP/IP socket连接中进行异步读操作.
ACE_Asynch_Write_Stream, 提供从TCP/IP socket连接中进行异步写操作.
使用这些操作类的一般方式如下:
初始化
将相关的操作注册到服务处理器中,一般可通过调用其open方法实现。
发出IO操作
发出异步IO操作请求,该操作不会阻塞,具体的IO操作过程由操作系统异步完成。
IO操作完成回调处理
异步IO操作完成后,OS会触发服务处理器中的相应回调函数,可通过该函数的ACE_Asynch_Result参数获取相应的返回值。
3 使用连接器或接受器和远端进行连接
ACE为Proactor框架提供了两个工厂类来建立TCP/IP连接。
ACE_Asynch_Acceptor, 用于被动地建立连接
ACE_Asynch_Connector 用于主动地建立连接
当远端连接建立时,连接器或接受器便会创建相应的服务处理器,从而可以实现服务处理。
4 启动Proactor事件分发处理
启动事件分发处理只需如下调用:
while(true)
ACE_Proactor::instance ()->handle_events ();
ACE库(见图2)应用中需要特别注意内存泄漏问题,特别是与VC的MFC联合使用时。我们采用的是以下方式检测内存泄漏:
(1)将下列内容输入到文件
//use MFC library
#define ACE_HAS_MFC 1
//use standard C++ library
#define ACE_HAS_STANDARD_CPP_LIBRARY 1
//define this, the application must create the ACE_Object_Manager.
//The recommended way is to call
//the program, and call
#define ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER
#include "ace/config-win32.h"
(2)在CWinApp的派生类的构造函数或InitInstance()函数中加入ACE的初始化函数ACE::init(),在该派生类的析构函数中加入ACE的清理函数ACE::fini()。
(3)若运行时还检测到有内存泄漏,其输出信息如下:
Detected memory leaks!
Dumping objects ->
{148} normal block at 0x003EBD90, 6 bytes long.
Data: < > 00 00 00 00 00 00
{61} client block at 0x003E3298, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $003E3298, 64 bytes long
a CDynLinkLibrary object at $003E3298, 64 bytes long
Object dump complete.
这种现象一般是由于ACE库和应用程序的字符集不一致所造成的,ACE在VS2005项目选项中的字符集设置是“未设置”,可将其设成“使用Unicode字符集”(注:VS2005默认的字符集设置是“使用Unicode字符集”)
(4)几点说明:
1)ACE_DOESNT_INSTANTIATE_NONSTATIC_OBJECT_MANAGER
应用程序手动创建ACE_Object_Manager,推荐的方式是在程序开始时调用ACE::init(),在结束时调用ACE::fini()。
2)若在文件
#undef ACE_HAS_NONSTATIC_OBJECT_MANAGER
说明应用程序要使用静态的对象管理器,ACE会为其创建,应用程序无需手动加入。
3)在Win32平台,ACE默认使用非静态的对象管理器,这个对象会被分配在main()函数的stack里;因main()函数已经在MFC类库里定义, 故ACE不能使用默认的方法,可以按2)所说的使用静态的对象管理器,或者按前面所说的自己定义ACE的初始化函数。
采用IOCP模式与ACE库后,现有的机房环境监控系统主站设备不需要新增昂贵的高性能服务器进行大规模升级改造,可在现有硬件上通过软件升级,实现大量站点、大量通讯对象的接入。同时可节省大量的建设经费和人力物力投入。