【问题标题】:tiemout for a function that waits indefiinitely (like listen())无限期等待的函数超时(如listen())
【发布时间】:2011-02-05 16:00:44
【问题描述】:

我不太确定是否可以做我要问的事情,所以我想我会问。

我有一个多线程程序,其中线程共享一个内存块来传递必要的信息。其中一个信息是线程终止,其中线程不断检查此值,当值更改时,它们知道是pthread_exit() 的时间了。其中一个线程包含listen() 函数,它似乎无限期地等待。如果没有人想要建立连接并且线程需要退出但它无法检查线程是否需要终止的值,因为它卡在listen() 上并且无法移动,这可能会出现问题。

while(1)
{
  listen();
  ...
  if(value == 1)
    pthread_exit(NULL);
}

如果它有助于更​​好地说明我的观点,我的逻辑就是这样。我认为可以解决问题的是允许 listen() 等待一段时间,如果没有任何反应,它会继续执行下一条语句。不幸的是,listen() 的两个参数都没有涉及时间限制。我什至不确定我是否正在采用正确的多线程编程方式,我一点经验都没有。那么这是一个好方法吗?也许有更好的方法来解决它?感谢任何有见地的 cmets。

编辑:澄清一点,listen() 在 while 循环中的原因是这是一个服务器,一次将连接到多个客户端。

【问题讨论】:

  • 您只需调用一次listen(),然后在循环中调用accept()accept() 是阻止的,所以请参阅下面的一些好的回复,建议使用 select()/poll()
  • 感谢您解决这个问题。我阅读了select()/poll(),但我还有更多问题。下面的人(nos & slacker)说listen() 将套接字标记为就绪。除了将其标记为被动之外,还有更多的意义吗?那么它是如何跟踪积压的呢?我认为您的建议是当 select()/poll() 返回有一个要读取的套接字时会调用 accept() 吗?你能推荐任何关于这个主题的网络文献吗?我已经阅读了 opengroup 手册和 beej 的指南等。非常感谢!

标签: c multithreading time listen


【解决方案1】:

您可以将套接字设置为非阻塞,并使用 select/poll 或类似方法等待事件 - select/poll 允许您设置超时。

请注意,listen() 不会阻塞,它只是标记套接字准备好处理传入的连接 - accept() 将是下一步,它会阻塞。

【讨论】:

  • 我认为 listen() 正在等待传入连接?我正在使用 select() 来检查来自多个套接字的数据包(因为这是针对服务器的,并且将有多个客户端尝试连接)并且那是针对已经建立的连接。
  • @Fantastic Fourier: 不,listen() 仅将套接字标记为被动“监听”套接字,并立即返回。您必须稍后调用accept() 来创建真正的连接(如果侦听套接字阻塞,则可能会阻塞)。
  • 抱歉,我认为我的理解不太正确。我知道我在 listen() 返回后使用了 accept() 。如果我要使用 select/poll,我应该区分新接收到的数据是否来自新连接,然后使用 accept() 进行新连接?
  • 是的。将监听socket添加到select()中设置的readfds,如果在select()返回时设置了,那么就可以调用accept()了。
【解决方案2】:

IIRC你需要用setsockopt()设置超时,在listen()失败后检查errno看看是超时还是严重错误。

在我看来,如果您总是使用相同的连接套接字,那么只调用一次listen() 似乎是可行的。 但也许你对accept() 也会有同样的问题。

【讨论】:

  • 问题是这是一个服务器程序,正在等待(通过listen())尚未建立的传入客户端连接(并将使用accept()建立)
【解决方案3】:

您应该从另一个线程(将值更改为 1 的线程)发送一个信号。它将使监听函数返回 EINTR 错误代码。

【讨论】:

  • 就我个人而言,我不会用信号使事情复杂化,单独线程已经够难了。
  • 对不起,我对多线程比较缺乏经验,我将如何在线程之间发送信号?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 2012-05-12
相关资源
最近更新 更多