首页
下载
文档
问答社区
视频
捐赠
源代码
AI 助理
赞助商
CRMEB
Apipost
腾讯云
微擎
禅道
51Talk
商业产品
Swoole AI 智能文档翻译器
Swoole-Compiler PHP 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
多协程之间共用php对象变量
### 问题描述 需求: 1,并行处理列表数据 2,列表中每条数据有多个不同规则进行判断处理 如下代码中的processList,process函数在多个协程之间使用同一个php对象变量是否会有问题。 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole 4.5.7 php7.2 centos 7 easyswoole 3.3.7 ### 相关代码 ```php <?php class ProcLogic { use Singleton; private $rules = [ ['method' => 'rule1', 'name' => 'rule1'], // 规则1 ['method' => 'rule2', 'name' => 'rule2'], // 规则2 ['method' => 'rule3', 'name' => 'rule3'], // 规则3 ]; // 列表处理 public function processList($list = []) { if (empty($list) || !is_array($list)) { return []; } $wg = new \Swoole\Coroutine\WaitGroup(count($list)); $curObj = $this; $result = []; foreach ($list as $item) { $wg->add(); \Swoole\Coroutine::create(function() use($wg, $curObj, $item, &$result) { $result[$item['id']] = call_user_func_array([$curObj, 'process'], [$item]); $wg->done(); }); } $wg->wait(); foreach ($list as $key => $value) { $id = $value['id']; $list[$key]['rule_result'] = $result[$id][$id] ?? []; } return $list; } // 单条多规则处理 public function process($item = []) { $wg = new \Swoole\Coroutine\WaitGroup(count($this->rules)); $curObj = $this; $result = []; foreach ($this->rules as $value) { $method = $value['method']; $name = $value['name']; $wg->add(); \Swoole\Coroutine::create(function() use($wg, $curObj, $method, $item, $name, &$result) { $result[$item['id']][$name] = call_user_func_array([$curObj, $method], [$item]); $wg->done(); }); } $wg->wait(); return $result; } // rule1 public function rule1($data = []) { $return = []; // db查询 (多协程环境连接共用已处理好) // ... // 返回结果 return $return; } // rule2 public function rule2($data) { $status = $data['use_status']; $return = [ 'use_status' => $status, 'use_status_txt' => $status == 1 ? 'ok' : '不可拆分', ]; return $return; } // rule3 public function rule3($data) { $return = []; // redis查询 (多协程环境连接共用已处理好) // ... // 返回结果 return $return; } } // 调取 $list = [ ['id' => 1, 'xx' => 'xx', 'yy' => 'yy'], ['id' => 2, 'xx' => 'xx', 'yy' => 'yy'], ]; $return = ProcLogic::getInstance()->processList($list); var_dump($return); ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 目前自测运行正常 请教在多协程之间使用同一个php对象($this)会不会有什么问题?
发布于3年前 · 54 次浏览 · 来自
讨论
index.php
### 问题描述 需求: 1,并行处理列表数据 2,列表中每条数据有多个不同规则进行判断处理 如下代码中的processList,process函数在多个协程之间使用同一个php对象变量是否会有问题。 ### Swoole版本,PHP版本,以及操作系统版本信息 swoole 4.5.7 php7.2 centos 7 easyswoole 3.3.7 ### 相关代码 ```php <?php class ProcLogic { use Singleton; private $rules = [ ['method' => 'rule1', 'name' => 'rule1'], // 规则1 ['method' => 'rule2', 'name' => 'rule2'], // 规则2 ['method' => 'rule3', 'name' => 'rule3'], // 规则3 ]; // 列表处理 public function processList($list = []) { if (empty($list) || !is_array($list)) { return []; } $wg = new \Swoole\Coroutine\WaitGroup(count($list)); $curObj = $this; $result = []; foreach ($list as $item) { $wg->add(); \Swoole\Coroutine::create(function() use($wg, $curObj, $item, &$result) { $result[$item['id']] = call_user_func_array([$curObj, 'process'], [$item]); $wg->done(); }); } $wg->wait(); foreach ($list as $key => $value) { $id = $value['id']; $list[$key]['rule_result'] = $result[$id][$id] ?? []; } return $list; } // 单条多规则处理 public function process($item = []) { $wg = new \Swoole\Coroutine\WaitGroup(count($this->rules)); $curObj = $this; $result = []; foreach ($this->rules as $value) { $method = $value['method']; $name = $value['name']; $wg->add(); \Swoole\Coroutine::create(function() use($wg, $curObj, $method, $item, $name, &$result) { $result[$item['id']][$name] = call_user_func_array([$curObj, $method], [$item]); $wg->done(); }); } $wg->wait(); return $result; } // rule1 public function rule1($data = []) { $return = []; // db查询 (多协程环境连接共用已处理好) // ... // 返回结果 return $return; } // rule2 public function rule2($data) { $status = $data['use_status']; $return = [ 'use_status' => $status, 'use_status_txt' => $status == 1 ? 'ok' : '不可拆分', ]; return $return; } // rule3 public function rule3($data) { $return = []; // redis查询 (多协程环境连接共用已处理好) // ... // 返回结果 return $return; } } // 调取 $list = [ ['id' => 1, 'xx' => 'xx', 'yy' => 'yy'], ['id' => 2, 'xx' => 'xx', 'yy' => 'yy'], ]; $return = ProcLogic::getInstance()->processList($list); var_dump($return); ``` ### 你期待的结果是什么?实际看到的错误信息又是什么? 目前自测运行正常 请教在多协程之间使用同一个php对象($this)会不会有什么问题?
赞
0
分享
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
评论
2021-06-17
Rango
这个会有上下文问题,当一个协程在使用该全局变量期间,如果发生了挂起,可能这个变量会被另外一个协程所修改,如果你的程序处理了这种情况,能够按照预期的逻辑执行就没问题。 ```php go(function() { $GLOBALS['a'] = 1; Co::sleep(0.1); // 这里 $GLOBALS['a'] 可能就不是 1 了,有可能被其他协程修改 var_dump($GLOBALS['a']); }); ``` 你需要考虑到协程切换的可能性。
赞
0
回复
2021-06-17
index.php
回复
Rango
多谢Rango回复 程序内多个rule函数中未使用修改变量操作,更多是从db,redis获取数据查询操作。
赞
0
回复
微信公众号
热门内容
暂无回复的问答
- CodeGalaxy K3s 轻量集群节点之间如何实现负载均衡
- 关于openssl CURL WARNING swSSL_connect: SSL_connect(fd=69) failed. Error: error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small[1|394]
- 多个模型如何进行事务异常回退?
- websocket开启wss报错
- 协程tcp服务器如何使用多进程?recv()方法接收信息,打印出来的pid一直是同一个。没用使用到多进程啊。