0

我有一个从套接字接收数据的函数,我需要在 5 秒后停止函数而不创建额外的线程。我的代码:

void TestReceive()
{
 //how to stop code below when 5 second passed&
 size_t received = 0;
 while (received < 4)
 {
  ssize_t r = read(fd, buffer, 4);
  if (r <= 0) break;
  received += r;
 }
}
4

4 回答 4

2

使用 select(),这将阻塞,直到可以读取某些内容或最多在 timeval 中指定的时间,如下所示。

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

select() 不会读取或写入,它的作用是针对一组描述符(readfds、writefds 和/或exceptfds),它将等待/阻塞,直到发生以下情况之一:

  • 有一个可供读取的描述符
  • 有一个准备写入的描述符
  • 其中一个描述符有异常,就像它已关闭一样
  • 如果指定了超时,则当配置的时间到期时

如果您只需要“等待”(睡眠)5 秒钟,然后读取,您可以睡眠(usleep()在 linux 上)5 秒钟,然后通过设置套接字选项或调用 select() 进行非阻塞读取最小超时并检查是否有要读取的内容。

这是一个相关的问题。C++ select() 函数如何在 Unix 操作系统中工作?

于 2012-05-30T13:03:11.537 回答
1

正如@Brady 建议的那样, select() 将起作用

您还可以设置套接字选项 setsockopt(s, SOL_SOCKET, SO_RCVTIMEO ...

于 2012-05-30T13:08:56.617 回答
0

记录循环开始前的当前时间。在每次迭代中 - 检查是否已经过了 5 秒 - 如果是 -中断;

于 2012-05-30T13:06:06.817 回答
0

我会推荐以下方法:

  • 将当前时间测量为 var 说 startTime;
  • 环形
  • 使用超时(选择)从您的套接字读取。让超时为startTime + 5 秒 - 现在
  • 迭代直到超时匹配(或超时很少应用)

这种方法使用超时而不是单独的线程

于 2012-05-30T13:45:05.633 回答