Workerman globalEvent 全局变量疑问
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();本身就是不被允许的呢?
1个回答
年代过于久远,无法发表回答
Worker::$globalEvent 直接在业务中用,不用也不能初始化
这时候能不能通过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();就好了。
这代码都好几年了,你让我想其中细节我也记不起来了,可能是当时版本主进程会创建eventLoop,也可能是为了做单元测试吧,
这样修复下:
Master 里面写:
if( static::$globalEvent instanceof EventInterface) {
$eventloop = static::$globalEvent;
static::$eventloopClass = get_class($evnetloop);
static::$globalEvent = null;
}
子进程复制过来也是未初始化的globalEvent, 也会按照用户的事件驱动进行运行Workerman。
这样就兼容了这种错误写法,底层实现上规避这种问题。
看看提交个pr,能否合并呢,不能就关闭就是啦。
提交吧
已提交pr