我需要等待一些东西从文件描述符A中读取,然后仅在文件描述符B可写时才读取它。
我的第一个实现是这样的(伪代码):

while (true) {
  select(A readable, B writeable, timeout)
  if (A was readable and B was writeable) {
    ReadFromAWriteToB();
  }
}

这有一个问题,其中一种情况发生,select马上返回。这是一个问题,因为A可以说10%的时间是可读的,但是B可以说90%的时间是可写的,因此即使我们通常没有从A读取的任何数据,它也会唤醒写入B。

我的下一个实现是这样的:
while (true) {
  select(A readableB, timeout);
  if (A was readable) {
    select(B writeable, 0); // Check if it is writeable right now
    if (B was writeable) {
      ReadFromAWriteToB();
    }
  }
}

这样比较好,但是我到达了可以读取A的峰值,因此第一个选择立即返回,但是B不可写,因此我将陷入繁忙的循环,直到B再次可写为止。

因此,我可以在第二个选择中添加一小段等待时间,例如1毫秒。
我真正想做的是选择/轮询,直到两个条件都有效为止,而不仅仅是一个或两个条件都有效,但我认为选择/轮询不支持这一点。
是否有更好的API可以使用或有更好的方法来构造此循环?

最佳答案

在发现B不可写之后增加睡眠呢?

while (true) {
  select(A readableB, timeout);
  if (A was readable) {
    select(B writeable, 0); // Check if it is writeable right now
    if (B was writeable) {
      ReadFromAWriteToB();
    }
    else {
      sleep for an appropriate amount of time
    }
  }
}

这将:
  • 防止当A准备好而B不是
  • 时出现紧密循环
  • 确保在检查B之前总是对A进行全新检查

  • 如果我们在找到A准备就绪后可以等待无限制的时间,则可以这样重写循环:
    while (true) {
      select(A readableB, timeout);
      if (A was readable) {
        b_timeout = 0
        while true {
          select(B writeable, b_timeout); // Check if it is writeable right now
          if (B was writeable) {
            ReadFromAWriteToB();
            break;
          }
          sleep for a small amount of time to prevent tight loop around B
          b_timeout += a few milli seconds
        }
      }
    }
    

    这将
  • 防止像先前解决方案
  • 中的紧密循环
  • 减少发现A就绪后我们检查A的次数

  • 希望这是有道理的。

    关于linux - 等待可读的文件描述符和可写的文件描述符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42015120/

    10-12 22:19