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一个。 其实传文件尤其是大文件最好用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运算,零拷贝省了内存拷贝和频繁内核/用户模式转换的开销,性能好很多。 原帖由 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. 原帖由 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 编辑 ] wishel,你终于来了。 原帖由 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 原帖由 psycheqiqi 于 2009-10-26 11:04 发表 http://www.acejoy.com/bbs/images/common/back.gif
我的逻辑都写到一起了。我试了试这样改了下,自己都晕了。
能不能用开线程或者用信号量的方法
wishel老大,你要有时间的话,我把项目给你发过去。这个问题一个星期了都没弄好。 ...
我不是老大哈,大家互相学习。
我只是提供一个思路。就是想办法控制发送速度,其实可以有很多种方法的。
你把自己的思路理理,想想有没有简单的方法,达到目的就行。目的就是限制new的速度不要超过release的速度。如果自己能想到解决方法,这是最好的提高方式。
实在来不及的话,你把工程打包发上来我看看吧。
“能不能用开线程或者用信号量的方法”可能也可以,我没有深想,建议你仔细想想试试看。
回复 #37 wishel 的帖子
我发你邮箱吧,论坛好像传不上去。你的邮箱多少?
[ 本帖最后由 psycheqiqi 于 2009-10-26 16:17 编辑 ] 原帖由 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 编辑 ] 原帖由 psycheqiqi 于 2009-10-26 16:08 发表 http://www.acejoy.com/bbs/images/common/back.gif
我发你邮箱吧,论坛好像传不上去。
你的邮箱多少?
收短消息。