深圳夜归人

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

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  32 随笔 :: 0 文章 :: 64 评论 :: 1 引用
看到很多地方都使用下面的方式来表示不等待:

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 阅读(3242) 评论(2) 编辑 收藏

评论

大哥,厉害.
 回复 引用   

#2楼 2008-05-15 18:24 goldou[未注册用户]
大哥你太强了,希望还有心得可以分享。
 回复 引用