2017-02-03 224 views
2

我需要等待某些內容從文件描述符A中讀取,然後只在文件描述符B可寫時纔讀取它。 我的第一個執行是這樣的(僞):等待可讀文件描述符和可寫文件描述符

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

這有這樣的選擇,一旦發生的條件之一返回的問題。這是一個問題,因爲A是可讀的,說10%的時間,但B是可寫的,說90%的時間,所以它會醒來寫給B,即使我們通常沒有任何數據要從A讀取。

我的下一個執行是這樣的:

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毫秒。 我真正想要做的是select/poll,直到兩個條件都有效,而不僅僅是一個或另一個,但我不認爲select/poll支持這個。 有沒有更好的API使用或更好的方式來構建這個循環?

回答

2

如何在發現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不是
  • 確保我們始終做一個新鮮的檢查檢查乙

前如果我們可以在找到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準備

希望這是有道理的。

+0

您可以簡化第二個例子,只需選擇帶有永遠等待的NULL超時。 – pilkch

+1

另一種選擇是在選擇可寫入中使用短暫超時以避免睡眠。我想我會在我的項目中使用這個選項。感謝您與我一起努力! – pilkch