zoukankan      html  css  js  c++  java
  • 使用ACE_Task管理线程

    为什么要使用ACE_Task来管理线程

    从C#转到C++后,感觉到C++比C#最难的地方,就是在系统编程时,C#中有对应的类库,我接触到一个类后,就可以通过这个类,知道很多相关的功能。而在C++中,必须使用Windows API,但是Windows API的缺点反而是不系统。比如,想要创建一个线程时,C#中可以通过新建一个Thread类,我得到这个类后,就可以通过帮助或者MSDN了解到这个类中有哪些方法,如何管理线程等。但是C++中,创建一个线程,需要调用CreateThread,但因为它是一个API,所以很难快速的了解到与线程管理相关的API,至少对我来说,这是一个难点。

    C#的优势是以类的方式去管理线程,而C++ 调用API更像是在单打独斗,显得特别特别散乱。

    那么在C++中,我们能不能以类的方式去管理线程呢。针对这个问题,ACE_Task便浮出了水面。

    ACE_Task使用方法

    ACE_Task对常用线程处理进行了OO包装,通过ACE_Task,能对线程进行更好的操作。

    根据ACE_Task的父类ACE_Task_Base中的注释,可以总结出以下几点:

    • 想要使用ACE_Task,就要从ACE_Task派生一个子类,然后实现比较重要的几个虚方法。
    • 实现服务初始化和终止方法:open()方法应该包含所有专属于任务的初始化代码。其中可能包括诸如连接控制块、锁和内存这样的资源。close() 方法是相应的终止方法。
    • 调用启用(Activation )方法:在主动对象实例化后,你必须通过调用activate()启用它。要在主动对象中创建的线程的数目,以及其他一些参数,被传递给activate()方法。activate()方法会使svc()方法成为所有它生成的线程的启动点。
    • 实现服务专有的处理方法:如上面所提到的,在主动对象被启用后,各个新线程在svc()方法中启动。应用开发者必须在子类中定义此方法。

    实现ACE_Task的虚方法

    编写ACE_Task的Demo

    下面就通过总结的几点来编写一个Demo

    首先是派生ACE_Task的子类ShowTask

    #pragma once
    #include "ace/Task_T.h"
    #include <string>
    #include <iostream>
    using namespace std;
    
    class ShowTask : public ACE_Task<ACE_SYNCH>
    {
    public:
      ShowTask(const char* str_to_show, int interval) : show_str_(str_to_show), interval_(interval)
      {
        //启动线程
        activate();
      }
      ~ShowTask()
      {
        //结束线程
        close();
      }
    public:
      virtual int open( void *args = 0 )
      {
        cout << "线程启动" << endl;
        return 0;
      }
    
      virtual int close( u_long flags = 0 )
      {
        cout << "线程结束" << endl;
        return 0;
      }
    
      virtual int svc( void )
      {
        int time_begin = GetTickCount();
        while(true)
        {
          int time_end = GetTickCount();
          if(time_end - time_begin >= interval_)
          {
            time_begin = time_end;
            cout << show_str_ << endl;
          }
          Sleep(10);
        }
        return 0;
      }
    private:
      //需要显示的信息
      string show_str_;
      //间隔多长时间进行显示
      int interval_;
    };

    然后在程序中调用ShowTask

    #include "ShowTask.h"
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        ACE::init();
        string str = "这是一个测试程序";
        ShowTask task(str.c_str(), 1000);
    
        Sleep(10000);
        ACE::fini();
        return 0;
    }

    运行效果图:

    demo_运行效果图

    需要注意的地方

    在程序中使用ACE_Task,那么就必须在使用前对ACE进行初始化,即调用ACE::init方法,然后在程序结束的时候调用ACE::fini方法。如果没有进行初始化就调用ShowTask,那么程序就会崩溃。

    至于为什么会崩溃,以及ACE::init方法做了些什么,后续的文章中会详细的介绍。

    关于open方法的疑惑

    从上面的测试图中可以看到,线程结束后,调用了close方法,但是在线程启动时并没有调用open方法。

    而且从谷歌找到的资料中也介绍,在线程启动的时候回调用open方法,而且他们的示例程序与本文中提供的demo中关于ACE_Task的使用方法也基本一致。

    那么open方法为什么没有被调用呢,究竟是使用方法不对,还是因为ACE版本不同导致的。关于这个问题也会在后续的文章中进行详细的介绍。

  • 相关阅读:
    Flash/Flex学习笔记(44):万有引力与粒子系统
    Flash/Flex学习笔记(43):动量守恒与能量守恒
    Flash/Flex学习笔记(36):自己动手实现一个滑块控件(JimmySilder)
    Flash/Flex学习笔记(40):弹性运动续弹簧
    Flash/Flex学习笔记(38):缓动动画
    Flash/Flex学习笔记(37):不用系统组件(纯AS3)的视频播放器只有8.82K
    Flash/Flex学习笔记(42):坐标旋转
    LAMP经典入门教程
    配置SQLServer2005数据库镜像实践操作记录
    PHP 免费视频教程
  • 原文地址:https://www.cnblogs.com/hbccdf/p/acetaskdemo.html
Copyright © 2011-2022 走看看