Workerman globalEvent 全局变量疑问

meows

globalEvent 全局变量疑问

//// 这时候已经初始化操作
Worker::$globalEvent = new Event();

$worker = new Worker("http://0.0.0.0:8818");
$worker->count = 8;
$worker->reusePort = false;
Worker::runAll();
// Get column mapping for UI
foreach(static::getUiColumns() as $column_name => $prop){
    !isset($worker->{$prop}) && $worker->{$prop} = 'NNNN';
    $prop_length = \strlen((string) $worker->{$prop});
    $key = '_max' . \ucfirst(\strtolower($column_name)) . 'NameLength';
    static::$$key = \max(static::$$key, $prop_length);
}

// Listen.
if (!$worker->reusePort) {
    $worker->listen();
}

   /// 由于已经初始化,就能通过这里
   public function resumeAccept()
    {
        // Register a listener to be notified when server socket is ready to read.
        if (static::$globalEvent && true === $this->_pauseAccept && $this->_mainSocket) {
            if ($this->transport !== 'udp') {
                static::$globalEvent->add($this->_mainSocket, EventInterface::EV_READ, array($this, 'acceptConnection'));
            } else {
                static::$globalEvent->add($this->_mainSocket, EventInterface::EV_READ, array($this, 'acceptUdpConnection'));
            }
            $this->_pauseAccept = false;
        }
    }

// 但forkOneWorkerForLinux()看这里又是允许的
// Create a global event loop.
if (!static::$globalEvent) {
    $event_loop_class = static::getEventLoopName();
    static::$globalEvent = new $event_loop_class;
}

// Reinstall signal.
static::reinstallSignal();

//// 疑问:
因为master已经把mainSocket加入eventloop()了。
这时候globalEvent 已经被初始化,多个worker 进程会拷贝master的已经加入eventloop数据,这样不会出现问题?
//// 文档讲解了作用: https://www.workerman.net/doc/workerman/worker/global-event.html
/// 还是说我这种用法Worker::$globalEvent = new Event();本身就是不被允许的呢?
417 1 0
1个回答

walkor

Worker::$globalEvent 直接在业务中用,不用也不能初始化

  • meows 2023-10-14

    这时候能不能通过Master 去检测用户是否已经这样使用:
    Worker::$globalEvent = new Event();

    $worker = new Worker("http://0.0.0.0:8818");
    $worker->count = 8;
    $worker->reusePort = false;
    Worker::runAll();

    直接把他在master里面 static::$globalEvent = null;
    这样的话就从实现上面规避这种不被允许的用法呢?
    子进程就算拷贝过来也还是null,这样worker进程自己new Eventloop();就好了。

  • walkor 2023-10-14

    这代码都好几年了,你让我想其中细节我也记不起来了,可能是当时版本主进程会创建eventLoop,也可能是为了做单元测试吧,

  • meows 2023-10-14

    这样修复下:
    Master 里面写:

    if( static::$globalEvent instanceof EventInterface) {
    $eventloop = static::$globalEvent;
    static::$eventloopClass = get_class($evnetloop);
    static::$globalEvent = null;
    }

    子进程复制过来也是未初始化的globalEvent, 也会按照用户的事件驱动进行运行Workerman。
    这样就兼容了这种错误写法,底层实现上规避这种问题。
    看看提交个pr,能否合并呢,不能就关闭就是啦。

  • walkor 2023-10-14

    提交吧

  • meows 2023-10-15

    已提交pr

🔝