首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
如何在父协程或兄弟协程中杀死特定协程
### 问题描述 如果我检测到某个协程执行时间过长,想主动杀死他,怎么根据协程id杀死协程。在协程函数中只找到了获取协程信息的方法没有杀死的相关函数 ### Swoole版本,PHP版本,以及操作系统版本信息 ### 相关代码 ```php 请将代码粘贴至此处(请勿用截图) ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
发布于5年前 · 5 次浏览 · 来自
提问
云天001
### 问题描述 如果我检测到某个协程执行时间过长,想主动杀死他,怎么根据协程id杀死协程。在协程函数中只找到了获取协程信息的方法没有杀死的相关函数 ### Swoole版本,PHP版本,以及操作系统版本信息 ### 相关代码 ```php 请将代码粘贴至此处(请勿用截图) ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2021-03-18
鲁飞
暂不支持
赞
0
回复
2021-03-18
序冢
任何外部杀死线程的行为都是不合理的,取自陈硕的c++多线程网络编程。协程也是同样的道理。可以用数组建立一个协程池子,然后value是协程的标志位,如果父协程想杀死子协程,那么就把子协程的标志位设置为死亡,然后子协程处理完业务后检查这个标志位,如果子协程发现标志位是死亡,那么关闭当前正在阻塞的io套接字,进行自然死亡,这样就可以达到你说的效果了。不要在外部强制杀死子协程,这个方案本身就缺乏科学性,是不合理的. 详见我写的 终止apollo协程客户端代码: 首先创建一个父协程不停地管理服务的运行状态 ```php Coroutine::create(function () { while (SwooleProcessManager::getSyncPrimitive()->get()) { $coro = $this->pop(); /** * [[[@var ](/u/3588)](/u/3588)](/u/3588)$coro CoroData */ if ($coro) { $coro->handle->start($coro->callable, $coro->params); } Coroutine::sleep(0.001); } //关闭协程 $this->channel->close(); foreach ($this->pool as $worker) { /** * [[[@var ](/u/3588)](/u/3588)](/u/3588)$worker CoroData */ $worker->handle->stop(); $worker->callable->stop(); } }); ``` SwooleProcessManager::getSyncPrimitive()->get() 返回1 就代表服务正常运行,返回0就代表需要终止协程,停掉服务,注意停掉服务后,调用子协程的stop方法 ```php //关闭协程 $this->channel->close(); foreach ($this->pool as $worker) { /** * [[[@var ](/u/3588)](/u/3588)](/u/3588)$worker CoroData */ $worker->handle->stop(); $worker->callable->stop(); } ``` stop方法会回收协程内的套接字资源,并且将协程运行标志位设置为self::STOP,从而达到平滑停止协程的目的 ```php /** * 平滑终止swoole协程 */ public function stop() { $this->logger->log(LogLevel::INFO, "apollo client ". $this->appId . " stop"); //关闭日志 if ($this->logger) { $this->logger->stopBackgroundThread(); } $this->state = self::STOP; $this->httpClient->close(); } ```
赞
0
回复