在select的構(gòu)造函數(shù)中,有如下代碼
<?php
// Create a pipeline and put into the collection of the read to read the descriptor to avoid empty polling.
$this->channel = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
if ($this->channel) {
stream_set_blocking($this->channel, 0);
$this->_readFds = $this->channel;
}
?>
這個(gè)創(chuàng)造出來的一對(duì)套接字,一般是被用來進(jìn)行進(jìn)程間通信的,但是一般的使用方式是這樣
<?php
$sockets = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
/_ parent _/
fclose($sockets);
fwrite($sockets, "child PID: $pid\n");
echo fgets($sockets);
fclose($sockets);
} else {
/_ child _/
fclose($sockets);
fwrite($sockets, "message from child\n");
echo fgets($sockets);
fclose($sockets);
}
?>
使用一對(duì)套接字,在進(jìn)程分裂的時(shí)候每個(gè)進(jìn)程擁有其副本,然后互相發(fā)送,可以得到消息
但是workerman中的stream_socket_pair的創(chuàng)建是在子進(jìn)程分裂之后,的run中,才給每一個(gè)子進(jìn)程創(chuàng)建一對(duì)stream_socket_pair,而且只在_readFds中加入了channel的第一個(gè),另外一個(gè)不知道用到哪兒了,請(qǐng)問walkor老大,這樣做是什么目的啊,每看明白
stream_socket_pair 創(chuàng)建一個(gè)管道主要是給stream_select 用,避免stream_select空輪詢報(bào)錯(cuò)。
實(shí)際上這里stream_socket_pair創(chuàng)建的管道并不是為了通訊用。
以下代碼都出去 workerman Select.php loop函數(shù)
抱歉,老大,stream_select不是類似于socket_select嗎,在給定的timeout時(shí)間里面等待,您現(xiàn)在的代碼里面是這么寫的
$ret = stream_select($read, $write, $e, 0, $this->_selectTimeout);這就意味著根本不等待,直接返回,我理解這樣做是為了執(zhí)行$this->tick(); 如果一直等待下去,_scheduler中的時(shí)間就會(huì)過去,任務(wù)就會(huì)延遲執(zhí)行
那么如果不給那個(gè)_readFds[0],只不過是$ret為空,也就是下面回去執(zhí)行
if (!$ret) {
continue;
}
也是符合程序設(shè)想的流程的啊,避免空輪詢的目的是什么呢?
$ret = stream_select($read, $write, $e, 0, $this->_selectTimeout);
是等待 $this->_selectTimeout 這么多時(shí)間。stream_select不允許$read, $write, $e同時(shí)為空,否則會(huì)報(bào)錯(cuò)