關於php stream_select方法的研究理解
function stream_select (array &$read, array &$write, array &$except, $tv_sec, $tv_usec = null) {}
stream_select函數返回的條件爲:
- $read數組中的任何一個連接發生可讀事件
- $write數組中任何一個連接發生可寫事件
- $except數組中的任何一個連接有帶外數據到來(OOB)
- 當前進程收到系統信號(signal), 如:pcntl_alarm產生的鬧鐘信號,也就是說信號可以中斷stream_select的調用,使其立即返回
- stream_select阻塞等待時間超過($tv_sec+$tv_usec)的時間總值,如果$tv_sec=&null時,則無限阻塞直到上面4種返回條件中的任何一種發生了
返回值
- 返回值爲監聽的所有連接中發生狀態改變的連接數,比如當有3個連接發生可寫事件,導致方法返回,則返回值爲3(integer類型)
- 如果是被系統信號中斷返回值爲false並輸出警告(被信號中斷).
- 如果等待直到超時都沒任何事件發生,則返回0
關於帶外數據
- 帶外數據長度只支持1個字符,用於發生緊急的數據,比如暫停這類的功能,就是發生一個緊急字符優先發送到對端,進而緊急處理
stream_select是如何判斷連接可讀可寫的
- 每一個socket連接都有一個讀緩衝區(readBuffer)和一個寫緩衝區(writeBuffer). 每個緩衝區都有一個低水位標記. 接收緩存區低水位標記(用於判斷可讀)和發送緩存區低水位標記(用於判斷可寫)stream_select底層通過遍歷所有待監聽的socket連接,並通過下面的方式判斷每個連接的可讀可寫:
- 可讀: 當readBuffer中的數據量”大等於”接收低水位標記值時. 默認接收低水位標記值=1; 還有另一種情況發生可讀事件, 就是對端關閉連接時, 這時可以使用 !is_resource($fd) || feof($fd)==true 判斷連接已經斷開
- 可寫: 當writeBuffer中剩餘的可用空間”大等於”發送低水位標記值時, 默認發送低水位標記值=2048