找回密码
 用户注册

QQ登录

只需一步,快速开始

楼主: skillzero

请教proactor例子的速度问题和无法写文件问题

[复制链接]
发表于 2009-6-1 14:27:05 | 显示全部楼层
不能写入?那需要跟进去看看了。
发表于 2009-6-1 14:51:04 | 显示全部楼层
这个例子我记得很早以前拿vs2003跑过,写磁盘印象里是没问题的。
发表于 2009-6-1 16:36:30 | 显示全部楼层
我在VS2005和VS2008跑过都没出现问题1   if (this->wf_.write (result.message_block (),result.bytes_transferred (),   this->file_offset_) == -1)

对于问题2和问题3我也有做过测试,有一样的问题。
测试1:将ACE_Block_Message改为8M,传输小于7M的文件在1秒内完成,传输10.2M的文件为6秒。但是传输100+M的文件时每次只传输17520字节。
测试2:将ACE_Block_Message改为11M,传输小于11M的文件都在1秒内完成。传输100+M的文件上同。
测试3:将ACE_Block_Message改为17521个字节,传输7M和10.2M的文件每次都以17521字节传输,但100+M的文件每次还是传输17520
测试4:将ACE_Block_Message改为17519个字节,传输三个文件每次都传输17519。
测试5:将ACE_Block_Message改为小于17520字节,每次都以设定的值传输。

为什么传输大数据量的数据效率如此低呢?
 楼主| 发表于 2009-6-2 22:20:53 | 显示全部楼层
在咨询过本站的csfreebird后,问题得到了解决
在handle_read_stream里去判断这个result.message_block的 实际传输量如果小于 预期的再次 就再次发动一次读操作针对比预期残余的那部分
后来实测 在 一个百兆网卡和 千兆网卡 中间由 一个 千兆路由 连同,速度有 10M+
千兆网卡之间和一个千兆路由的时候,还不理想,只有30M 左右
messageblock的值设为 65535
详细点的见
http://www.skillzero.cn/archives/97
发表于 2009-6-3 11:38:27 | 显示全部楼层
skillzero,您好!我按照你的思路去修改程序测试后发现并没有你说的10M+的效果,帮忙看下我的程序。代码如下:

int
Receiver::initiate_read_stream (void)
{
  ACE_Message_Block *mb = 0;
  ACE_NEW_RETURN (mb,
                  ACE_Message_Block (65535+ 1),
                  -1);

  if (this->rs_.read (*mb,
                      mb->size () - 1) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "ACE_Asynch_Read_Stream::read"),
                      -1);
  return 0;
}

void
Receiver::handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
{
  ACE_DEBUG ((LM_DEBUG,
              "handle_read_stream called\n"));
  size_t actualBytes=result.bytes_transferred();
  result.message_block ().rd_ptr ()[ result.bytes_transferred ()] = '\0';

  ACE_DEBUG ((LM_DEBUG, "********************\n"));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_to_read", result.bytes_to_read ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "handle", result.handle ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "bytes_transfered", result.bytes_transferred ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "act", (u_long) result.act ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "success", result.success ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "completion_key", (u_long) result.completion_key ()));
  ACE_DEBUG ((LM_DEBUG, "%s = %d\n", "error", result.error ()));
  ACE_DEBUG ((LM_DEBUG, "********************\n"));
#if 0
  // This can overrun the ACE_Log_Msg buffer and do bad things.
  // Re-enable it at your risk.
  ACE_DEBUG ((LM_DEBUG, "%s = %s\n", "message_block", result.message_block ().rd_ptr ()));
#endif /* 0 */

  if (result.success () && result.bytes_transferred () != 0)
    {
   
      if (this->wf_.write (result.message_block (),
                           result.bytes_transferred (),
                           this->file_offset_) == -1)
        {
          ACE_ERROR ((LM_ERROR,
                      "%p\n",
                      "ACE_Asynch_Write_File::write"));
          return;
        }

      if(actualBytes<needDataLength_) //needDataLength_声明为全局变量为65535
      {
          ACE_DEBUG ((LM_DEBUG,"readed bytes(%d) is less than needed bytes(%d)\n",actualBytes,needDataLength_));
          size_t dataLength = needDataLength_-actualBytes;
          ACE_Message_Block* pMessageBlock;
          ACE_NEW_NORETURN(pMessageBlock,ACE_Message_Block(dataLength+1));
           if(this->rs_.read(*pMessageBlock,pMessageBlock->space()-1)!=0)
             {
         pMessageBlock->release();
        // needDataLength_=dataLength;
       
               }
           needDataLength_=dataLength;

            return;
         }
     needDataLength_=65535;
      // Initiate new read from the stream.
    }
  else
    {
      ACE_DEBUG ((LM_DEBUG,
                  "Receiver completed\n"));
      result.message_block ().release ();
      delete this;
    }
   if (this->initiate_read_stream () == -1)
        return;
}
发表于 2009-6-15 14:33:27 | 显示全部楼层
wupeter1 ,你只改了receiver的buffer大小,sender也要改(Sender::initiate_read_file (void)中)

这个例子我以前也跑过,程序中sender的读文件buffer和receiver的读stream的buffer都是512,太小。sender可以改到10M以上,但receiver的读stream的buffer超过17520就不起作用(每次读到的最大长度,具体原因不知道)。
发表于 2009-6-15 16:25:44 | 显示全部楼层
是否因为超过TCP默认的接受缓冲区大小导致你设置的这个数值不起作用,
17520比较接近16K,
尝试使用SO_RCVBUF 选项把接收缓冲区设置的大一些,比如65535
发表于 2009-6-16 14:54:21 | 显示全部楼层
原帖由 modern 于 2009-6-15 16:25 发表
是否因为超过TCP默认的接受缓冲区大小导致你设置的这个数值不起作用,
17520比较接近16K,
尝试使用SO_RCVBUF 选项把接收缓冲区设置的大一些,比如65535 ...


有可能,很久以前跑的,现在懒得调了。wupeter1如果还有兴趣让他试试看。
发表于 2009-6-16 18:55:35 | 显示全部楼层

回复 #18 wishel 的帖子

把文件数据读到内存,然后把写文件函数注释掉,测试内存到内存的之间数据的传输速度是可以达到10M+的
发表于 2009-6-17 13:11:51 | 显示全部楼层
原帖由 wupeter1 于 2009-6-16 18:55 发表
把文件数据读到内存,然后把写文件函数注释掉,测试内存到内存的之间数据的传输速度是可以达到10M+的

没通过网络么?内存到内存应该远不止10M+吧。
上面说的10M+的上限是由于百兆接口的限制。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

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

GMT+8, 2024-12-23 08:18 , Processed in 0.026805 second(s), 4 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

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