PHP协程内容的详解
内容导读
收集整理的这篇技术教程文章主要介绍了PHP协程内容的详解,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4577字,纯文字阅读大概需要7分钟。
内容图文
这篇文章给大家分享了关于php协成的内容,有一定的参考价值,希望可以帮助到有需要的朋友。概念
咱们知道多进程和多线程是实现并发的有效方式。但多进程的上下文切换资源开销太大;多线程开销相比要小很多,也是现在主流的做法,但其的控制权在内核,从而使用户(程序员)失去了对代码的控制,而且线程的上下文切换也是有一定开销的。 这时为了解决以上问题,"协程"(coroutine)的概念就产生了。你可以将协程理解为更轻量级的线程。这种线程叫做“用户空间线程“。协程,有下面两个特点:
协同。因为是由程序员自己写的调度策略,其通过协作而不是抢占来进行切换
在用户态完成创建,切换和销毁
PHP对协程的支持是在迭代生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数)。 这就把生成器到调用者的单向通信转变为两者之间的双向通信。
迭代器
迭代器的概念这里就不赘述了。下面看看我们自己实现的一个迭代器。
class MyIterator implements Iterator{ private $var = array(); public function __construct($array) { if (is_array($array)) { $this->var = $array; } } public function rewind() { // 第一次迭代时候会执行(或调用该方法的时候),后面的迭代将不会执行。 echo "rewindingn"; reset($this->var); } public function current() { $var = current($this->var); echo "current: $varn"; return $var; } public function key() { $var = key($this->var); echo "key: $varn"; return $var; } public function next() { // 最后执行,就是执行完下面sleep(2)后再执行。(执行了next本次迭代才算结束) $var = next($this->var); echo "next: $varn"; return $var; } public function valid() { // 当valid返回false的时候迭代结束 $var = $this->current() !== false; echo "valid: {$var}n"; return $var; }}$values = array(1,2,3,4);$it = new MyIterator($values);foreach ($it as $a => $b) { // 进行迭代(每次迭代,会依次执行以下方法: rewind(特别之处见上面解释), valid, current, key, next) print "=====n"; sleep(2);}
输出:
rewindingcurrent: 1 // 因为valid里面调用了current, 这里current出来一次valid: 1current: 1key: 0=====next: 2current: 2valid: 1current: 2key: 1=====next: 3current: 3valid: 1current: 3key: 2=====next: 4current: 4valid: 1current: 4key: 3=====next: current: valid: // valid返回false,迭代结束
生成器
有了yeild的方法就是一个生成器(生成器实现了Iterator接口,即一个生成器有迭代器的特点)。生成器的实现如下:
function xrange($start, $end, $step = 1) { for ($i = $start; $i <= $end; $i += $step) { echo $i . "n"; yield; }}// foreach方式foreach (xrange(1, 10) as $num) { }$gene = xrange(1, 10); // gene就是一个生成器对象// current$gene->current(); // 打印1// next$gene->next();$gene->current() // 打印2
输出:
1234567891012
注意:
生成器不能像函数一样直接调用,调用方法如下:
1. foreach他
2. send($value)
3. current / next...
yield
yield的语法很灵活,我们用下面的例子,让大家能明白yield语法的使用。
用例1: 让出cpu执行权
function task1 () {for ($i = 1; $i <= 10; ++$i) { echo "This is task 1 iteration $i.n"; yield;// 遇到yield就会主动让出CPU的执行权; }}$a = task1(); $a->current(); // 执行第一次迭代$a->send(1); // 唤醒当时让出CPU执行权的yield
输出:
This is task 1 iteration 1.This is task 1 iteration 2.
用例2: yield的返回
// yield返回function task2 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 2 iteration $i.n"; yield "lm$i"; // 遇到yield就会主动让出CPU的执行权,for暂停执行, 然后返回"lm"。放在yield后面的值就是返回值 }}$a = task2(); $res = $a->current(); // 第一次迭代, 遇到yield返回var_dump($res); $res = $a->send(1); // 唤醒yield, for继续执行,遇到yield返回。var_dump($res);
输出:
This is task 2 iteration 1.string(3) "lm1"This is task 2 iteration 2.string(3) "lm2"
用例3: yield接收值
function task3 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 3 iteration $i.n"; $getValue = yield;// 遇到yield就会主动让出CPU的执行权;send后,将send值赋值给getValue echo $getValue . " "; }}$a = task3(); $a->current();$a->send("aa"); // 唤醒yield,并将"aa"值赋值给$getValue变量
输出:
This is task 3 iteration 1.aa This is task 3 iteration 2.
用例4: yeild接收和返回写在一起
function task4 () { for ($i = 1; $i <= 10; ++$i) { echo "This is task 4 iteration $i.n"; $ret = yield "lm$i"; // yield, 然后返回lm$i; 当send时,将send过来的值赋值给$ret; echo $ret; }}$a = task4(); var_dump($a->current()); // 返回lm1var_dump($a->send("hhh ")); // 先唤醒yield, 将"hhh "赋值给$ret,再返回lm2var_dump($a->send("www ")); // 先唤醒yield, 将"www "赋值给$ret,再返回lm3
输出:
This is task 4 iteration 1.string(3) "lm1"hhh This is task 4 iteration 2. string(3) "lm2"www This is task 4 iteration 3. string(3) "lm3"
相关推荐:
PHP中抽象类和接口的使用方法(代码)
php分页和正则验证的代码实现
以上就是PHP协程内容的详解的详细内容,更多请关注Gxl网其它相关文章!
内容总结
以上是为您收集整理的PHP协程内容的详解全部内容,希望文章能够帮你解决PHP协程内容的详解所遇到的程序开发问题。 如果觉得技术教程内容还不错,欢迎将网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。