swoole / rfc

Swoole 提案
116 stars 3 forks source link

RFC-1005 Process 管道显式设置阻塞或非阻塞 #5

Closed matyhtf closed 6 years ago

matyhtf commented 6 years ago

问题描述

底层在 process->write 是根据当前有没有 reactor 来判断是否启用非阻塞的,这个存在严重的问题。比如在 worker 进程中 write,就会用 reactor_write 异步发送,但是必须设置 pipe 为nonblock,如果 worker 进程中又有代码是阻塞循环 process->read ,那么就会出现死循环。

因此底层设计上根据当前进程是否有reactor的思路是存在缺陷的。

演示代码

$serv->on("WorkerStart", function () use ($process) {
    while(true) {
        //底层使用了`reactor_write`异步发送,会将该`socket`设置为非阻塞模式
        $process->write("hello");
        //这里会理解返回 false,错误码为 EAGAIN
        $msg = $process->read();
    }
});

问题解决

$serv->on("WorkerStart", function () use ($process) {
    //设置为阻塞模式
    $process->setBlocking(true);
    while(true) {
        $process->write("hello");
        $msg = $process->reqd();
    }
});
use Swoole\Event;
$serv->on("WorkerStart", function () use ($process) {
    //设置为非阻塞模式
    $process->setBlocking(false);
    Event::add($process->pipe, function () use ($process) {
        $msg = $process->read();
    });
});