Linux高级环境编程实验报告6_第1页
Linux高级环境编程实验报告6_第2页
Linux高级环境编程实验报告6_第3页
Linux高级环境编程实验报告6_第4页
Linux高级环境编程实验报告6_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

作业报告学生姓名:学号:指导教师:学生E-mail:一、作业名称:英文统计词频程序的实现二、作业要求以英文文章为例,利用执行体程序库实现一个多进程词频统计的程序。对于给定的多个目录,并发地统计每个目录下的所有文件(假设每个文件中只有英文字符)中单词出现的次数,并最终汇总出在给定目录下所有文件中单词出现次数,然后记录下来。该过程要求采用多线程协作方式。三、设计与实现1、设计思路首先分析程序设计的需求,要对多个目录下的文件进行词频统计,如果只用一个进程顺序的对各个目录下各个文件进行计算,会消耗很大时间,另外也无法充分发挥执行体程序库的优势。而且要求采用多线程协作方式,这样很自然的会想到创建一些进程去各个目录下进行统计,最后用一个进程统一管理这些进程,那么父进程和子进程的思想就出来了。这个过程中,我们是将一个任务划分成了多个任务并行地去执行,最后把这些子任务的执行结果汇总起来就是整个任务的结果,其实这就是Map-Reduce思想——把整个任务执行过程划分为映射(Map)和化简(Reduce)两个阶段。在词频统计程序设计中,这两个阶段具体工作划分如下:1、映射(Map)阶段:①.主进程根据输入的目录数量创建多个子进程,每个子进程处理一个目录;②.子进程获得目录名后,遍历整个目录,统计该目录下的每个文件的单词词频,作为中间结果保存。③.子进程统计结束后把中间结果发送给主进程。2、化简(Reduce)阶段:①.父进程接收子进程发送过来的中间结果,并进行汇总;②.子进程发送结束后父进程向其发送退出消息,子进程接收到后退出;③.父进程检查所有子进程是否全部退出,若是,则工作结束,父进程退出,否则父进程继续等待所有子进程结束。图3-1协议设计图3-1显示了主进程与子进程之间的消息协议,其消息通信流程也比较清楚。2、词频统计程序的实现代码清单3.2.1classCLFatherInitMsg:publicCLMessage{public: CLFatherInitMsg():CLMessage(FATHER_INIT_MESSAGE_ID){}public: stringdirname};消息由消息头部、消息标志ID和数据组成。代码清单3.2.1给出了CLFatherInitMsg的声明,该类继承了CLMessage类。其中包含一个string类型的dirname变量,用来存放消息中携带的目录名。此消息是由父进程发送给子进程的初始化消息,该目录名即为子进程要进行单词统计的目录名。代码清单3.2.2intmain(intargc,char**argv){…… try { if(!CLLibExecutiveInitializer::Initialize().IsSuccess()) { cout<<"Initializeerror"<<endl; return0; } CLFatherWordCountObserver*pFatherWordCountObserver=newCLFatherWordCountObserver; for(inti=1;i<argc;i++) pFatherWordCountObserver->PushDirname(argv[i]); pFatherWordCountObserver->Init(); CLNonThreadForMsgLoopfather_nonthread(pFatherWordCountObserver,"father_pipe",EXECUTIVE_BETWEEN_PROCESS_USE_PIPE_QUEUE); father_nonthread.RegisterDeserializer(CHILD_INIT_MESSAGE_ID,newCLChildInitMsgDeserializer);father_nonthread.RegisterDeserializer(CHILD_SEND_REQUEST_MESSAGE_ID,newCLChildSendRequestMsgDeserializer); father_nonthread.RegisterDeserializer(INTERMEDIATE_RESULT_MESSAGE_ID,newCLIntermediateResultMsgDeserializer); father_nonthread.RegisterDeserializer(CHILD_WORK_FINISH_MESSAGE_ID,newCLChildWorkFinishMsgDeserializer); father_nonthread.Run(0); throwCLStatus(0,0); } ……}代码清单3.2.2显示了主进程的main函数,描述了主进程的执行过程。首先实例化一个FatherWordCountObserver类的对象,并进行初始化操作。接着创建主进程的消息循环过程,该函数的传入参数分别是:FahterWordCountObserver类指针,消息循环过程的名称以及消息循环的方式。其中消息通信方式为进程间的管道通信。代码清单3.2.3intmain(intargc,char*argv[]){if(argc!=2) { cout<<"usage:./a.outchildname"<<endl; exit(-1); } try { if(!CLLibExecutiveInitializer::Initialize().IsSuccess()) { cout<<"Initializeerror"<<endl; return0; }CLNonThreadForMsgLoopchild_nonthread(newCLChildWordCountObserver(argv[1]),argv[1],EXECUTIVE_BETWEEN_PROCESS_USE_PIPE_QUEUE); child_nonthread.RegisterDeserializer(FATHER_INIT_MESSAGE_ID,newCLFatherInitMsgDeserializer);child_nonthread.RegisterDeserializer(FATHER_ACK_MESSAGE_ID,newCLFatherAckMsgDeserializer); child_nonthread.RegisterDeserializer(QUIT_MESSAGE_ID,newCLQuitMsgDeserializer); child_nonthread.Run(0); throwCLStatus(0,0); } catch(CLStatus&s) { if(!CLLibExecutiveInitializer::Destroy().IsSuccess()) cout<<"Destroyerror"<<endl; return0; }}代码清单3.2.3是子进程的main函数,描述了子进程的执行过程。分别将FATHER_INIT_MESSAGE_ID、FATHER_ACK_MESSAGE_ID、QUIT_MESSAGE_ID这三种消息ID的反序列化类注册到消息循环过程中。四、测试根据前面工作,利用执行体程序库实现了词频统计程序,下面我们先穿件两个待遍历的目录testdir_1和testdir_2,每个目录中都有两个文件(只有英文字符)。输入如图4-1所示的命令创建主线程,携带两个目录的目录名,此时主线程等待。图4-1创建主进程在另一个终端创建一个子进程ch1,此时主线程与子线程之间通信如图4-2所示:图4-2主进程与子进程ch1可以看出,此时主进程和子进程ch1已经完成通信流程,ch1收到退出消息,而主线程并未退出,因为需要一个子进程完成对另个目录的处理,所以在等待第二个进程的结束。创建子进程ch2,处理第二目录下文件的词频统计,此时主进程与该子进程的通信如图4-3所示。可以看到,子进程ch2完成操作后,主进程发出退出消息,子进程ch2接收退出消息后结束,同

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论