首页
下载
文档
问答社区
视频
捐赠
源代码
AI 助理
赞助商
CRMEB
Apipost
腾讯云
微擎
禅道
51Talk
商业产品
Swoole AI 智能文档翻译器
Swoole-Compiler PHP 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
如何在父协程或兄弟协程中杀死特定协程
### 问题描述 如果我检测到某个协程执行时间过长,想主动杀死他,怎么根据协程id杀死协程。在协程函数中只找到了获取协程信息的方法没有杀死的相关函数 ### Swoole版本,PHP版本,以及操作系统版本信息 ### 相关代码 ```php 请将代码粘贴至此处(请勿用截图) ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
发布于3年前 · 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
回复
微信公众号
热门内容
作者其它话题
- 定时任务里面如果有异常错误或退出 会被执行两次定时,并且如果在定时里面的添加的中断捕获,第二次报错时才能进入中断捕获
- 协程代码会阻塞 pcntl_signal 的异步信号监听
- 主进程和子进程之间如何传递文件描述符或者socket客户端
- 进程池 或者进程管理器中 如何对主进程设置信号监听
- 当swoole\Event 进行信号监听和 文件描述符监听时,信号监听无法触发,
暂无回复的问答
- 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一直是同一个。没用使用到多进程啊。