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() 阻塞造成的思维误区,那就是认为要想真正实现非阻塞或者说实现异步的话,是必须依赖于语言底层的。

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

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

 

 

本文来自投稿,不代表展天博客立场,如若转载,请注明出处:https://www.me900.com/325615.html

(0)

相关推荐

  • 申请淘宝店铺需要什么条件(怎么申请淘宝网店的步骤)

    我们可以把淘宝店铺的类型分为淘宝普通店铺以及淘宝企业店铺,不同类型的店铺的入驻方式和条件是不一样的,相比之下,企业店铺的入驻门槛会高一些,那么企业店铺入驻到底需要哪些条件呢?   其实现在做一个企业店铺,有两种方式,一个是升级你现有的淘宝店铺,一个是重新注册新的企业店铺,升级店铺的话在你的卖家后台,直接点击升级,会提示你是否符合条件,有很多要求,可…

    2021-11-19
  • 雷佳音妻子回应出轨事件

    12月5日,雷佳音当街搂美女,疑似婚内出轨的新闻登上了热搜榜单,在某媒体偷拍视频中,只见雷佳音戴着一顶黑色的渔夫帽,白色口罩遮面,着装也是一身黑,样子显得相当低调,当时雷佳音与工作伙伴在某酒店吃饭。 一行人吃完饭后像是在酒店门口等车,而雷佳音则一出酒店门就立马搂住了旁边的女生,动作看起来十分娴熟,被搂的女生也没半分的不适,似乎这已经是司空见惯的事,两人的关系…

    2022-04-27 投稿
  • 淘宝买东西的流程是什么(怎么在淘宝买东西流程)

    随着时代的快速发展,网络购物已成为一种时尚,一种更为普遍的消费方式。数据显示越来越多的人开始网购!网购已然成为人们生活中必不可少的一部分!足不出户,轻松购物!网购方便你我他!第一步:手机需与银行卡绑定!持身份证和银行卡去银行办理,大部分银行不支持网上办理捆绑和解绑! 第二步:手机下载“淘宝“”天猫“”京东“”拼多多“”苏宁易购““盒马”“亚马孙”等…

    2021-11-28 投稿
  • 养老院价格收费(养老院价格收费一览表wuhan)

    “全国选择居家养老的老年人占90%,只有约10%的老年人选择机构养老。” 以上两组数据表明了什么问题?刚刚过去的重阳节,又一次激发了公众对养老话题的关注。成都一个名为“院落窝窝”的项目,与“能做机构不做居家和社区,能做床位绝不做上门服务”的行业“潜规则”背道而驰,受到关注。 以“在家生活、小区养老、社区安养”为理念,通过租赁小区民房、院落闲置物业组建互助养老…

    2023-05-29 投稿
  • 网赚大巴:网络项目发布网

    有位做地推的朋友找到我,说他的团队最近没单了,问我该去哪里接项目?地推我没做过,这方面我也知之甚少,既然来问我了,我就简单的说一下,不足之处,请大家补充指正! 一、直接找官方; 中秋节的时候,我在小区的超市门口,看到有2个人在做淘特活动拉新,我走过去看了一下,扫码下载淘特APP,送两个儿童小玩具,一个桌子面前围满了人,几乎都是宝妈;淘特活动拉新,新人下载注册…

    2021-11-29 投稿
  • 电梯广告策划方案(电梯广告推广话术)

    这大半年来,每天上下班坐电梯时发现了一些很有意思的广告和品牌,如果把他们串联和归纳起来,会发现电梯广告几乎“承包了”城市生活的方方面面,影响着主流城市人群的消费选择。 有时候你甚至觉得,电梯广告就像个“保姆”,为大众的美好生活操碎了心。 为你备好办公室零食 休闲零食作为打工人的“续命神器”,近两年行业增长迅猛,年复合增速达17.17%,去年市场规模接近2万亿…

    2022-01-03 投稿
  • 鼠目寸光打一生肖,鼠目寸光打一生肖最佳答案是什么

    今年的“年”过的很特殊,谁也没想到,疫情来得这么突然,相信许多家庭的出行计划,都全部搁置了,家庭聚会也全部取消。根据目前的情况,还是不要外出,虽然我们很多人没有参与一线的工作,但是我们不外出,做好自我防护,也算是为国家减少一点负担吧。 可是长期在家里,我们大人或许可以看看电视,玩玩手机,时间还可以很快打发,但是孩子不能长时间的去看电视。这样也正好可以培养一下…

    2022-04-29 投稿
  • 个人收款开通花呗收款(个人收款开通花呗收款怎么开通)

    近日,支付宝推出了一个12月份到店付款15天瓜分15亿红包活动,而使用花呗奖金还有翻倍。最近身边很多朋友问小编支付宝怎么开通花呗收款?使用花呗收款有2个好处,一个是红包奖金可能翻倍,另外一个是提现免费。不过,此前花呗收款都是针对商家,需要上传营业执照才可以申请,普通个人用户比较难申请,今天小编教大家一招,不用营业执照,个人也可以开通花呗收钱,下面是详细的方法…

    2021-12-26 投稿
  • 九寨沟珍珠滩瀑布(九寨沟珍珠滩瀑布简介)

    珍珠滩瀑布,位于九寨沟

    2023-05-24 投稿
  • app怎么制作?app制作教程及产品规划

    APP作为现代生活中最重要的生活工具之一,给大家带来了方方面面的便利,各个领域也诞生了许多移动互联网巨头。传统的企业和个人生产应用已成为新趋势。如何制作软件应用程序?今天小编就为大家介绍一下app软件的制作方法。   米么信息   1、痛点分析 对于项目开发,前期需要大量的市场分析和敏锐的嗅觉,找到用户的核心需求和痛点,目前有市场上没有同…

    2022-04-17
  • 中国移动米粉卡套餐(三大运营商哪个套餐性价比高)

    目前来看,三大运营商的套餐林林总总。中国移动的资费偏高,语音通话国内主叫一般在0.19元/分钟。中国联通和中国电信的资费相对便宜,语音通话国内主叫一般在0.15元/分钟或0.1元/分钟。俗话说,一分价钱一分货,中国移动坚持自己的信号好,就坚持高价不降。 当然,在移动互联网时代,语音通话几乎成为人们使用手机的次要功能,主要功能还是在上网流量上。根据流量使用的不…

    2023-06-14 投稿
  • 白金汉宫边牧(白金汉宫边牧犬舍官网)

    冬天到了,巴力这个狗东西有点凄惶,在寒风中瑟瑟发抖。我们把在夏天就为他准备好的铁房子宿舍整理了一下,四周围上棉被,使它有了栖身过冬的地方。 巴力是我们工作队的一员,是有身份、有户籍、在册的警犬。年初的时候,它被迫放弃舒适安逸的生活,乘着火车从繁华都市来到遥远的僻乡来陪同我们。刚从铁笼子里出来的时候,这狗东西神情恍忽,眼中充满敌意,耳朵坚竖,和传说中的德国奥特…

    2022-01-21 投稿