重新启动套接字编程select()中的定时器
Restart the timer in select() of socket programming
我想使用select()来接收来自其他服务器的更新,并定期发送消息。考虑以下设置:
, (1) {选择(…Timeout = 5秒);//其他代码}
如果我在t = 2秒收到update,那么select()将返回并执行相应的语句。当下一个循环开始时,timeout将再次设置为5秒。但是,它应该是5 - 2 = 3秒。是否有一种方法来更新计时器与正确的时间?
我想在select()之前手动启动一个计时器,但是这个计时器可能与select()中使用的计时器不同步。并且会引起其他潜在的问题。
根据select
手册页:
在Linux上,
select()
修改timeout以反映未休眠的时间;大多数其他实现都不这样做。(POSIX.1-2001允许任意一种行为)
因此,您只需重用timeout
变量。只有当你真的超时时,你才会重置它的值。
正如警告所示,依赖于此行为会导致移植问题,因此,如果您依赖于此行为,请确保将其记录下来,以便在移植代码时做正确的事情。
在调用select()
之前记住变量中的time()
,当select()
返回时获得另一个time()
,然后…在下一次while(1)
迭代中,使用5 - difference_between_times
而不是5
作为超时值。
也许你想使用new_timeout = 5 - difference_between_times % 5
,所以如果你的操作在select
返回后需要超过5秒…你仍然设置timeout
在5秒的间隔。
您可能不应该使用秒,而应该使用更细粒度的时间单位。并考虑以上是否是你真正想要的行为(用模)。也许当difference_between_times > 5
,你应该等待5秒。做你想做的,但你得到的想法。
当你的应用变得更复杂时,你可能会有多个定时器,它们具有不同的超时时间间隔。我们所做的。以下是我们的处理方法。
每个计时器都有一个计时器对象,其time_t表示计时器何时到期。我们将所有计时器存储在堆数据结构中,因此最快到期的计时器位于堆的根。在执行select()之前,我们获取堆的根,并从计时器的过期时间中减去当前时间,并使用该增量作为select()调用的超时。
Timer * t = heap->Root();
time_t now = time(0);
timeval tv;
tv.tv_sec = t->when - now;
tv.tv_usec = 0;
select( ... & tv );
- 当套接字连接断开时检测C/C++Unix
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何通过套接字将文本文件的内容从服务器发送到客户端
- 如何在C/C++中用FD_set Unix设置套接字文件描述符
- 套接字读取后,我在缓冲区中看到意外输入
- 套接字连接"Operation not permitted"错误,甚至使用升压/平发器根.cpp
- 在网络套接字计时器滴答后增加asio短读错误
- 如何从 boost::asio::ssl::stream<boost::asio::ip::tcp::socket> 获取本机套接字文件描述器?
- C++ 套接字侦听器 accept() 在发布时不接受连接请求
- C 套接字误差(新的初始器表达式列表被视为复合表达式)
- IPv6 和 IPv4 的套接字侦听器
- 我正在尝试用 DevC++ 编译一个套接字程序,但每次我这样做时,我都会收到很多链接器错误,如下所示:
- C++套接字客户端/服务器简单消息发送器
- C++套接字编程,带压缩的多播,任何好的库/包装器
- 非本地 IP 的套接字侦听器不起作用
- Boost Asio-使用shared_ptr处理解析器和套接字
- c侦听器与winsock-sender dll之间的套接字通信
- 如何在不相互阻塞的情况下使用套接字和计时器
- 重新启动套接字编程select()中的定时器
- 我是否正确使用GMFBridge. dll和GMFBridge播放器,GMFBridge播放器是否可以从套接字获取数据