modern 发表于 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是怎么用的。

xtdwnuisea 发表于 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样例工程,一个并不能运行消息,不含消息流转的工程,其它一点也看不到; 我知道书上说是可以、我的老板也说可以、您也说可以、但是事实上没有一个实际的工程,也许做程序员的人都太实际了,看不到存在的东西就认为它不存在;最后我想补充:理论上是可以的,我认可,事实上可以吗?我想问的就是这个!

modern 发表于 2010-1-7 14:55:52

他们可不是被孤零零的加载哦,
楼主没有好好看svc.conf里面的内容,
才会有上述的疑问的。

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

另外不知道楼主是否看过APG的第18、19章。
那个例子或许对你会有帮助。

modern 发表于 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中。

xtdwnuisea 发表于 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 = {"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;
}

xtdwnuisea 发表于 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"

这些函数全部启动起来, 这些函数中的文字输出我全部都能运行起来

xtdwnuisea 发表于 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 编辑 ]

xtdwnuisea 发表于 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);
};

modern 发表于 2010-1-7 15:45:46

很高兴看到楼主上面提出的问题,可以看出楼主确实是花了不少时间研究。
其实离楼主想要的已经越来越近了。
1.put了就会流转起来么,再我看来当然不会,put了之后,
至少放在 队列头部的Module的wirte task你得处理呀。
你不处理然后扔到队列中下一个Module的wirte task里面当然他不会流转了。
2.答复15楼的问题,
第一种方法,三个model 确实被加载到stream中,第二种方法,三个model 与一个stream被各自加载。
这不是靠推断的。我是跟代码看到源代码中确实按照我说的方式加载的。
楼主的论据有问题,导致得出了错误的结论。

xtdwnuisea 发表于 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代码, 我做完测试再来汇报情况;
页: 1 [2] 3
查看完整版本: 关于service configure 和 streams 能结合起来吗?