wishel 发表于 2009-10-24 16:21:29

运行稳定后,大体执行次序为:
async_read_file() -> handle_read_file() -> WriteDate() -> handle_write_stream() -> async_read_file()->......循环下去(实际上是流水线方式)
瓶颈在于从WriteDate() -> handle_write_stream()这段时间的大小,也就是写socket的速度,取决于网速。
理想的情况下一个连接有2个(=流水线的并行数=流水线的串行数)就足够塞满瓶颈了(理论推测,有待测试验证)。message block的大小不要设的过小,以保证socket buffer总是处于比较满的状态。

如果用pool就更好了,循环利用message block,不用每次读写都new、release一个。

wishel 发表于 2009-10-24 16:37:35

其实传文件尤其是大文件最好用ACE_Asynch_Transmit_File。test_proactor.cpp里有它的用法。在windows下它用的api是TransmitFile(),利用了零拷贝原理。可惜在posix下它也是封装的async stream/file类,用的是AIO函数,而不是用零拷贝函数sendfile(),所以性能应该不会比直接用async stream/file类好。实现代码参见POSIX_Asynch_IO.cpp
也可能在别处有对sendfile()的封装吧,只是我没发现。

传大文件的情况主要繁重任务是io,而不是cpu运算,零拷贝省了内存拷贝和频繁内核/用户模式转换的开销,性能好很多。

wishel 发表于 2009-10-24 16:43:28

原帖由 psycheqiqi 于 2009-10-23 14:42 发表 http://www.acejoy.com/bbs/images/common/back.gif
writeDate()函数中是1450号错误。


windows下
1450 系统资源不足,无法完成所请求的服务。
可以用ACE_OS::perror();打出可读信息

以下摘自《windows via c++》,10.5 Basics of Asynchronous Device I/O

If GetLastError returns a value other than ERROR_IO_PENDING, the I/O request could not be queued to the device driver. Here are the most common error codes returned from GetLastError when an I/O request can't be queued to the device driver:

ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY Each device driver maintains a fixed-size list (in a nonpaged pool) of outstanding I/O requests. If this list is full, the system can't queue your request, ReadFile and WriteFile return FALSE, and GetLastError reports one of these two error codes (depending on the driver).

ERROR_NOT_ENOUGH_QUOTA Certain devices require that your data buffer's storage be page locked so that the data cannot be swapped out of RAM while the I/O is pending. This page-locked storage requirement is certainly true of file I/O when using the FILE_FLAG_NO_BUFFERING flag. However, the system restricts the amount of storage that a single process can page lock. If ReadFile and WriteFile cannot page lock your buffer's storage, the functions return FALSE and GetLastError reports ERROR_NOT_ENOUGH_QUOTA. You can increase a process' quota by calling SetProcessWorkingSetSize.

How should you handle these errors? Basically, these errors occur because a number of outstanding I/O requests have not yet completed, so you need to allow some pending I/O requests to complete and then reissue the calls to ReadFile and WriteFile.

psycheqiqi 发表于 2009-10-26 11:04:53

原帖由 wishel 于 2009-10-24 16:11 发表 http://www.acejoy.com/bbs/images/common/back.gif


把OnFileSend() 中的while循环内容提炼出async_read_file();
static ACE_Atomic_Op count;
OnFileSend() { //参照test_proactor.cpp中Sender::open (const ACE_TCHAR *host, u_short port)
...
while (count...

我的逻辑都写到一起了。我试了试这样改了下,自己都晕了。

能不能用开线程或者用信号量的方法

wishel老大,你要有时间的话,我把项目给你发过去。这个问题一个星期了都没弄好。

[ 本帖最后由 psycheqiqi 于 2009-10-26 13:09 编辑 ]

psycheqiqi 发表于 2009-10-26 15:47:39

wishel,你终于来了。

wishel 发表于 2009-10-26 15:51:51

原帖由 wishel 于 2009-10-24 16:43 发表 http://www.acejoy.com/bbs/images/common/back.gif


windows下
1450 系统资源不足,无法完成所请求的服务。
可以用ACE_OS::perror();打出可读信息


汗。。用perror打不出来这个1450的信息,可能因为perror是clib函数,对windows函数无效
只能查WinError.h

#define ERROR_NO_SYSTEM_RESOURCES      1450L

ps:perror程序

errno = 1450L;
perror("perror 1450:");
printf("14: %s\n", strerror(14L));
printf("1450: %s\n", strerror(1450L));

结果:
perror 1450:: Unknown error
14: Bad address
1450: Unknown error

wishel 发表于 2009-10-26 16:02:52

原帖由 psycheqiqi 于 2009-10-26 11:04 发表 http://www.acejoy.com/bbs/images/common/back.gif


我的逻辑都写到一起了。我试了试这样改了下,自己都晕了。

能不能用开线程或者用信号量的方法

wishel老大,你要有时间的话,我把项目给你发过去。这个问题一个星期了都没弄好。 ...

我不是老大哈,大家互相学习。

我只是提供一个思路。就是想办法控制发送速度,其实可以有很多种方法的。
你把自己的思路理理,想想有没有简单的方法,达到目的就行。目的就是限制new的速度不要超过release的速度。如果自己能想到解决方法,这是最好的提高方式。
实在来不及的话,你把工程打包发上来我看看吧。

“能不能用开线程或者用信号量的方法”可能也可以,我没有深想,建议你仔细想想试试看。

psycheqiqi 发表于 2009-10-26 16:08:28

回复 #37 wishel 的帖子

我发你邮箱吧,论坛好像传不上去。
你的邮箱多少?

[ 本帖最后由 psycheqiqi 于 2009-10-26 16:17 编辑 ]

modern 发表于 2009-10-26 16:08:43

原帖由 wishel 于 2009-10-24 16:21 发表 http://www.acejoy.com/bbs/images/common/back.gif
运行稳定后,大体执行次序为:
async_read_file() -> handle_read_file() -> WriteDate() -> handle_write_stream() -> async_read_file()->......循环下去(实际上是流水线方式)
瓶颈在于从WriteDate() -> handle_write_st ...
wishel 说的也正是我想说的!
另外对于资源耗尽,
建议楼主首先检查是否自己代码有内存泄露。
比如像wishel 所说,ACE_Message_Block申请了忘记Release了。

[ 本帖最后由 modern 于 2009-10-26 16:14 编辑 ]

wishel 发表于 2009-10-26 16:21:34

原帖由 psycheqiqi 于 2009-10-26 16:08 发表 http://www.acejoy.com/bbs/images/common/back.gif
我发你邮箱吧,论坛好像传不上去。
你的邮箱多少?

收短消息。
页: 1 2 3 [4] 5 6
查看完整版本: proactor传文件的测试