找回密码
 用户注册

QQ登录

只需一步,快速开始

楼主: xtdwnuisea

关于service configure 和 streams 能结合起来吗?

[复制链接]
发表于 2010-1-7 13:29:46 | 显示全部楼层
这个说来话长,我简单的回答一下楼主的几个问题,要融会贯通的还是得看书。
1.Service configraturor可以动态配置ACE_Service_Object 、ACE_Moudle、ACE_Stream等,
注意Moudle可以配置在Stream中,也可以直接配置。
2.ACE_Service_Config是Service configraturor这套框架的控制接口。
3.ACE_Service_Repository 与 ACE_Service_Repository_Iterator 是这套框架的容器类。
4.类似make_mr ,ACE_SVC_FACTORY_DECLARE (Test_Task)
ACE_SVC_FACTORY_DEFINE (Test_Task)这种东西要是不理解的话,先看书。
5.应用程序中每次编写一个新的功能的动态库都要引入一次对应的lib库,那岂不麻烦死。
如果对这个不理解,还是先看书,理解svc.conf是怎么用的。
 楼主| 发表于 2010-1-7 13:53:08 | 显示全部楼层
我能够理解 Service configraturor可以动态配置ACE_Service_Object ,
但我不能够理解 Service configraturor可以动态配置ACE_Moudle、ACE_Stream等...

只是因为:书上、CCM_App工程中,都没有完整的工程来讲这个事情,我不知道版主是如何学习与理解这些东西的;

在CCM_App工程中, 确实我也看到了加载ACE_Moudle、ACE_Stream, 但它们都是孤零零地被加载,不知道它如何在被加载的Stream中添加Moudle, 更不知道消息息放到Stream中后,是如何在各Moudle间运转的, 我不知道版主是否见过这样的可运行的例子,消息能运转起来的...

这个时候我要提到:我知道ACE书上是讲它可以融合二者、我也知道它DSEJ-94.pdf 94年写的论文中也是说可以加载在一起,《ACE程序员指南-网络与系统编程的实用设计模式》一书也有一句话说它们可以融合在一起,但我除了看到一个不完整的CCM_App样例工程,一个并不能运行消息,不含消息流转的工程,其它一点也看不到; 我知道书上说是可以、我的老板也说可以、您也说可以、但是事实上没有一个实际的工程,也许做程序员的人都太实际了,看不到存在的东西就认为它不存在;  最后我想补充:理论上是可以的,我认可,事实上可以吗?我想问的就是这个!
发表于 2010-1-7 14:55:52 | 显示全部楼层
他们可不是被孤零零的加载哦,
楼主没有好好看svc.conf里面的内容,
才会有上述的疑问的。

至于消息如何流转,
C++NPV2第九章上也有例子。
都是可以作为参考的。

另外不知道楼主是否看过APG的第18、19章。
那个例子或许对你会有帮助。
发表于 2010-1-7 14:59:04 | 显示全部楼层
举例:
stream dynamic CCM_App STREAM *CCM_App:make_stream() active
{
  dynamic Device_Adapter Module *CCM_App:make_da()
  dynamic Event_Analyzer Module *CCM_App:make_ea()
  dynamic Multicast_Router Module *CCM_App:make_mr() "-p 3001"
}
按照上述的格式,STREAM 将被加载到Service configraturor中
大括号里面的三个Module将被加载到STREAM 中。

stream dynamic CCM_App STREAM *CCM_App:make_stream() active
dynamic Device_Adapter Module *CCM_App:make_da()
dynamic Event_Analyzer Module *CCM_App:make_ea()
dynamic Multicast_Router Module *CCM_App:make_mr() "-p 3001"
这样的格式,四个模块将会分别加载到Service configraturor中。
 楼主| 发表于 2010-1-7 15:19:00 | 显示全部楼层
楼上版主,在谈论这个问题中,您是我遇到的最务实的对话者了, 已经谈到实际问题上了;

其实我注意了svc.conf这一段了,并且做了详细测试, 我一开始也是和你一样以为svc.conf中这一段就是把三个model 加入到这个 CCM_App:make_stream 流中, 但我后来认为它不是这样的是因为,我做了如下测试 :

//这个函数中我加了我自己的代码,其目的是向这个流中添加消息, 但这个消息根本就不能在Module中流转......
MT_Stream * make_stream (void)
{
        MT_Stream* pMT_Stream = new MT_Stream;

        ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("make_stream - zhangcf new thread.\n")));

        // WorkStreamThread* pWorkStreamThread = new WorkStreamThread( );
        //pWorkStreamThread->activate();

        // new thread error, exec flowing:
        char p[20] = {"333333333"};
        printf("开始压入消息\n");
        ACE_Message_Block * mb;
    ACE_NEW_RETURN (mb, ACE_Message_Block (strlen(p)), NULL);

    char* pp = (char *)mb->wr_ptr ();
    mb->wr_ptr (strlen(pp));
         
    int rval = pMT_Stream->put (mb);
    ACE_DEBUG ((LM_DEBUG,
                ACE_TEXT ("RecordingStream::record() - ")
                ACE_TEXT ("this->put() returns %d\n"),
                rval));

  return pMT_Stream;
}


而CCM_App例子中提供的这个函数是这样写的:
MT_Stream * make_stream (void)
{
  return new MT_Stream;
}
 楼主| 发表于 2010-1-7 15:20:42 | 显示全部楼层
CCM_App 这个项目我已经能运行起来, 我已经能把它编译成lib 并且能把 相应的
stream dynamic CCM_App STREAM *CCM_App:make_stream() active
dynamic Device_Adapter Module *CCM_App:make_da()
dynamic Event_Analyzer Module *CCM_App:make_ea()
dynamic Multicast_Router Module *CCM_App:make_mr() "-p 3001"

这些函数全部启动起来, 这些函数中的文字输出我全部都能运行起来
 楼主| 发表于 2010-1-7 15:30:15 | 显示全部楼层
至于 消息流转,我做了Stream的单向流与双向流,真的非常熟悉; 包括流中的Module动态拆卸等, 我还做了流的压力测试与效率统计:(只能以文本方式贴出来了)


##############################
时间单位是秒(注:IBM数据是假的)
##############################
系统概况:1个单向               
        加入队列时间        执行完成
Windows        6        9
Linux        1.3        4.3
Linux(无屏显)        1.2        1.2
IBM        4.5        80
               
系统概况:2个单向                 
        加入队列时间        执行完成
Windows        8        14
Linux        6        8
Linux(无屏显)        2        2
IBM        4.5        80
               
系统概况:10个单向               
        加入队列时间        执行完成
Windows        32        47
Linux        37        52
Linux(无屏显)        6        6
IBM        4.5        80
               
系统概况:20个单向                 
        加入队列时间        执行完成
Windows        41        71
Linux        79        166
Linux(无屏显)        11        11
IBM        4.5        80

##################################
下面是针对10个单向流测试情况:
##################################
                        
各平台1000条流消息压入测试                        
        加入队列时间        执行完成        
Windows        0.17        2.15        
Linux        0.3        3        
Linux(无屏显)        0.58        0.61        
IBM        4.5        80        
                        
各平台10000条流消息压入测试                        
        加入队列时间        执行完成        
Windows        32        47        
Linux        37        52        
Linux(无屏显)        6        6        
IBM        4.5        80        
                        
各平台100000条流消息压入测试(一百万)                        
        加入队列时间        执行完成        列1
Windows        0        0        Windows估计很难出来
Linux        499        568        
Linux(无屏显)        53        56        
IBM        4.5        80

[ 本帖最后由 xtdwnuisea 于 2010-1-7 15:31 编辑 ]
 楼主| 发表于 2010-1-7 15:38:27 | 显示全部楼层
还有,我想说的是svc.conf中这样加载估计是不行的, 至少于CCM_App这个例子没有做完整,因为在Stream这个章节中调度消息是要我们手工写基类调度的, 例如我们需要自己去调用put() 与get()消息,如Stream中这段代码,当然是放在基类中的,这个不是ACE基类,而是要我们自己封装的:

下面就是单向流中:作为Module之上的Task基类写法:(它的目的是调度Module间的message)
#pragma once
#include "ace/Task_T.h"
#include "ace/ace_wchar.h"
#include "Message.h"

class CBasicTask :
        public ACE_Task<ACE_MT_SYNCH>
{
public:
        CBasicTask(void);

        ~CBasicTask(void);

        typedef ACE_Task<ACE_MT_SYNCH> inherited;

public:
        // open (void * = 0)
        int open(void* = 0 );

  // Listing 101 code/ch18
  int put (ACE_Message_Block *message,
           ACE_Time_Value *timeout)
  {
    return this->putq (message, timeout);
  }
  // Listing 101

  // Listing 1020 code/ch18
  virtual int svc (void)
  {
    for (ACE_Message_Block *message = 0; ; )
      {
        ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("BasicTask::svc() - ")
                    ACE_TEXT ("waiting for work\n" )));

        if (this->getq (message) == -1)
          ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
                             ACE_TEXT ("getq")),
                            -1);
        // Listing 1020

        // Listing 1021 code/ch18
        if (message->msg_type () == ACE_Message_Block::MB_HANGUP)
          {
            if (this->putq (message) == -1)
              {
                ACE_ERROR ((LM_ERROR,
                            ACE_TEXT ("%p\n"),
                            ACE_TEXT ("Task::svc() putq")));
                message->release ();
              }
            break;
          }
        // Listing 1021

        // Listing 1022 code/ch18
        CMessage *recordedMessage =
          (CMessage *)message->rd_ptr ();

        if (this->process (recordedMessage) == -1)
          {
            message->release ();
            ACE_ERROR_RETURN ((LM_ERROR,
                               ACE_TEXT ("%p\n"),
                               ACE_TEXT ("process")),
                              -1);
          }
        // Listing 1022

        // Listing 1023 code/ch18
       ACE_DEBUG ((LM_DEBUG,
                    ACE_TEXT ("BasicTask::svc() - ")
                    ACE_TEXT ("Continue to next stage\n" )));
        if (this->next_step (message) < 0)
          {
            ACE_ERROR ((LM_ERROR,
                        ACE_TEXT ("%p\n"),
                        ACE_TEXT ("put_next failed")));
            message->release ();
            break;
          }
        // Listing 1023
      }

    return 0;
  }

  // Listing 103 code/ch18
  virtual int close (u_long flags)
  {
    int rval = 0;

    if (flags == 1)
      {
        ACE_Message_Block *hangup = new ACE_Message_Block ();
        hangup->msg_type (ACE_Message_Block::MB_HANGUP);
        if (this->putq (hangup) == -1)
          {
            hangup->release ();
            ACE_ERROR_RETURN ((LM_ERROR,
                               ACE_TEXT ("%p\n"),
                               ACE_TEXT ("Task::close() putq")),
                              -1);
          }

        rval = this->wait ();
      }

    return rval;
  }
  // Listing 103

  // Listing 105 code/ch18
protected:
  virtual int next_step (ACE_Message_Block *message_block)
  {
    return this->put_next (message_block);
  }
  // Listing 105

  // Listing 104 code/ch18
  virtual int process (CMessage *message) = 0;

public:
        virtual int desired_threads(void);
};
发表于 2010-1-7 15:45:46 | 显示全部楼层
很高兴看到楼主上面提出的问题,可以看出楼主确实是花了不少时间研究。
其实离楼主想要的已经越来越近了。
1.put了就会流转起来么,再我看来当然不会,put了之后,
至少放在 队列头部的Module的wirte task你得处理呀。
你不处理然后扔到队列中下一个Module的wirte task里面当然他不会流转了。
2.答复15楼的问题,
第一种方法,三个model 确实被加载到stream中,第二种方法,三个model 与一个stream被各自加载。
这不是靠推断的。我是跟代码看到源代码中确实按照我说的方式加载的。
楼主的论据有问题,导致得出了错误的结论。
 楼主| 发表于 2010-1-7 16:03:14 | 显示全部楼层
“1.put了就会流转起来么,再我看来当然不会,put了之后,
至少放在 队列头部的Module的wirte task你得处理呀。” 刚刚看到您这句话,我就有一种乌云拔见天日的感觉, 我的问题一直就是:CCM_App这个工程是不完整的,它没有让消息流起来,所以:我没法做;

OK, 我现在就按您意思假设 make_da() make_ea() make_mr() 出来的Module是加入到make_stream() new出来的流中, 我现在再做一个测试是:
我在make_da() ...ea() ...mr() 使用的Test_Task线程中类中添加srv虚函数 其内容基本上就是我实现单向流时候的CBasicTask中的svc代码, 我做完测试再来汇报情况;
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-2 23:01 , Processed in 0.016230 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表