/Workerman-master/Events/select.php中的channel

haotian

在select的构造函数中,有如下代码

<?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;
        }
?>

这个创造出来的一对套接字,一般是被用来进行进程间通信的,但是一般的使用方式是这样

<?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);
}
?>

使用一对套接字,在进程分裂的时候每个进程拥有其副本,然后互相发送,可以得到消息
但是workerman中的stream_socket_pair的创建是在子进程分裂之后,的run中,才给每一个子进程创建一对stream_socket_pair,而且只在_readFds中加入了channel的第一个,另外一个不知道用到哪儿了,请问walkor老大,这样做是什么目的啊,每看明白

3179 2 0
2个回答

walkor

stream_socket_pair 创建一个管道主要是给stream_select 用,避免stream_select空轮询报错。
实际上这里stream_socket_pair创建的管道并不是为了通讯用。

  • haotian 2017-03-15

    以下代码都出去 workerman Select.php loop函数
    抱歉,老大,stream_select不是类似于socket_select吗,在给定的timeout时间里面等待,您现在的代码里面是这么写的
    $ret = stream_select($read, $write, $e, 0, $this->_selectTimeout);这就意味着根本不等待,直接返回,我理解这样做是为了执行$this->tick(); 如果一直等待下去,_scheduler中的时间就会过去,任务就会延迟执行
    那么如果不给那个_readFds[0],只不过是$ret为空,也就是下面回去执行
    if (!$ret) {
    continue;
    }
    也是符合程序设想的流程的啊,避免空轮询的目的是什么呢?

  • haotian 2017-03-15

    还是说,是为了不然几个流$read, $write 沦为空数组?避免空轮询?

  • walkor 2017-03-15

    $ret = stream_select($read, $write, $e, 0, $this->_selectTimeout);
    是等待 $this->_selectTimeout 这么多时间。stream_select不允许$read, $write, $e同时为空,否则会报错

  • haotian 2017-03-15

    @1:谢谢老大 明白了

damao

学习了

  • 暂无评论
年代过于久远,无法发表回答
🔝