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

下载本文档

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

文档简介

作 业 报 告学生姓名: 学 号: 指导教师:学生E-mail: 一、作业名称: 多队列线程池的应用二、作业要求设计并实现一个整数加法运算的线程池,其中能够接收三种线程:1、用户线程,向线程池(主控线程)提交加法运算请求;2、主控线程,接收用户线程提出的加法运算请求,并负载均衡地将请求下发到若干计算线程;3、若干计算进程,接收来自于主控线程转发的加法计算请求,完成加法计算,并将计算结果直接返回给用户线程。另外,这三种线程都应具有各自的消息队列,来完成加法计算请求的发送与转发,并返回计算结果。具体业务要求:1)、用户线程需同时向主控线程提出=1000个加法计算请求2)、用户线程需要验证是否收到了这些加法计算的结果三、设计与实现根据作业要求分析,需要设个三中线程,而且三种线程之间还要相互通信和协作,图3-1显示了它们之间的通信关系。用户线程向线程池中的主控线程发送消息,主控线程将消息负载均衡的分发给线程池中的若干计算线程。为了实现负载均衡分发,将所有的线程形成一个循环链表,设置一个指针,该指针总是指向刚被分发消息的下一个计算线程,则所有的线程获取消息的机会均等。计算线程计算完成后直接将消息计算结果返回给用户线程。设计实现的关键操作是线程池中主控线程分发线程,计算线程组成循环链表,完成消息计算,将消息结果返回给用户线程。图 3-1 三种线程间通信下面给出线程池,计算线程和主控线程的具体实现。代码清单 3.1-a 线程池的实现class CLMyCalculateThreadPro;CLThreadPool:CLThreadPool() /未指定线程数时默认构造的线程数为6 ThreadNumber = 6; MainThread = mainThread; ThreadCount = NULL; /计算线程队列,初始为空 CLThreadPool:CLThreadPool(int threadNumber) if (threadNumber = 0) threadNumber = 6; ThreadNumber = threadNumber; MainThread = mainThread; /主控线程的名字 ThreadCount = NULL;CLThreadPool:CLThreadPool() void CLThreadPool:InitThreadPool()/初始化线程池 /创建主控线程 CLThreadProxy proxyMain(new CLThreadMainProcessor(this), MainThread.c_str(), false); proxyMain.Run(0); for (int i = 1; i ThreadName = thread_ + s; thread-Next = ThreadCount; ThreadCount = thread; CLThreadProxy proxy(new CLMyMsgProcessor, (thread-ThreadName).c_str(), false); proxy.Run(0); CurrentThread = ThreadCount; void CLThreadPool:UninitThreadPool() /用户向主控线程发送消息的实体void CLThreadPool:PostMessageToMainThread(CLMessage *Msg) CLExecutiveNameServer:PostExecutiveMessage(MainThread.c_str(), Msg);代码清单3.1-a是线程池的具体实现,在构造函数中,设置线程池中计算线程的数目,默认情况下为6;设置线程循环队列指针初始为空等。在线程池的初始化函数CLThreadPool:InitThreadPool中创建主控线程和若干计算线程。用户调用PostMessageToMainThread函数向主控线程发送消息实体,参数是指向CLMessge类的对象。代码清单3.1-b 计算线程的实现CLMyCalculateThreadPro:CLMyCalculateThreadPro()CLMyCalculateThreadPro:CLMyCalculateThreadPro()/将加法消息和退出消息的执行注册到消息的回调函数中CLStatus CLMyCalculateThreadPro:Initialize(CLMessageLoopManager *pMessageLoop, void* pContext) pMessageLoop-Register(ADD_MSG, (CallBackForMessageLoop)(&CLMyCalculateThreadPro:Do_AddMsg);pMessageLoop-Register(QUIT_MSG, (CallBackForMessageLoop)(&CLMyCalculateThreadPro:Do_QuitMsg); return CLStatus(0, 0);CLStatus CLMyCalculateThreadPro:Do_AddMsg(CLMessage *pM)CLAddMessage *pAddMsg = (CLAddMessage *)pM;int result = pAddMsg-m_Op1 + pAddMsg-m_Op2; CLResultMessage *pResultMsg = new CLResultMessage(pAddMsg-m_Op1, pAddMsg-m_Op2, result); /将计算结果消息发送给用户线程 CLExecutiveNameServer:PostExecutiveMessage(user_thread, pResultMsg); return CLStatus(0, 0);CLStatus CLMyCalculateThreadPro:Do_QuitMsg(CLMessage *pM)return CLStatus(QUIT_MESSAGE_LOOP, 0);代码清单3.1-b是计算线程的具体实现,其中主要涉及到两个消息,加法消息和退出消息。在Initializeh函数中将加法消息和退出消息的执行注册到消息的回调函数中。另外还要调用PostExecutiveMessage函数将计算结果消息发送给用户。代码清单3.1-c 主控线程的实现CLMainThreadPro:CLMainThreadPro(CLThreadPool *threadPool) this-threadPool = threadPool;CLMainThreadPro:CLMainThreadPro()/主控线程的初始化函数,注册分发消息和退出消息的回调函数CLStatus CLMainThreadPro:Initialize(CLMessageLoopManager *pMessageLoop, void* pContext) pMessageLoop-Register(ADD_MSG, (CallBackForMessageLoop)(&CLMainThreadPro:Do_PostMsgToThreadPool); pMessageLoop-Register(QUIT_MSG, (CallBackForMessageLoop)(&CLMainThreadPro:Do_QuitMsg); return CLStatus(0, 0);/将消息分发给计算线程队列中的线程CLStatus CLMainThreadPro:Do_PostMsgToThreadPool(CLMessage *pM) CLAddMessage *p = (CLAddMessage *)pM; CLAddMessage *pp = new CLAddMessage(p-m_Op1, p-m_Op2);/将消息转发到当前计算线程 CLExecutiveNameServer:PostExecutiveMessage(threadPool-CurrentThread-ThreadName.c_str(), pp); /将当前计算线程的指针指向线程队列中的下一个计算线程 threadPool-CurrentThread = threadPool-CurrentThread-Next; if (threadPool-CurrentThread = NULL) threadPool-CurrentThread = threadPool-ThreadCount; return CLStatus(0, 0);CLStatus CLMainThreadPro:Do_QuitMsg(CLMessage *pM) CLThreadQueue *p = threadPool-ThreadCount;/退出线程池时,主控线程将“退出”消息发送给线程池中的每个计算线程 while (p != NULL) CLQuitMessage *q = new CLQuitMessage(); CLExecutiveNameServer:PostExecutiveMessage(p-ThreadName.c_str(), q); p = p-Next; return CLStatus(QUIT_MESSAGE_LOOP, 0);从代码清单3.1-c中可以看到,主控线程的初始化函数Initialize主要是注册分发消息和退出消息的回调函数。在Do_PostMsgToThreadPool函数和Do_QuitMsg函数中实现与计算进程的通信,分别发送加法消息和退出消息。四、测试前面已经创建好三种线程,并实现了它们各自的功能和相互之间的通信。下面我们创建一个线程池并初始化,再创建一个用户线程,同时制定线程池,启动用户线程,开始发送加法消息。代码清单 4.1-a 测试代码class CLUserThreadPro : public CLMessageObserverprivate: CLThreadPool *Pool;/用户线程绑定的线程池 int CommandCount;/发送的消息数目 int ReceviceResultCount;/接收的消息数目public:CLUserThreadPro(CLThreadPool *Pool)/用户线程构造函数,指定线程池 this-Pool = Pool; virtual CLUserThreadPro() /实现CLMessageObserver类的初始化函数,注册返回消息和退出消息的回调函数virtual CLStatus Initialize(CLMessageLoopManager *pMessageLoop, void* pContext) pMessageLoop-Register(RESULT_MSG, (CallBackForMessageLoop)(&CLUserThreadPro:Do_ResultMsg); pMessageLoop-Register(QUIT_MSG, (CallBackForMessageLoop)(&CLUserThreadPro:Do_QuitMsg); CommandCount = 1000; /发送的消息数目 ReceviceResultCount = 0; /返回的消息数目/向线程池中的主控线程发送消息 for (int i = 0; i PostMessageToMainThread(new CLAddMessage(23 + i, 64 + i); return CLStatus(0, 0); CLStatus Do_ResultMsg(CLMessage *pM) CLResultMessage *pResultMsg = (CLResultMessage *)pM;cout m_op1 + m_op2 = m_Result PostMessageToMainThread(new CLQuitMessage(); return CLStatus(QUIT_MESSAGE_LOOP, 0); return CLStatus(0, 0); CLStatus Do_QuitMsg(CLMessage *pM) return CLStatus(QUIT_MESSAGE_LOOP, 0); ;int main(int argc, char* argv) /创建线程池 CLThreadPool *Pool = new CLThreadPool(5); Pool-InitThreadPool(); /初始化线程池 /启动用户线程 CLNonThreadProxy proxy(new CLUserThreadPro(Pool), user_thread); proxy.Run(0); return 0;代码清单4.1-a是测试代码,首先定义一个

温馨提示

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

评论

0/150

提交评论