现在的位置: 首页 > 综合 > 正文

多线程中使用ACE日志策略示例

2012年08月28日 ⁄ 综合 ⁄ 共 4595字 ⁄ 字号 评论关闭

多线程中使用ACE日志策略示例

2009年10月26日

 
 

0. 本文介绍

    本文通过代码,演示了如何在多线程中使用ACE日志设施(log facilites)代码。本文分为三部分。

第一部分概述了ACE日志设施代码;

第二部分给出完整的源代份和运行结果;

第三部分对相关代码作了说明,其中包括了运行Reactor事件,运行时动态服务加载等。

 

1. ACE日志策略

ACE_Logging_Strategy 提供了一种可以在运行时动态配置ACE日志的机制,通过这种机制

可以设置日志文件的大小以及日志文件的“回转”备份。

ACE_Logging_Strategy  默认使用单体的Reactor,使用者也可以通过

  ACE_Reactor my_reactor;
ACE_Logging_Strategy *logging_strategy = …… // Get instance.
 
  logging_strategy->reactor (&my_reactor);

修改。

ACE_Logging_Strategy 的主要参数说明

-f 用来控制日志的标志位,如

   OSTREAM, STDERR, LOGGER, VERBOSE,
    SILENT, VERBOSE_LITE

-i 指定检测日志文件大小的时间间隔。 单位为秒,默认为0表示不检查。

   ACE_Logging_Strategy  内部实现了定时器。

-m 指定日志文件的大小,单位为Kbytes (千字节数)

-N 指定可以创建日志文件的最多个数。超过个数就“回转”备份,即替换旧的日志文件。

-p 指定输出日志的严重级别

DEBUG, INFO, WARNING, NOTICE, ERROR, CRITICAL, ALERT,
EMERGENCY

如果想禁止输出日志的严重级别,可以这样使用

~DEBUG, ~INFO, ~WARNING,

     ~NOTICE, ~ERROR, ~CRITICAL, ~ALERT, ~EMERGENCY

 

2. 示例的代码

   本文以教学演示为目的,所以代码全部写在同一个文件中。下面是完整的代码

//begin
//file: test_log.cpp
//

// author: stone jiang (http://www.tao-studio.net/blog)

// date:    2009-10-26

 

#include "ace/Log_Msg.h"
#include "ace/Time_Value.h"
#include "ace/OS.h"
#include "ace/Logging_Strategy.h"
#include "ace/ARGV.h"
#include "ace/Dynamic_Service.h"
#include "ace/Service_Config.h"
#include "ace/Reactor.h"
#include "ace/Task.h"

class Task_Reactor : public ACE_Task_Base
{
public:
    virtual int open (void *args = 0);
    virtual int svc (void);
    int  done();
};

int Task_Reactor::open(void *args /* = 0 */)
{
    ACE_DEBUG ((LM_DEBUG, "(%t) TaskReactor::open()/n"));

    return this->activate ();
}

int Task_Reactor::svc()
{
    ACE_DEBUG ((LM_DEBUG, "(%t) TaskReactor::svc()/n"));
    return  ACE_Reactor::instance()->run_event_loop();
}

int  Task_Reactor::done()
{
    ACE_DEBUG ((LM_DEBUG, "(%t) TaskReactor::done()/n"));

    return ACE_Reactor::instance()->end_event_loop();
}

class Task_Test : public ACE_Task<ACE_MT_SYNCH>
{
public:
    virtual int open (void *args = 0);
    virtual int close (u_long flags = 0);
    virtual int svc (void);

private:
};

int
Task_Test::open (void *)
{
    return this->activate ();
}

int
Task_Test::close (u_long)
{
    return 0;
}

int
Task_Test::svc (void)
{

    ACE_DEBUG ((LM_DEBUG, "(%t) svc: waiting/n"));
    for(int i = 0; i < 10;  i++)
    {
        ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t|%T) Task_Test:: i = %d./n"),i));
        ACE_OS::sleep(ACE_Time_Value(1,0));

    }

    ACE_DEBUG ((LM_DEBUG, "(%t) svc: finished waiting/n"));
    return 0;
}

int ACE_TMAIN(int argc, ACE_TCHAR *[])
{
    ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t|%T) start here./n")));
    ACE_Logging_Strategy *  log =
        ACE_Dynamic_Service<ACE_Logging_Strategy>::instance("Logger");
    if (log == 0)
    {
        int result =  ACE_Service_Config::process_directive(
            ACE_DYNAMIC_SERVICE_DIRECTIVE("Logger",
             "ACE",             
            "_make_ACE_Logging_Strategy",
            "")
            );
        ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t|%T) result = %d./n"),result));
    }
    log =
        ACE_Dynamic_Service<ACE_Logging_Strategy>::instance("Logger");

    if (log)
    {
        ACE_ARGV args;
        args.add (__argv[0]);
        char cmdline[250] ={0};
        sprintf(cmdline,"-s log.txt -f STDERR|OSTREAM -p DEBUG|ERROR");
        args.add (ACE_TEXT (cmdline));    
        log->init(args.argc(),args.argv());
    }
    else
    {
        return -1;
    } 

    Task_Test  testTask;
    testTask.open( 0 );
    Task_Reactor reactorTask;
    reactorTask.open(0);

    for(int i = 0; i < 10;  i++)
    {
        ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t|%T) i = %d./n"),i));
        ACE_OS::sleep(ACE_Time_Value(1,0));

    }
    testTask.wait();

    reactorTask.done();
    reactorTask.wait();
    ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%t|%T) end here./n")));
    return 0;
};

//file: test_log.cpp
// end

 

 

代码运地结果

在可执行文件当前目录下,程序自动创建了日志文件log.txt,内容如下

(4728) TaskReactor::open()
(4728| 15:14:34.156000) i = 0.
(4944) TaskReactor::svc()
(3248) svc: waiting
(3248| 15:14:34.156000) Task_Test:: i = 0.
(4728| 15:14:35.156000) i = 1.
(3248| 15:14:35.156000) Task_Test:: i = 1.
(4728| 15:14:36.156000) i = 2.
(3248| 15:14:36.156000) Task_Test:: i = 2.
(4728| 15:14:37.156000) i = 3.
(3248| 15:14:37.156000) Task_Test:: i = 3.
(4728| 15:14:38.156000) i = 4.
(3248| 15:14:38.156000) Task_Test:: i = 4.
(4728| 15:14:39.156000) i = 5.
(3248| 15:14:39.156000) Task_Test:: i = 5.
(4728| 15:14:40.156000) i = 6.
(3248| 15:14:40.156000) Task_Test:: i = 6.
(4728| 15:14:41.156000) i = 7.
(3248| 15:14:41.156000) Task_Test:: i = 7.
(4728| 15:14:42.156000) i = 8.
(3248| 15:14:42.156000) Task_Test:: i = 8.
(4728| 15:14:43.156000) i = 9.
(3248| 15:14:43.156000) Task_Test:: i = 9.
(3248) svc: finished waiting
(4728) TaskReactor::done()
(4728| 15:14:44.156000) end here.

 

3.与程序相关的ACE其它内容

本程序还用到了多线程编程,演示了ACE_Task_Base, ACE_Task<>,的使用;

其中Task_Reactor演示了如何在独立的线程中运行Reactor事件循环,并在主线程中结束Reactor事件循环。

 

本程序还用到了动态服务加载:

ACE_Service_Config::process_directive()

它可以在运行时显示的加载所需要的服务(svc),使用这种手法可以不必编写*.conf文件。

本程序还用到了在程序中根据ident访问直接访问加载的动态服务

ACE_Dynamic_Service<ACE_Logging_Strategy>::instance("Logger");

 

其他:

在学习ACE的过程中如果有任何问题,欢迎来邮件(jiangtao) 或在本站论坛http://www.tao-studio.net/bbs中提问。

抱歉!评论已关闭.