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)

相关推荐

  • 黑土地种什么最赚钱?黑土地种植什么效益高

    (在**新时代中国特色社会主义思想指引下——新时代新作为新篇章·**总书记关切事) 黑土地上的大豆新事 新华社哈尔滨3月17日电 题:黑土地上的大豆新事 提高大豆自给率事关粮食安全。扩种大豆是今年一号文件的重要内容。 去年中央农村工作会议会前,**总书记主持召开中央政治局常委会会议专题研究“三农”工作时强调,要实打实地调整结构,扩种大豆和油料,见到可考核的成…

    2023-01-29
  • 已售罄是什么意思(已售罄是什么意思怎么读)

    售罄是讲房产销售的一本书,在业内也是非常有名,而我作为一个从事一手房七个月,二手房两天的新手,还是想好好学习一下,所以每天分享一下自己的学习,大家有兴趣的可以一起学习,每天两节,好好学习,天天向上!   第一章和第二章,属于激励篇,有句话说的好,你得有欲望,你才会有动力,你才能去做好一件事,所以开篇先讲思想,端正思想,端正态度,方向才能正确,动力才…

    2021-12-16
  • 曹先生人物形象(曹先生人物形象50字)

    作者:濮天 电影艺术具有听觉语言和视觉语言两种语言形式,色彩是视觉语言的重要元素,具有象征、还原和表意的三重功能,即修辞、比喻和省略等语言修辞功能,自然现实的再现功能与传达作者创作意念的表意功能。通过以上三重功能,在电影所型塑的观看空间中,色彩起到了使内在世界外射化、抽象概念可视化、感性觉知共情化的作用,在衬托人物、渲染环境、达情表意、升华意义的同时,为电影…

    投稿 2023-05-26
  • 王宝强和女友同框现身(王宝强与女友罕同框)

    2月23日,知名娱乐刘大锤在社交平台上晒出王宝强与女友牵手同行的视频, 两人上演最萌身高差,相恋四年感情仍旧稳定惹人羡慕。 当天王宝强携带女友冯清低调现身,王宝强身穿黑色羽绒服,头戴黑色帽, 因为疫情的原因他做防护很是到位,还戴着黑的口罩 如此低调的装扮就宛如路人一般,没有一丝丝明星架子, 看起来非常的朴素,尽管如此的低调,都还是被八卦媒体认了出来,并拍摄的…

    2023-05-25 投稿
  • 宠物美容店赚钱吗?宠物美容师的工资待遇

    学宠物美容师工资高,待遇好,环境优越;由于宠物业的不断发展,宠物美容师需求量日益增长,宠物美容师的工资待遇也成倍增加,从年收入十几万到上几十万的都有。 学习宠物美容的费用不是随随便便定的,是根据学校的实力,和当地的消费水平实时的调整,很合理很科学,具体可以先了解一下当地的消费水平,或者是对比几家宠物美容培训学校,不同的学校价格也是不同的,学宠物美容最好到一线…

    2023-02-02
  • 四川一家五口坠河身亡,四川三人坠河最新

    一辆载有3人的白色轿车在213国道四川阿坝州茂县飞虹乡坠河,车上3人(1男2女)失联。10月25日,封面新闻记者从茂县公安局了解到,当地各派出所、交警中队派出警力一直沿岷江搜寻。目前,仍未发现3人踪迹。 白色轿车被冲走 车内有人爬出车窗 途经茂县飞虹乡的213国道,与岷江并行,另一侧则是山体。事发地段属岷江上游,水流湍急。从失联者家属提供的视频中可以看到,一…

    2022-03-21
  • 滑肉片汤的做法(滑肉片汤的做法窍门)

    比照着豆果里的四川滑肉的做法,简单实用,好吃好做。 By 泡泡机 用料 里脊肉 250g盐 5克木薯粉 10克培根肥肉部分 适量鸡蛋 2个开水 足量小白菜 适量 做法步骤 1、猪里脊切大的薄片。 2、盐、木薯淀粉、适量温水,把肉抓拌如图。 3、一点点底油,把培根偏肥的部分切丁,炒至吐油。 4、打入两个鸡蛋,煎起来。 5、继续加入开水,逐片加入腌好的肉片,搅散…

    2022-05-08 投稿
  • 快速学拼音打字的方法(零基础学拼音怎么学得快)

    很多人不会盲打并不是因为笨,而是没找到一种简单易行的练习方法。按照标准指法,看着键盘按照从A到Z的顺序打26个字母,最多七天你就可以学会盲打了。下面笔者和你分享学习拼音打字最快的方法,希望对大家有所帮助!   一、这是最简单的,词组。当要输入“棉袄”一词的拼音“mianao”时,肯定是出不来这个词的,因为ao字是零声母,不过要是在“mi…

    2021-12-23
  • 曼巴out什么意思?科比退役曼巴out前一句英文

    这是科比留给斯坦普斯的最后一句话是:“Mamba Out(曼巴出洞)。”当科比生涯最后一次说之际,另有它意——“曼巴最后一次出洞,故事完结。” 如何形容这样一名伟大的球员?当他离开之际,不妨试着拆解他最后的话语,试图寻找多面的他。 M:Michael 迈克尔 在**,有两个伟大的“迈克尔”:一位是流行天王迈克尔·杰克逊,另一位则是篮球之神迈克尔·乔丹。 科比…

    投稿 2022-04-20
  • 金童玉女打一最佳生肖,金童玉女:生肖猴的含义与寓意

    夫妻恩爱是最难得的财富,而一段姻缘,不仅是两人走进幸福殿堂的开始,更是集善积福的开端,如果天生命理相合,那么婚姻可称为“龙凤合鸣”,必然钱财丰足,福禄安康,下面这3个生肖配对就是龙配风一般的大吉大利,一起看看都是哪些呢? 蛇配鸡 蛇配鸡,天凤配地龙,和鸣又和睦,这一对生肖堪称为龙凤配的第一对,正是因为命理三合加上五行半合,形成大吉大利之势,婚前再穷,婚后也能…

    投稿 2023-05-08
  • 未来10大暴利行业,未来最挣钱的十大行业排行榜

    不论你是正在上学的学生,还是打算转行的毕业生,亦或者考虑创业的中年人,这六个行业都值得你好好投入精力去钻研。 因为这些都是未来最赚钱的行业。 一直以来,我们都在强调一件事情,就是一定要做顺应趋势的人。 无论是08年加入房地产,还是13年开始搞淘宝,还是15年开始做公众号,还是17年开始的短视频风潮,这一波波趋势,肉眼可见地让许多无背景,无后台的年轻人走上了逆…

    2022-04-22 创业项目
  • 支付宝自动续费怎么取消订阅(支付宝如何取消订阅续费)

    前几天#B站会员提前3天自动续费#话题冲上微博热搜,在上海市消保委出手后,哔哩哔哩也只是将扣费时间调整为“提前24小时和到期后扣款”,其实不止B站,很多应用都存在提前自动续费的情况,而且极少部分应用会发短信通知用户。对于芝麻妹来说还是将续费掌握在自己手中才放心,要不然被莫名其妙扣费了还不知道,那么我们该如何避免被“自动续费”呢?   11月23日,…

    2021-12-02 投稿