php多线程,php 协程实现多任务并发

PHP多任务,并发并行,多线程,协程等知识点理解

在讲协程之前,先谈谈多进程、多线程、并行和并发。对于单核处理器,多进程实现多任务的原理是让操作系统给一个任务每次分配一定的 CPU 时间片,然后中断、让下一个任务执行一定的时间片接着再中断并继续执行下一个,如此反复。

由于切换执行任务的速度非常快,给外部用户的感受就是多个任务的执行是同时进行的。

多进程的调度是由操作系统来实现的,进程自身不能控制自己何时被调度,也就是说: 进程的调度是由外层调度器抢占式实现的

而协程要求当前正在运行的任务自动把控制权回传给调度器,这样就可以继续运行其他任务。这与抢占式的多任务正好相反, 抢占多任务的调度器可以强制中断正在运行的任务, 不管它自己有没有意愿。如果仅依靠程序自动交出控制的话,那么一些恶意程序将会很容易占用全部 CPU 时间而不与其他任务共享。

协程的调度是由协程自身主动让出控制权到外层调度器实现的

协程可以理解为纯用户态的线程,通过协作而不是抢占来进行任务切换。

相对于进程或者线程,协程所有的操作都可以在用户态而非操作系统内核态完成,创建和切换的消耗非常低。

简单的说协程 就是提供一种方法来中断当前任务的执行,保存当前的局部变量,下次再过来又可以恢复当前局部变量继续执行。

我们可以把大任务拆分成多个小任务轮流执行,如果有某个小任务在等待系统 IO,就跳过它,执行下一个小任务,这样往复调度,实现了 IO 操作和 CPU 计算的并行执行,总体上就提升了任务的执行效率,这也便是协程的意义

多线程

在单核下,多线程必定是并发的;

不过现在的统一进程的多线程是可以运行在多核CPU下,所以可以是并行的

并发(Concurrency)

是指能处理多个同时性活动的能力,并发事件之间不一定要同一时刻发生。

并行(Parallesim)

是指同时发生的两个并发事件,具有并发的含义,而并发则不一定并行。

多个操作可以在重叠的时间段内进行。

并行和并发区别

并发指的是程序的结构,并行指的是程序运行时的状态

并行一定是并发的,并行是并发设计的一种

单线程永远无法达到并行状态

协程

协程的支持是在生成器的基础上, 增加了可以回送数据给生成器的功能(调用者发送数据给被调用的生成器函数).

这就把生成器到调用者的单向通信转变为两者之间的双向通信.

我们在上篇文章已经讲过了send方法, 下面让我们理解下协程

在没有涉及到异步执行代码之前,我们的代码都是这样的

function printNum($max, $caller){ for ($i=0; $i<$max; $i++ ) { echo “调度者:” . $caller . ” 打印:” . $i . PHP_EOL; }}printNum(3, “caller1”);printNum(3, “caller2”);# output调度者:caller1 打印:0调度者:caller1 打印:1调度者:caller1 打印:2调度者:caller2 打印:0调度者:caller2 打印:1调度者:caller2 打印:2使用协程后改进的代码,初稿,手动调整生成器执行

# 本代码手动调整了进程执行代码的顺序,当然本代码实现不用协程也可以,只是利用本流程说明协程作用# 生成器给了我们函数中断,协程[生成器send]给了我们重新唤起生成器函数的能力function printNumWithGen($max){ for ($i=0; $i<$max; $i++ ) { $res = yield $i; echo $res; }}$gen1 = printNumWithGen(3);$gen2 = printNumWithGen(3);// 手动执行caller1 再 caller2$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);// 手动执行caller1 再 caller2$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);// 手动执行caller2 再 caller1$gen2->send(“调度者: caller2 打印:” . $gen2->current() . PHP_EOL);$gen1->send(“调度者: caller1 打印:” . $gen1->current() . PHP_EOL);# output调度者: caller1 打印:0调度者: caller2 打印:0调度者: caller1 打印:1调度者: caller2 打印:1调度者: caller2 打印:2调度者: caller1 打印:2自定义简单定时执行任务示例:

class timer { private $start = 0; // 定时开始时间 private $timer; // 间隔的时间差,单位秒 private $value = 0; // 产生的结果值 private $callback; // 异步回调 private $isEnd = false; // 当前定时器任务是否结束 public function __construct($timer,callable $callback) { $this->start = time(); $this->timer = $timer; $this->callback = $callback; } public function run() { if($this->valid()) { $callback = $this->callback; $callback($this->value ++,$this); $this->start = time(); } } /** * 定时执行检查 */ public function valid() { $end = time(); if($end – $this->start >= $this->timer) { return true; } else { return false; } } public function setEnd($isEnd) { $this->isEnd = $isEnd; } public function getEnd() { return $this->isEnd; }}/** * 模拟阻塞的协程1 * */function taskObject1() { $timer = new timer(1,function($value,timer $timer) { if($value >= 5) { $timer->setEnd(true); } echo ”.’A ‘.$value; }); $tid = (yield getTaskId()); while (true) { if($timer->getEnd() == true) { break; } yield $timer->run(); }}/** * 模拟阻塞的协程2 * */function taskObject2() { $timer = new timer(2,function($value,timer $timer) { if($value >= 3) { $timer->setEnd(true); } echo ”.’B ‘.$value; }); $tid = (yield getTaskId()); while (true) { if($timer->getEnd() == true) { break; } yield $timer->run(); }}$scheduler = new Scheduler;$scheduler->newTask(taskObject1());$scheduler->newTask(taskObject2());$scheduler->run();以上实现的是:产生两个任务,并行执行,并且给每个任务在执行的时候模拟几秒钟的阻塞;让协程切换的时候能顺利切换,其中的任务阻塞不相互影响;

 

思考:

我为什么要做以上这件事情呢?因为我发现协程实现虽然很强大也很有意思,能让多任务并行,但是我在其中一个任务里调用系统函数 sleep() 的时候,阻塞任务会阻止协程切换,其实从协程的实现原理上来书也是这么回事。

那么,我也就想模拟协程阻塞,但是不产生阻塞看是否可行。PHP本身只提供了生成器为协程调用提供了支撑,如果不依赖扩展,没有提供多线程的程序实现方式,没有java那么强大,可以开子线程进行实现。

我印象中java的子线程是独立执行且不会相互阻塞的,所以我在想,PHP既然可以实现类似于多线程这样的机制,那么能不能实现调用过程中非阻塞呢?

经过这样一个实现和思考,一开始是陷入了一个误区的,是由于PHP原生函数 sleep() 阻塞造成的思维误区,那就是认为要想真正实现非阻塞或者说实现异步的话,是必须依赖于语言底层的。

后来,我想明白了一个道理,既然某个方法或者函数在执行过程中,会产生阻塞,那么把当前这个方法换成自定义的,做成非阻塞(相对于整个协程调度来说)不就行了吗?比如上面的定时执行我自己实现了一个。

而另一方面,协程调度本身的目的也是为了把任务执行过程切成尽量小片,从而快速切换执行,达到并行的目的。从这方面来看,协程应该也算是一种程序设计思想。

 

 

本站部分内容由互联网用户自发贡献,该文观点仅代表作者本人,本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如发现本站有涉嫌抄袭侵权/违法违规等内容,请联系我们举报!一经查实,本站将立刻删除。

(0)

相关推荐

  • 汕头移动流量卡(汕头移动流量套餐介绍)

    只要它家在卖的新卡,老用户都是可以要求转的。当然过程往往一波三折。 19孝心卡是我老早就看上的了。一开始卖新卡是要65岁以上才可以办理。这条件达不到,所以放弃。 今年618左右我看到卖新卡的页面,文字条件降低到60岁。这下我妈岁数达到了。所以就有了办下来的念想。 但是我妈平时用着8月租的卡,用不上流量。农n代的她,去年学会了刷抖音,但是不会扫码支付。所以家里…

    2023-05-31
  • 电信流量卡正规吗(电信流量卡申请入口)

    电信黄山卡 优惠月租;19元 国内流量;100G通用+30G定向流量 国内通话;100分钟 定向范围;查看详细 1、套餐宣传图 2、套餐海报 3、套餐评价 新上架的电信套餐,前一年都是19月租每月,流量长期每月都是130G流量+100分钟通话! 性价比很不错的套餐,前一年19月租每月,无合约期,建议用完1年后直接销卡再换其他卡! 4、套餐介绍 原套餐:39元…

    2023-05-25
  • 快递要是不拿会不会自动退了(快递不拿会自动退回吗)

    随着网购的普及,很多用户朋友都选择在网上购物,但网上购物有一定的风险,经常会遇到一些商家, 以次充好坑害消费者,但好在有平台作为监管者,遇到商家以次充好,我们可以发起退货,很多朋友不知道拒收快递后的退款流程,本期文章就说说举手快递后的一些事情。   拒收快递后必须符合条件才能退款 很多人对“拒收快递”的理解有偏差,认为只要没有收到货就可以退款,有这…

    2021-12-25
  • 小提请乐器有哪些(小提琴三弦是什么音)

    有些小提琴家喜欢使用固定品牌的琴弦。而有些人则通过不断寻找可能改善乐器声音或使演奏更容易的琴弦。现在弦乐演奏者在挑选小提琴弦时,选择开始多样化了起来,包括一些镀有铂金、金和银等材料的 E 弦。不过去尝试所有可用的琴弦以找到更适合自己的琴弦,可能有点不现实,但如果你了解弦芯和缠绕材料的构成、琴弦张力以及能够发出的音色,你就可从中选出适合自己的琴弦来。 当然,倾…

    2022-01-04
  • 中小学生安全教育月 ,各级教育行政部门应当负责监督

    今天(3月27日)是第28个全国中小学生安全教育日。日前,教育部基础教育司印发专门通知,决定从3月27日起,组织开展“全国中小学生安全教育周”主题活动。 通知要求,各地教育行政部门以“普及安全知识,提高避险能力”为重点,广泛深入开展形式多样、内容丰富的中小学生安全教育系列活动,着力提高学生安全防范意识,增强学生自我防护能力,推进校园安全文化建设,促进学生安全…

    2023-06-02
  • 汉朝电视剧有哪些(汉代古装剧电视剧大全)

    能不能推荐十部必追的大陆电视剧,口碑和网播量高的那种# 1.康熙王朝   清朝顺治十八年,天花在皇宫蔓延,顺治帝的董爱妃因此一命呜呼,顺治因痛不欲生而决意出家。此时,清帝国充满了内忧外忧。危急之际,孝庄太后(斯琴高娃 饰)当机立断,将得了天花初愈的年仅八岁的皇子玄烨力推为皇室继承人,康熙皇帝登基了。康熙(陈道明 饰)即位以后,手握兵权的鳌拜以权相逼…

    2021-12-22
  • 怎么发外链(高权重的外链发布平台)

    SEO优化过程中常常会发布一些外链,外链有哪些平台呢?小编花了一晚上的时间为大家整理了以下7大类外链发布平台,全方位做好站外的宣传。贪多嚼不烂,每一个大类推荐5-10个最好的,好好利用就可以了! 方法/步骤1: 博客类: 1、新浪博客 2、天涯博客 3、搜狐博客 4、网易博客 5、凤凰博客 方法/步骤2: 投稿类: 1、今日头条 2、搜狐自媒体 3、一点资讯…

    投稿 2021-11-30
  • 长虹电视黑屏了怎么调回来(长虹电视黑屏怎么回事)

    作为国内知名彩电企业之一的长虹,以产品质量和注重研发在业界闻名,在消费者中间也一直享有良好的口碑。但在最近,有消费者对长虹电视投诉称,今年1月购买的55寸长虹电视出现了质量问题,并且维修不好。 图片来源于网络 在九十年代,凭借着低价和良好的品质,在众多国牌中脱颖而出的长虹彩电,其市场号召力令人难以想象:长虹彩电的市场占有率由16.68%激增至31.64%,最…

    2022-03-19
  • 大葱白生姜熬水喝有什么功效,老姜大葱白煮水功效

    正月廿四,今日是浪漫的情人节,天气非常好,气温也非常暖和,艳阳高照,鸟语花香,草长莺飞,遍地都是绿油油的植物,充满着生机勃勃的气息。春天是最需要养生的时候,不能吃太多油腻的食物,顺应时令的变化,可以多吃新鲜的蔬菜,喝一些鲜美的汤品。 我们家神兽去学校了,学校的饭菜都不合胃口,这些日子不是很忙碌,给老公和孩子做一桌饭菜,老公给我准备一些礼物,用来感谢我的付出。…

    2023-06-30 投稿
  • wow点卡涨价(wow点卡价格)

    一直以来,魔兽世界全新的点卡收费制度饱受各种苟评,既有魔兽世界休闲党抱怨、亦有肝肝党的庆幸。一个月75元的价格,折合下来就是2.5元一天,但是好是坏,是贵是贱,大家也是各说各的理由。而今天,魔兽世界在本月推出了全新的充值优惠活动,活动有二: 活动①:从未充值过魔兽世界点卡的玩家首度充值享受超额优惠,优惠的力度有多大呢?原价75现价30,如果你足够运气的话,你…

    2022-01-21
  • 土地是什么意思(土地造句一年级简单的造句)

    开垦(kāi kěn)。近义词有:拓荒,开辟,开发,开荒,垦荒。反义词有:荒废。 把荒地开辟成可以种植的土地。[洪深《劫后桃花》:“我本来是青岛本地的人,因为外国人压迫我们,我们才搬到黑龙江去开垦的。”]指开创某种事物。[鲁迅《致榴花社》:“新文艺之在太原,还在开垦时代,作品似以浅显为宜。”] 开垦参考例句: 1、我们今天所拥有的这片乐土,都是先人辛勤开垦的…

    2022-05-07
  • 大角刷新具体地点(大角刷新时间14小时)

    创造与魔法大角牛位置分布图有哪些?刷新时间在什么时候?创造与魔法大角牛是合成巨角拳手的宠物,然后才能一步一步的进化龙血拳皇,玩家需要捕捉它,那么创造与魔法大角牛位置在哪?相信这也是很多玩家想知道的问题,下面就赶紧跟小编一起一睹为快吧! 创造与魔法大角牛位置分布图及刷新时间2021 分布位置 名称:大角牛 类型:普通生物(可捕捉成宠物或坐骑) 宠物资质:命资 …

    2022-01-13