深圳夜归人

繁华的都市,有谁记得我们的脚步?

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
看到很多地方都使用下面的方式来表示不等待:

ACE_Time_Value nowait (ACE_OS::gettimeofday());
peer ().send (..... &nowait);

这包括马维达译的《ACE程序员指南》。

上次测试了一下,证实这个用法是错误的,可以做一个简单的测试环境:写一个简单的echo服务器,服务端收到数据以后sleep几秒再写回peer,而客户端则在发送数据以后立即关闭peer。这种情况下,服务端send将会有Broken pipe断道错误并强行结束程序,这可以简单添加MSG_NOSIGNAL参数(LINUX下可用),使得程序不会因Broken pipe而结束。

服务端处理过程如下:

// in function handle_input
....
char buf[1024];
ACE_Time_Value nowait (ACE_OS::gettimeofday ());
int recv_len = peer.recv (buf, 1024, MSG_NOSIGNAL, &nowait);
ACE_OS::sleep (5);
peer().send (buf, recv_len, MSG_NOSIGNAL, &nowait);
...

在服务端sleep时,由于客户端断线,将导致send失败。由于使用了MSG_NOSIGNAL标志,程序不会直接DOWN掉,但那个nowait显然没有起到应有的作用,它会一直阻塞。

通过查看ACE源码(ACE.cpp)可以看到,这个值其实是相对于当前时间的长度,send和recv函数里会对这个值加上ACE_OS::gettimeofday()的值,真正超时应该是在35年以后了。。。所以这个用法是错误的,正确用法是:

// in function handle_input
....
char buf[1024];
ACE_Time_Value nowait (ACE_Time_Value::zero);
int recv_len = peer.recv (buf, 1024, MSG_NOSIGNAL, &nowait);
ACE_OS::sleep (5);
peer().send (buf, recv_len, MSG_NOSIGNAL, &nowait);
...
posted on 2005-08-28 17:04  cpunion  阅读(8807)  评论(2编辑  收藏  举报