关于 PHP pthreads 跨线程变量传递

写了一个 PHP 多线程聊天服务器,在实现接收到客户端消息后将消息广播到所有客户端这个功能时,卡住了

问题在于没法将客户端列表 $list 传递给 thread 内部,run 方法调用出错。

PHP Fatal error: Uncaught RuntimeException: Threaded members previously set to Threaded objects are immutable, cannot overwrite clients in /root/SocketServer.php:25
Stack trace:
#0 /root/SocketServer.php(178) : eval()'d code(1): Client->setClient(Array)
#1 /root/SocketServer.php(178): eval()
#2 {main}
thrown in /root/SocketServer.php on line 25

Fatal error: Uncaught RuntimeException: Threaded members previously set to Threaded objects are immutable, cannot overwrite clients in /root/SocketServer.php:25
Stack trace:
#0 /root/SocketServer.php(178) : eval()'d code(1): Client->setClient(Array)
#1 /root/SocketServer.php(178): eval()
#2 {main}
thrown in /root/SocketServer.php on line 25

一开始我的方法是这样的:

while(($client = socket_accept($server))) {
    $Handler = new Client($client); // 将新连接进来的客户端交给 Thread 处理
    $clients[] = $Handler; // 在 Thread 列表中添加一个新的 Thread 对象,即 Handle
    $list[] = $client; // 在客户端列表中新增一个 resource 类型的 Socket 客户端
    foreach($clients as $c) {
        $c->clients = $list; // 递归 Thread 列表,将每个 Thread 的客户端列表更新一次
    }
}

然后在 run() 方法里这样写

// 在接收到消息后,把消息广播给列表里的所有客户端
foreach($this->clients as $c) {
    socket_write($c, $data['msg'] . "\n");
}

看起来没有任何问题,可是它居然报错了

在咕鸽查了一下,貌似是说 Thread 类在实例化了以后就不能再从外部改变内部的变量???

后来我还尝试了 global 全局变量,序列化存到文件(后来发现不支持 resource 类型),eval 动态执行赋值等等方法,但是最终都没有成功。

放弃,我还是去写单线程 Socket 服务器吧 Orz

PS:Swoole 是个好东西

推荐阅读文章

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注