一种多线程传输模型结构

背景说明:

        开发一个目录传输工具,将目录下的文件传输到服务器上。支持多个目录同时传输。限制对文件的传输暂不支持多线程。

        目录传输需要进过如下流程,扫描目录形成传输队列,在服务器上创建目录结构,上传文件。流程为串行,文件传输目前也为串行,不支持一个目录下的多个文件同时传输,以及一个文件的多线程传输。

        用户可以随时暂停目录的传输,(在任何一个阶段)然后关闭传输程序。在重启程序需要能够恢复到原来传输位置继续传输。对于大文件(可以大于2G)的文件支持断点传输。

 

类设计的简易视图:

每个Task对应一个要传输的目录。Task有一个Thread负责完成所有的流程。Thread里面运行的是TransFlw的具体实现。如扫描流程,目录上传流程(目录UpFlw),文件上传流程。

        TransFlw可以串联形成一个工作流。TransThread不含有Task的指针,这样TransThreadTask解耦,便于后续将TransThread提出来形成线程池,进行统一管理。TransThread只负责循环执行TransFlw的工作。

do

{

        rc = ::WaitForMultipleObjects(2,m_multiHandls,FALSE,INFINITE);

        index = rc - WAIT_OBJECT_0;

        if ( index == 0 )           //启动一次传输

        {

             ::ResetEvent( m_reqEvent );

             while ( m_pCurTransFlw != NULL ){

                  

                  pnext = m_pCurTransFlw->GetNextFlow();

                  m_pCurTransFlw->DoCurWork();

 

                  if ( m_pCurTransFlw->GetIfStop() )//取消一个流程,需要唤醒在等待的任务

                  {

                      m_pCurTransFlw->CallWaitCancelTask();

                      break;

                  }

                  else if ( NULL == pnext )       //执行最后一个流程

                  {

                      m_pCurTransFlw->CallWaitFlwFinishTask();  //流程的结束唤醒等待任务

                      break;                     

                  }

                  else

                  {

                      m_pCurTransFlw = pnext;

                  }

                  

             }//end while

        }

        else //离开信号

        {

        

        }

    }while(true);

上面代码中TransThread循环调用TransFlw进行执行,知道TransFlwNext指针为空。下面说明一下这段代码中的需要注意的点。

rc = ::WaitForMultipleObjects(2,m_multiHandls,FALSE,INFINITE);

等待两个Event事件,一个表示启动一次传输,另一个表示退出线程。这样Task只用创建一个线程就可以完成多个流程的操作。

m_pCurTransFlw-> CallWaitFlwFinishTask ();

break;

唤醒等待的Task,任务在执行某一个流程时,如扫描流程时可能需要等待TransThread执行完成才进行后续操作,那么Task就可以等待。就是从TransThrea的唤醒Task中的Event。注意break这样就直接跳出循环,不然在进行while的判断,因为多线程的切换可能会导致,在while判断的时候,m_pCurTransFlw被修改。

下面需要说明的是这一句代码

m_pCurTransFlw->CallWaitCancelTask();

break;

TransThread在执行一个复杂,耗时的流程时,用户选择了暂停,那么Task所在的主线程直接向m_pCurTransFlw发出退出该流程的信号。但流程的退出不会是实时的,流程中通过的是一个循环判断是否设置了退出位,如果退出位置位那么就退出。这样之间有一个时间差,为了保证线程的同步,那么Task需要再发出退出流程信号后,将自己挂起,等到被唤醒。所以如果线程的退出不是正常那么需要唤醒Task。唤醒后的break;也是避免while的再判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值