5

您好我正在寻找一种在 php 文件中实现协程的方法。这个想法是我有很长的流程,需要能够在可能的几个小时或几天内产生结果。因此,其他 php 文件将调用与协程相同的文件中的函数来更新某些内容,然后调用类似的函数$coroutine.process()会导致协程从其最后一次产量继续。这是为了避免必须使用大型状态机。

我在想协程 php 文件在空闲时实际上不会运行,但是当给定处理时间时,它将从顶部进入并使用 switch 或 goto 之类的东西从以前的产量重新启动。然后,当它达到下一个产量时,文件会将其当前状态保存在某处(如会话或数据库),然后退出。

有没有人听说过这个,或者类似的比喻?以某种方式在一个集合下聚合和管理多个协程的奖励积分,也许支持类似线程的连接,以便在它们完成时流在一个地方继续(有点像 Go)。

更新:php 5.5.0 增加了对生成器和协程的支持:

https://github.com/php/php-src/blob/php-5.5.0/NEWS

https://wiki.php.net/rfc/generators

我还没有尝试过,所以也许有人可以提出一个准系统的例子。我正在尝试将状态机转换为协程。因此,例如,for 循环中的 switch 命令(其流程难以遵循,并且随着添加更多状态而容易出错)转换为协作线程,其中每个决策点在有序的线性流程中很容易看到,该流程暂停yield 关键字的状态变化。

一个具体的例子是,假设你正在编写一个电梯控制器。不是根据电梯的状态(STATE_RISING、STATE_LOWERING、STATE_WAITING 等)确定是否读取按钮的状态,而是编写一个带有子循环的循环,该循环在电梯处于每种状态时运行。所以当它上升时,它不会下降,它不会读取除紧急按钮之外的任何按钮。这可能看起来没什么大不了的,但在像聊天服务器这样的复杂状态机中,几乎不可能在不引入细微错误的情况下更新状态机。而协作线程(协程)版本具有明显可见的流程,更易于调试。

4

3 回答 3

3

Swoole 协程库为 PHP 提供了类似 go 的协程。每个协程每个进程只增加 8K 的内存。它提供了一个协程 API 以及预期的基本功能(如 yield 和 resume)、coro 实用程序(如协程迭代器)以及更高级别的协程内置函数,如文件系统函数和网络(socket 客户端和服务器、redis 客户端和服务器、MySQL客户端等)。

您问题的第二个要素是拥有长期协同程序的能力 - 除非您在会话中保存 coro 的状态并允许 coro 结束/关闭,否则这可能不是一个好主意。否则,请求将必须与协程一样长。如果服务由长期存在的 PHP 脚本托管,则场景更容易,协程将简单地存在,直到它被允许/强制关闭。

Swoole 的性能与 Node.js 和基于 Go 的服务相当,并用于定期托管 500K+ TCP 连接的多个生产服务中。它是 PHP 鲜为人知的瑰宝,主要是因为它是在中国开发的,大多数支持和文档仅限于说中文的人,尽管少数人努力帮助说其他语言的人。

Swoole 的一个优点是它的 PHP 类包装了一个扩展的 C/C++ api,从一开始就允许它的所有功能在没有 PHP 的情况下使用。相同的源代码可以很容易地编译为 PHP 扩展和/或 *NIX 系统和 Windows 的标准库。

于 2018-11-30T05:07:40.510 回答
2

PHP 不支持协程。

我会用 编写一个 PHP 扩展setcontext(),当然假设您的目标是 Unix 平台。

这里有一个关于 PHP 扩展入门的 StackOverflow 问题: PHP 扩展开发入门。

为什么setcontext()setcontext()可用于协程是一个鲜为人知的事实。调用另一个协程时只需交换上下文。

于 2012-10-17T16:54:35.720 回答
0
于 2012-10-19T21:28:26.517 回答