这个模型是在原有的[封装IOCP]一文基础上,使用[基于C++的事件机制设计[2.0]]的事件机制进行了修改,替代了原有的虚函数方法。闲言少叙,请看代码。
/// 自定使用默认线程的IOCP typedef TIOCPService<> TMyIOCP; .
可以看到,现在的模型使用更简单。问题是,既然是事件,有什么事件?怎么处理事件?
事件原型定义如下:
/** * @class TIOCPThread * @brief IOCP线程对象 * @note 对_beginthreadex的包装 */ template <class __TDataUnit = TPack<int> > class TIOCPThread : public TObject { public: typedef __TDataUnit dataUnitType; //< 数据单元对象类型定义 typedef TIOCPThread<__TDataUnit> type; //< 处理线程类型定义 typedef TIOCPHandle<__TDataUnit> handleType; //< IOCP句柄类型定义 /** * @brief 初始化事件 * @param [in] type* 当前线程对象指针 */ typedef TEvent<void, type*> TOnInitialize; /** * @brief 销毁事件 * @param [in] type* 当前线程对象指针 */ typedef TEvent<void, type*> TOnUninitialize; /** * @brief 数据预处理事件 * @param [in] type* 线程对象 * @param [in] dataUnitType* 待处理的数据单元 * @return bool 返回结果 * - true : 数据预处理成功 * - false : 数据预处理失败 */ typedef TEvent<bool, type*, dataUnitType*> TOnBeforeProcess; /** * @brief 数据处理后事件 * @param [in] type* 线程对象 * @param [in] dataUnitType* 已经处理的数据单元 */ typedef TEvent<void, type*, dataUnitType*> TOnAfterProcess; /** * @brief 数据处理事件 * @param [in] type* 线程对象 * @param [in] dataUnitType* 待处理的数据单元 */ typedef TEvent<void, type*, dataUnitType*> TOnProcess; /// 以下省略若干字
有了原型定义,现在看看怎么处理这些事件:
/** * @class TDummy * @brief 我的对象,该对象响应创建IOCP事件并处理数据 */ class TDummy : public TObject { public: /// 已处理的工作单元计数 TLockVar<int> TotalProcessed; /// 某个处理线程的统计数据 hash_map<DWORD, TLockVar<unsigned int> > ThreadProcessedHash; public: /** * @brief 初始化事件 */ void onInitialize(TMyIOCP::threadType* thd) { cout<<"初始化线程"<<thd->getId()<<endl; ThreadProcessedHash.insert(make_pair<DWORD, TLockVar<unsigned int> >(thd->getId(), 0)); } /** * @brief 清理事件 */ void onUninitialize(TMyIOCP::threadType* thd) { cout<<"清理线程"<<thd->getId()<<endl; } /** * @brief 创建IOCP处理线程事件处理 */ /* TMyIOCP::threadType* onCreateIOCPThread(TMyIOCP::handleType* handle) { TMyIOCPThread* thd = new TMyIOCPThread(handle); if (thd) { ThreadProcessedHash.insert(make_pair<DWORD, TLockVar<unsigned int> >(thd->getId(), 0)); cout<<"创建线程 id="<<thd->getId()<<endl; } else cout<<"创建线程失败"<<endl; return thd; } */ /** * @brief 调节线程事件处理 */ void onAdjustThread(int val) { if (val > 0) cout<<"增加了"<<val<<"线程"<<endl; else cout<<"减少了"<<-val<<"线程"<<endl; } /** * @brief 数据预处理事件 */ bool onBeforeProcess(TMyIOCP::threadType* sender, TMyIOCP::dataUnitType* data) { return true; } /** * @brief 在数据处理后的事件 */ void onAfterProcess(TMyIOCP::threadType* sender, TMyIOCP::dataUnitType* data) { // 想不出该做什么 } void onProcess(TMyIOCP::threadType* sender, TMyIOCP::dataUnitType* data) { // 数据。。。。管数据去死,只是示例好不好。。 TotalProcessed++; // 统计处理数据,这里简单进行数据累加,注意,这种统计方式会产生锁竞争 // 对当前线程处理的次数进行统计 hash_map<DWORD, TLockVar<unsigned int> >::iterator it = ThreadProcessedHash.find(sender->getId()); if (it != ThreadProcessedHash.end()) { (*it).second++; } } };
OK,事件处理已经做好了,现在要做的是让IOCP运行起来。
int _tmain(int argc, _TCHAR* argv[]) { TMyIOCP myiocp; TDummy dummy; // 设置事件句柄 // IOCP线程创建事件,这里不响应 //myiocp.setOnCreateIOCPThread(EVENT(TMyIOCP::TOnCreateIOCPThread, TDummy, &dummy, onCreateIOCPThread)); // 其它事件 myiocp.setOnAdjustThread(EVENT(TMyIOCP::TOnAdjustThread, TDummy, &dummy, onAdjustThread)); myiocp.setOnInitialize(EVENT(TMyIOCP::TOnInitialize, TDummy, &dummy, onInitialize)); myiocp.setOnUninitialize(EVENT(TMyIOCP::TOnUninitialize, TDummy, &dummy, onUninitialize)); myiocp.setOnBeforeProcess(EVENT(TMyIOCP::TOnBeforeProcess, TDummy, &dummy, onBeforeProcess)); myiocp.setOnAfterProcess(EVENT(TMyIOCP::TOnAfterProcess, TDummy, &dummy, onAfterProcess)); myiocp.setOnProcess(EVENT(TMyIOCP::TOnProcess, TDummy, &dummy, onProcess)); myiocp.setAutoAdjustThread(true); // 使用自动调节线程 myiocp.begin(); // 启动IOCP int n = 0; while(!_kbhit()) // 无按键事件,则不停产生数据 { TPack<int> pack; // 数据 for(int i = 0; i < 16; i++ ) // 产生16个数据 { pack = TPack<int>(i); myiocp.input(&pack); // 投递 } // 循环200次后,打印信息 if (++n > 199) { n = 0; cout<<"现有"<<myiocp.getNumOfThreadsInPool()<<"个线程"<<endl; cout<<"投递了"<<myiocp.getPostedWorkUnitCount()<<"单元"<<endl; cout<<"投递失败了"<<myiocp.getPostFailedWorkUnitCount()<<"次"<<endl; // 有多少被处理了? cout<<"处理了"<<dummy.TotalProcessed<<"次"<<endl; // 查询所有线程,每个处理了多少数据 hash_map<DWORD, TLockVar<unsigned int> >::iterator it = dummy.ThreadProcessedHash.begin(); for(; it != dummy.ThreadProcessedHash.end(); it++) { cout<<"/t线程["<<(*it).first<<"]处理了"<<(*it).second<<endl; } } ::Sleep(10); // 暂停一下 } myiocp.stop(); // 停止IOCP return 0; } .
是不是粉简单?
新的IOCP线程模型源代码可以从这里下载[http://download.csdn.net/source/992129],如果不能下载,请来信索取[email protected]。
此乃末技。懒鱼充水而已。