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

多线程中使用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中提问。

你可能感兴趣的:(多线程,编程,.net,OS,bbs)