《DCOM配置方法及DCOM并行计算程序的构建.docx》由会员分享,可在线阅读,更多相关《DCOM配置方法及DCOM并行计算程序的构建.docx(36页珍藏版)》请在三一办公上搜索。
1、感谢焦龙同学的耐心讲解1.如何搭建DCOM编程、运行环境N台机器的用户名和密码必须相同。最好是用Administrator进入VC+6.0,打开HelloDcom.dsw,组建工具栏调出来。程序全编译一遍Server -组建-全部组建组建 工具堡)窗口叫 帮助贯):;:=编i羊main, cpp Ctrl+F7蛆建Server, exe FTI癌嘉重建二批组建. .活除开始调试Q)远程连接调试程序.!执仃Server, exe Ctrl+F5移除工程配置俱).配置. . 配置文件.组建|PSAddSub jJ|Win32 Debug三|奏断后! Ml明PSAddSub - 工具- Regist
2、er Control工具(!)窗口也)帮助源浏览器也). Alt+F12关闭源浏览器文件()Regi ster CuntrolError LookupActiveX Curitrol Test ContainerOLE/COM Object Vi ewerMFC Tr ac er定制.选项Q).代宏.记录宏操作Ctrl+Shift+R播放宏操作Ctrl+Shift+PJJlReeDllVi ev-|n| x|文件 编辑遂)查看但)选项巾 帮助也)LWINIIlTiVS sys t em3 Lwmn巳 tm gr. illl5002010-12-201132WIND0WSSystem32jscr
3、ipt, dll4002010-12-211304WINDOWSsys t em32vb s cr i p t. dll4002010-12-211304WIND0WSSyStem32mSxml6. dll11002010-12-211304WINDOWSSystem32msxml3. dll37002010-12-211304WIND0WSsystem32ACTXFEXY.DLL1002010-12-212227Hell oD c om S er ver D ebugS er ver. exe1002010-12-212228i.Frogi_:diri FilesTerLcenti.QQin
4、lappcqe. dll4002010-12-212231立涕udFSMdSub. dll /* 1002010-12-212236类别识别项名称|_程序标识符控制嚓9089C2A8-2E18-4BB2-BB59-F9E15CBFC.WebDetect ClassFeti on. WebllHt ect. 1不确1052巳注册文件,巳选定1个NirSaft Freeware, 至此配置完成看两台机器是否可以进行DCOM访问:网上邻居:看访问125.223.8.122是否成功,进入工作组,输入如下: or kgr Dup-! x|文件编辑电)查看(V)收藏(A)工具(T)帮助d)0 O 后退前进
5、向上搜索文件夹查看地址W125.223.8. 122|转到网貉任务LauIlu:rL (Ce0e9468a74c4dg)添加一个网上邻居查看网洛连接设置家庭或小型办恣 网洛为家庭或小型办公室 设置无魏网洛查看工作组计耸机显示联网的UFnP设 备的图标出现如下就证明可以进行通信了。打.印机瓣真I阁工作区,HelloDcom,: 4 + 穿 Client files-Bl ClientWin32 files-_J Source Filesttincludettincludettincludettinclude ./Seruer/Simain.ciClient刁Win32 DehugServer_i
6、.c-_J Header Files司 Server.h_| Resource Files+ _| External Depende+ jp PSAddSub files+ Server filesCString * iszHostName=neu CString(125.223.8.113);/ char *p52Ho砒Name=”125.223.8.77”;/pszHostName=;HRESULThResult;/ Prepare COM For usehResult = CoInitialize(NULL)iF (FfllLED(IResult) 本机IP = 125.223.8.11
7、3。测试的时候这里添加自己的IP号就行。如果想连接对方(125.223.8.122),就填对方的IP号 即可。这只是一个例子,测试程序而已。以后讲到的IP访问将不是这个样子。运行 HelloDcoa icrosoft Vi3区文件(X)编辑3)查看世)插/Q d1,| (All clEM2.如何新建立一个DCOM工程。Parallel Mesh Search=PMS,原地盖高楼。之前那些事对于例子程序的调通,下面是如何新建立一个DCOM工程。DCOM工程大概分为3个子工程:Server端、代理DLL、Client端。这3部分分别要建立3个工程。2.1建立Server端先建立一个空白的工作区l
8、crosoft i sual C+新建更). Ctrl+N文件 编辑但)查看 插入(X) 屯歹打开但). Ctrl+0关闭打开工作空间也). . =:il2d毒工作区网疝COM;矿工星再新建Server端工程PMS组件接口函数的定义: 不可 Fljdzd 1 D:FMS_DCOMPMSPMS. idlhelpstring(IPMSCom Interface), pointer_default(unique)屈工作区PMS-DCOM: 1 re -Bl PMS files-_J Source FilesPMS.cppinterface IPMSCom : lUnknounPMS.idlPMS.r
9、cPMSCom.cppHRESULT Para_MeshSearch( in long length,in,size_is(length) long* raw_Array,out,size_is(length) long* back_Array );interface IPMSCom : lUnknoun HRESULT Para_MeshSearch( in long length,in,size_is(length) long* raw_firray, out,size_is(length) long* back_firray );组件接口函数的声明I 由 StdAfx.cpp -_J H
10、eader Files|国司 Resource.hPMSCom.h在 public:里面加入一句话 STDMETHOD(Para_MeshSearch)( long length, long* raw_Array, long* back_Array);事翎 Header Files隹Resource.h:冒 StdAfx.hPMSCom.h组件接口函数的实现厂兰J I-IY1O.IUI豳 PMS.rcPMSCom.ci画 StdAfx.cpp向此文件中添加:/ IPMSCompublic:STDMETHOD(ParaMeshSearch)( long length, long* rawfirr
11、ay, long* backfirray);/ CPMSComSTDMETHODIMP CPMSCom:Para_MeshSearch(long length, long* rawArray, long* outArray)函数功能return NOERROR;注意,在编写PMSCom.cpp也就是Server端代码的时候,接口函数中数组rawArray是一个long*类型,在接口函数中 不用重新给这个rawArray分配空间。因为调用这个函数的时候实参是一个具体数组。蓟 PMS.idl务 PMS.rc幻 StdAfx.cppPMSCom.ciSTDMETHODIMP CPMSCom:Para
12、MeshSearchflong length, long* rawArray, long* backArrai)函数功能return NOERROR;Header Files组件注册:一般地,编译完成服务器自动注册-5P PMS files-_J Source Files 直PMS.cpp 国 PMS.idl 直 PMS.rc.君1 StriAfx.nnnPMSCom.c选中PMSCom.cpp,再编译!三咬圜断后!即妙三J R t奏(g)嘉! Hi妙j CPQSCom;(All class members . Para QuickSortj CPQSCom;(All class member
13、s . Para QuickSortSeruer registration done*PMS.exe - Q error(s), 0 uarning(s)H组建调试X在文件i中查找X在文件2.2建立代理/存根DLL这2.2节都是在PSPMS工程中的操作。再新建一个工程PSPMS向PSPMS.def中添加如下内容:LIBRARYEXPORTSDllGetClassObjectPRIVATEDllCanUnloadNowPRIVATEDllRegisterServerPRIVATEDllUnregisterServerPRIVATEGetProxyDllInfoPRIVATE把PMS.idl生成的
14、如下4个文件加入到工程中。方法如下:-Bl PSPMS files司 PSPMS.d_| Header File*_| Resource FiSource File国新建文件夹电).添加文件到目录1 5 Clasd 1 Resou 囹属性敏)-Bl PSPMS files-_J Source Files :? dlldata.c 直PMSJ.c 直PMS_p.c 司 PSPMS.defHeader FileResource Fil 口新建文件夹费添加文件到目录史).FMS.hS P PSPMS files插入文件到工程查找范围d):电正31卜囱普囹二 ClassV 墨| Resou一Debug
15、 |CJ dll data, c FMS. cpp回 PMS_p. cFMSC um. cpp 国 FMSCom.h 国 Re e Milt-1: e. hS t dkfx. cpp h StdAfx. h文件名页):|fms. h文件类型(T) : J C+ Filesi:; .:pp;. i:kk ;. t+i;. h;. tlh; Files will be inserted into folder titled Header Files1 in project在如下位置加入,REGISTER_PROXY_DLL, _WIN32_DCOM在如下位置加入 rpcndr.lib rpcns4
16、.lib rpcrt4.lib 记得rpcndr.lib前面加个空格Project Settings设置O: Win32 Debug团 PMS.idl固 PMS.rc 固 PMSCom.cpp 由 StdAfx.cppHeader Files 司 PMSCom.h _e Resource.h 司 StdAfx.hResource Files分类:常规I调试I C/C+资源I MIDL |诃国7TT输出文件名: pebug/PSPMS.dll对象淮模块:|l.lib odbc32.lib odbccp32.lit刷粉IB) Icndr.lib rpcnsl.lib rpcrt4.lib曲JnJi
17、司dlldata.cPSPMSource FilesPMSJ.cPMSp.c PSPMS.def向产生调试信息际唐加链接V允许配置文件V忽略全部默认库r产生map文件 v产品.仓库_j Header Files司 PMS.h_| Resource Fileskernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcndr.lib取消嘛定-Bl PSPMS files-
18、_J Source Files 画 dlldata.c 曲 PMSJ.cPMS-CPSPMS.def编译,连接j(Globals | All global members T |(No members - Create New Class. T |j(Globals) All global member* (No members - Create New Class.注册dll:Configuration: PSPMSPSPMS.dll - 0 error(s), 0 uarninq(s)工具(!)窗口也)帮助源浏览器也).关闭源浏览器文件(Z)狼更biF Win32 DebugA产e Err
19、or Looloipster Cuntrol2.3建立客户程序新建一个工程PMS_Client.cpp中的#include stdafx.h删了它就可以了。否则有出不尽的编译、链接错误。 客户端PMS_Client工程必须包含PMS.h和PMS_i.c文件。方法上面都说过了。插入文件到工程查找范围a):一DebugU dll data, cc FMS_i. c文件类型(T):文件名:Files will be inserted into folder titled Header Files in project-PMS_Client files-_j Source Files旬 PMS_Cli
20、ent.cpp宣=一:? StdAfx.cpp-_J Header Files司司 StdAbc.hPMS i.cPMS.h注意:在客户端,无论编写 debug 还是 release 程序,projectsetting c/c+ 中的 code generation 下的 Use run-time library 应选 DEBUG Multithreaded DLL。下图所示:3.代码填充3.1 PMS_Client.cpp 的框架可能用到的头文件#include #include #include #include #include #include /服务器的最大个数#include ./
21、PMS/PMS.h这个一定用得上#defne MAXJSERVERJNUM 20 using namespace std;struct PMS_Rangelong *Trans_Array;long *Back_Array;long length;int pid;;定义struct PMS_Range,这个东东任务分配用的。变量一般要定义为结构体数组,目的是传给好几个处理机,每一个结 构体数组元素就是一个处理机的任务。添加到多线程调用的参数中,跟多线程一起传到处理机那边。struct PQS_Timetime_t start;time_t end;PQS_Time ptime;处理机共同的时间
22、,总体的时间全局变量:int ser_num;/用户设定服务器个数long element_num;/数据量,数量级,保证很大的HANDLE PMS_ThreadMMAX_SERVER_NUM; /客户端线程,保证每个线程对应一个服务器char ProcessorMAX_SERVER_NUM15;/服务器 IP 地址PMS_Range rangeMAX_SERVER_NUM;/任务划分范围从servername.txt中读取IP地址列表。文件里面每一行是一个IP地址。void ReadProcessorList()int i;ifstream infile(servername.txt, io
23、s:in);for(i=0;iProcessori;infile.close();多线程运行函数。一个线程运行一个这样的run函数。DWORD WINAPI run(LPVOID pRange)PMS_Range* myrange = (PMS_Range*)pRange;/通信部分return 0;ptime.start=GetTickCount();开始计算时间ptime.end=GetTickCount();/停止计算时间printf(n 本次运算使用了切台处理机,运行时间为:dmsn, ser_num, ptime.end-ptime.stE);t3.2通信部分红色的字为个性化信息,表
24、示使用模板后需要根据自己工程的命名、函数调用改动的地方 绿色的字,你懂的,不解释。HRESULT hResult;hResult = CoInitialize(NULL); 初始化 COM 库 if (FAILED(hResult) return 0;IClassFactory *pClf;IUnknown *pIUnknown;wchar_t ip42;放弃使用 CString 类型,用 wchar_t 好int len = strlen(Processormyrange-pid);mbstowcs(ip, Processormyrange-pid, len);转换单字符串为宽字符串iple
25、n = 0 ;设置字符串结尾COSERVERINFO ServerInfo = 0, ip, NULL, 0 ;获取服务器信息hResult=CoGetClassObject(CLSID_PMSCom,CLSCTX_SERVER, &ServerInfo, IID_IClassFactory, (void*)&pClf);创建类厂printf(n 线程d 正在连接服务器%s,myrange-pid,Processormyrange-pid); if (FAILED(hResult)printf(n 连接服务器s 失败,Processormyrange-pid);return 0;hResult
26、 = pClf-CreateInstance( NULL,IID_IUnknown,(void*) &pIUnknown);创建组件对象if (FAILED(hResult) printf(n 创建组件对象失败%d”,myrange-pid);pClf-Release();return 0;pClf-Release(); 释放类厂IPMSCom *pI MeshSearch;hResult = pIUnknown-QueryInterface(IID_IPMSCom, (void*) &pIMeshSearch);/ 查询接口if (FAILED(hResult)pIUnknown-Relea
27、se();return 0;调用接口函数pIMeshSearch-Para_MeshSearch( myrange-length,myrange-Trans_Array,myrange-Back_Array );pIMeshSearch-Release();pIUnknown-Release();pIUnknown = NULL;CoUninitialize();释放 COM 库printf(n 线程%d结束.”,myrange-pid);3.3多线程在做并行计算的时候,需要几台处理机同时完成多个任务,这时,Client程序要建立N个线程,这N个线程将与N个 处理机进行通信,将划分好的任务传给
28、它们。每一个线程,都执行DWORD WINAPI run(LPVOID pRange)函数,在这 个函数里面建立与处理机的链接,并且调用远程处理机上的接口函数,将任务传过去。等远程处理机做好以后,从out 参数又传回数据。最后,Client将N个线程的传回数据加以处理。全局变量HANDLE PMS_ThreadMMAX_SERVER_NUM;/客户端线程,保证每个线程对应一个服务器线程函数DWORD WINAPI run(LPVOID pRange) . .这个函数里面写通信的部分,3.2节彩色的部分那段。主函数里面调用这段:/这里设置起始时间点,用于计算加速比for(i=0;iser_num
29、;i+)PMS_ThreadMi=CreateThread(0, 0, run, (LPVOID)&rangei, 0, NULL); 这里是建立线程/rangei是对应线程i的任务。将任务i分配给线程iunsigned long w1 = WaitForMultipleObjects(ser_num, PMS_ThreadM, TRUE, INFINITE);/监听,回收线程结束进程if ( w1 = WAIT_OBJECT_0 )for(i=0; isetting-link-input-Object/Library Modules,加入“mfcs42d.lib MSVCRTD.lib”,顺
30、序不能乱Linking. mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain12 already defined in dlldata.obj 的解决方法如下: 将_ USRDLL删掉出现如下错误:Linking.nafxcwd.lib(afxmem.obj) : error LNK2005: void * _cdecl operator new(unsigned int) (?2YAPAXIZ) already defined in LIBCD.lib(new.obj)nafxcwd.lib(afxmem.obj) : error LNK2
31、005: void _cdecl operator delete(void *) (?3YAXPAXZ) already defined inLIBCD.lib(dbgdel.obj)nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol _endthreadexnafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved external symbol _beginthreadexDebug/PQS.exe : fatal error LNK1120: 2 unr
32、esolved externals 执行link.exe时出错.Linking.nafxcwd.lib(afxmem.obj) : error LNK2005: void * _cdecl operator new(unsigned int) (?2YAPAXIZ) already defined in LIBCMTD.lib(new.obj)nafxcwd.lib(afxmem.obj) : error LNK2005: void _cdecl operator delete(void *) (?3YAXPAXZ) already defined inLIBCMTD.lib(dbgdel.o
33、bj)libcd.lib(crt0dat.obj) : error LNK2005: _cinit already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj) : error LNK2005: _exit already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj) : error LNK2005: _exit already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj) : erro
34、r LNK2005: _cexit already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj) : error LNK2005: _c_exit already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj) : error LNK2005: _C_Exit_Done already defined in LIBCMTD.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.li
35、b(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)libcd.lib(crt0dat.obj)
36、error LNK2005: _C_Termination_Done already defined in LIBCMTD.lib(crt0dat.obj)error LNK2005: _exitflag already defined in LIBCMTD.lib(crt0dat.obj)error LNK2005: _wpgmptr already defined in LIBCMTD.lib(crt0dat.obj)error LNK2005: _pgmptr already defined in LIBCMTD.lib(crt0dat.obj)error LNK2005:winitenv already defined in LIBCMTD.lib(crt0dat.obj)error LNK2005: _wenviron alre