PHP生成器(generator)和协程的实现方法详解
本篇章节讲解PHP生成器(generator)和协程的实现方法。分享给大家供大家参考,具体如下: 先说一些废话 PHP 5.5 以来,新的诸多特性又一次令 PHP 焕发新的光彩,虽然在本文写的时候已是 PHP 7 alpha 2 发布后的一段时间,但此时国内依旧是 php 5.3 的天下。不过我认为新的特性迟早会因为旧的版本的逐渐消失而变得越发重要,尤其是 PHP 7 的正式版出来后,因此本文的目的就是为了在这之前,帮助一些 PHPer 了解一些他们从没有了解的东西。所以打算将以本篇作为博客中 PHP 知识补全 系列文章的开篇。 其实在写本文之前,我对生成器以及基于此特性延伸出来的 php 的协程实现并没有比较直观的了解,主要是我个人水平并不是很高,属于典型的刚入了门的 PHPer。所以在看了前段时间鸟哥(laruence)博客中对协程的讲解(参考链接:《》)后,在我个人对本篇的理解上,针对那些比较难以理解的概念(包括我个人在理解这一概念的时候的难点),以一个更为通俗的方式去讲明白。当然由于本人也是刚刚去学习这一概念,所以有些不得当的地方在所难免,希望大神看见了请不吝赐教。
为便于新入门开发者理解,本文一半篇幅是讲述迭代器接口(Iterator)和 Generator 类的,对此已经理解的话,可以直接跳过。 1 0 3 2 5 4 7 6 9 8 11 10 PHP 官方文档这样说的:
官方文档给了上文对应的例子,我们在此简化了一下: $i; // 关键字 yield 表明这是一个 generator
}
}
// 我们可以这样调用
foreach (xrange(0,$value);
}
可能你已经发现了,这个例子的输出和我们前面在说 迭代器的时候那个例子结果一样。实际上生成器生成的正是一个迭代器对象实例,该迭代器对象继承了 Iterator 接口,同时也包含了生成器对象自有的接口,具体可以参考Generator 类的定义。
我们需要注意的关键是 我们也可以发现,yield 和 return 都会返回值,但区别在于一个 return 是返回既定结果,一次返回完毕就不再返回新的结果,而 yield 是不断产出直到无法产出为止。 实际上存在 yield 的函数返回值返回的是一个 这个对象不能手动通过 new 实例化),该对象实现了Iterator 接口。那么 Generator 自身有什么独特之处?继续看:
yield 字面上解释,yield 代表着让位、让行。正是这个让行使得通过 yield 实现协程变得可能。
yield 和 return 的区别,前者是暂停当前过程的执行并返回值,而后者是中断当前过程并返回值。暂停当前过程,意味着将处理权转交由上一级继续进行,直至上一级再次调用被暂停的过程,该过程则会从上一次暂停的位置继续执行。这像是什么呢?如果读者在读本篇文章之前已经在鸟哥的文章中粗略看过,应该知道这很像是一个操作系统的进程调度管理,多个进程在一个 CPU 核心上执行,在系统调度下每一个进程执行一段指令就被暂停,切换到下一个进程,这样看起来就像是同时在执行多个任务。
send('hello');
$printer->send('world');
上述例子输出内容为:
我们通过之前也了解了一个问题,yield 可以在其位置中断并返回一个值,那么能不能同时进行 接收和返回呢?当然,这可是实现协程的根本。我们对上述代码做出修改:current());
$printer->send('hello');
printf("%dn",$printer->current());
$printer->send('world');
printf("%dn",$printer->current());
输出内容如下:
上述例子已经足以表示 yield 在那一个位置作为双向传输的 工具,已具备实现协程的条件。协程 这一部分我不打算长篇大论,本文开头已经给出了鸟哥博客中更为完善的文章,本文的目的是出于补充对 Generator 的细节。 我们要知道,对于单核处理器,多任务的执行原理是让每一个任务执行一段时间,然后中断、让另一个任务执行然后在中断后执行下一个,如此反复。由于其执行切换速度很快,让外部认为多个任务实际上是 “并行” 的。 鸟哥那篇文章这么说道:
我们结合之前的例子,可以发现, 这样的功能对于读写和操作 Stream 资源时尤为重要,我们可以极大的提高程序对于并发流资源的处理能力,比如实现 tcp server。以上在 《》 有更为详尽的例子。本文不再赘述。 总结 PHP 自 5.4 到如今愈发稳定的 PHP 7,可以看到许多的新特性令这门语言愈发强大和完善,逐渐从纯粹的 Web 语言变得有着更为广泛的适用面,作为一枚 PHPer 的确不应当止步不前,我们依然有很多的东西需要不断学习和加强。 虽然 “PHP 是世界上最好的语言” 这句话只是个调侃,但不可否认 PHP 即使不是最好,但也在努力变好的事实,对吧? 更多关于PHP相关内容感兴趣的读者可查看本站专题:《》、《》、《》、《》及《》 希望本文所述对大家PHP程序设计有所帮助。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
foreach
对数组遍历并迭代输出其内容。在这一环节中,我们需要关注的重点是数组。虽然我们迭代的过程是 foreach
语句中的代码块,但实际上数组 $mapping
在每一次迭代中发生了变化,意味着数组内部也存在着一次迭代。如果我们把数组看做一个对象,foreach 实际上在每一次迭代过程都会调用该对象的一个方法,让数组在自己内部进行一次变动(迭代),随后通过另一个方法取出当前数组对象的键和值。这样一个可通过外部遍历其内部数据的对象就是一个迭代器对象,其遵循的统一的访问接口就是迭代器接口(Iterator
)。