PHP8.1 Fiber交叉执行多任务(附代码详解)

大家的电脑应该都是大等于2核的了,但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行,微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。(本文给大家抛个砖,欢迎大家补充更有意思的使用)

拿平时大家写的 for 循环举例。像 go 你可以写两个 go 每个里面各写一个循环同时输入,你可以看到输出是交替。在过去的php版本中,如果只开启一个 cli 写多个 for 循环,那么他的输出一定是顺序的。无法做到交叉输出(也就是无法在第一个循环中执行若干次后,让b再执行,b执行一段时间后,再让A执行)。

现在借助 fiber 我们也可以实现这种操作。【推荐学习:PHP视频教程】

下面这段代码就可以做到两个循环交叉执行。甚至可以控制两个程序执行的频率(比如A执行3次,B执行一次这样分配)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

$t1    = false;

$t2    = false;

$reg   = [];

$reg[] = new \Fiber(function () use (&$t1) {

    for ($i = 1; $i < 10; $i++) {

        echo $i;

        echo PHP_EOL;

        \Fiber::suspend();

    }

    $t1 = true;

});

$reg[] = new \Fiber(function () use (&$t2) {

    for ($i = 1; $i < 10; $i++) {

        echo $i;

        echo PHP_EOL;

        \Fiber::suspend();

    }

    $t2 = true;

});

$startTag = true;

while (count($reg) > 1) {

    if ($startTag) foreach ($reg as $pI) {

        $pI->start();

        $startTag = false;

    }

    foreach ($reg as $pI) {

        $pI->resume();

    }

    if ($t1 === true && $t2 === true) {

        break;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

1

1

2

2

3

3

4

4

5

5

6

6

7

7

8

8

9

9

你甚至可以控制两个循环的执行频率,比如 第一个循环 执行3次后,第二个循环执行一次。代码如下

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

$reg = [];

$fId = 1;

$reg[$fId] = new \Fiber(function () use (&$reg, $fId) {

    for ($i = 1; $i < 10; $i++) {

        echo $fId . ‘:’ . $i;

        echo PHP_EOL;

        if ($i % 3 == 0) {

            \Fiber::suspend();

        }

    }

    unset($reg[$fId]);

});

$fId++;

$reg[$fId] = new \Fiber(function () use (&$reg, $fId) {

    for ($i = 1; $i < 10; $i++) {

        echo $fId . ‘:’ . $i;

        echo PHP_EOL;

        \Fiber::suspend();

    }

    unset($reg[$fId]);

});

$startTag = true;

while (count($reg) > 0) {

    if ($startTag) foreach ($reg as $pI) {

        $pI->start();

        $startTag = false;

    }

    foreach ($reg as $pI) {

        $pI->resume();

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

1:1

1:2

1:3

2:1

1:4

1:5

1:6

2:2

1:7

1:8

1:9

2:3

2:4

2:5

2:6

2:7

2:8

2:9

通过消息通知完成

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;

use Symfony\Component\Console\Command\Command;

use Symfony\Component\Console\Input\InputArgument;

use Symfony\Component\Console\Input\InputInterface;

use Symfony\Component\Console\Input\InputOption;

use Symfony\Component\Console\Output\OutputInterface;

use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(

    name: ‘Sname’,

    description: ‘Add a short description for your command’,

)]

class SnameCommand extends Command

{

    protected function configure(): void

    {

        $this

            ->addArgument(‘arg1’, InputArgument::OPTIONAL, ‘Argument description’)

            ->addOption(‘option1’, null, InputOption::VALUE_NONE, ‘Option description’);

    }

    protected function execute(InputInterface $input, OutputInterface $output): int

    {

        $t1  = false;

        $t2  = false;

        $reg = [];

        $fId = 1;

        $reg[] = new \Fiber(function () use ($fId) {

            for ($i = 1; $i < 10; $i++) {

                echo $fId . ‘:’ . $i;

                echo PHP_EOL;

                if ($i % 3 == 0) {

                    \Fiber::suspend(new SuspendData(Status::Running));

                }

            }

            \Fiber::suspend(new SuspendData(Status::Stop));

        });

        $fId++;

        $reg[] = new \Fiber(function () use ($fId) {

            for ($i = 1; $i < 10; $i++) {

                echo $fId . ‘:’ . $i;

                echo PHP_EOL;

                \Fiber::suspend(new SuspendData(Status::Running));

            }

            \Fiber::suspend(new SuspendData(Status::Stop));

        });

        $startTag = true;

        while (count($reg) > 0) {

            if ($startTag) foreach ($reg as $pI) {

                $pI->start();

                $startTag = false;

            }

            foreach ($reg as $key => $pI) {

                $r = $pI->resume();

                if ($r->status === Status::Stop) {

                  unset($reg[$key]);

                }

            }

        }

        return Command::SUCCESS;

    }

}

class SuspendData

{

    public readonly Status $status;

    public function __construct($status)

    {

        $this->status = $status;

    }

}

enum Status

{

    case Stop;

    case Running;

}

以上就是PHP8.1 Fiber交叉执行多任务(附代码详解)的详细内容,更多请关注php中文网其它相关文章!

原文链接:

https://www.php.cn/topic/php8/486174.html

学校电脑室专用操作系统GHOST WIN10 64位 纯净无广告无后门

提供了三种系统恢复工具
其中Ghost安装器 和 CGI硬盘安装增强版 支持mbr分区系统恢复
一键安装系统(支持GTP) 支持GTP EFI系统恢复

注意:系统恢复工具在恢复系统时会修改系统必要启动项,可能会被部分杀毒软件误报!

所以运行装机软件前一定要关闭所有杀毒软件或卫士!!!

请放心使用!

(本系统下载及其他软件,均基于自由分享为目的,请下载者测试完成后24小时内删除。)

本GHOST内集成了电子教室客户端,冰点还原,360企业版(无广告),WPS2019(无广告),火狐、谷歌,金山打字通(无广告)。
默认密码均为abc123

多台机器安装时请临时解锁冰点,然后修改成想要的主机名,再重启。

2022.3.11

系统下载地址:

链接1:https://pan.baidu.com/s/1DEC1WuF20wYDt-G0sxfMYw?pwd=wvi2
提取码:wvi2
–来自百度网盘超级会员V6的分享

链接2:https://pan.baidu.com/s/1CtcRTSHhYL9K6kUzD9yuxA?pwd=4321
提取码:4321
–来自百度网盘超级会员V6的分享

公共DNS集 和 IPV6 DNS

百度公共DNS 180.76.76.76

腾讯公共DNS:119.29.29.29

阿里云公共DNS 223.5.5.5

谷歌公共DNS 8.8.8.8(国内最慢的)

中国互联网络中心公共DNS 1.2.4.8

openDNS:208.67.222.222

公共IPV6 dns大全

一、阿里ipv6 dns

阿里的dns好在于自家的服务器遍布全球,加上自家研究的CDN技术快稳定,强大的阿里云团队技术坚持也是国内首家支持IPv4和IPv6,双端加持,安全快速。

2400:3200::1
2400:3200:baba::1

二、百度ipv6 dns

百度作为国内最大的搜索引擎服务商,也不甘示弱的推出了ipv6服务,成为国内第二个支持双端IPv4和IPv6服务商之一。

2400:da00::6666

三、天地互连 ipv6 dns

该服务是北京天地互连信息技术有限公司,官方没有太多的介绍,但在全球也布属了多台服务器,该公司响应工信部发文,率先推出国内首个ipv6dns服务。可以说该ipv6是国内最安全的dns之一,毕竟是国家项目。

240C::6666
240C::6644

四、谷歌 vip6 dns

作为全球最大的互联网公司之一的谷歌,也推出了ipv6dns服务,但对于国内用户来说,基本用不着,谷歌除广告业务外,其他业务基本都撤离了中国大陆,包括很多服务器,所有如果不是在香港、台湾一带或离国外交接的地方,不建议是要谷歌dns,服务器响应可能过慢。

2001:4860:4860::8888
2001:4860:4860::8844

目前互联网上能收集的大公司ipv6 dns也就这几家,其他的都是什么研究院和大学的,这就不做分类了,排名不分先后。

建议大家选用哪个DNS之前,可以用ping来测试一下,不同地区不同公司的时延不一样,可以选择延时最少的。

ping -6 IPV6地址

可以测试IPV6 DNS的响应速度。

DNS介绍

DNS即Domain Name System的缩写,是因特网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串;
DNS主要用于域名与IP地址的相互转换,以及控制因特网的电子邮件的发送;大多数因特网服务依赖于DNS而工作,一旦DNS出错,将导致无法连接Web站点,电子邮件的收发也会失效;

免费公用DNS服务

名称IPV4IPV6
百度180.76.76.762400:da00::6666
阿里223.5.5.5/223.6.6.6
腾讯119.29.29.29/182.254.116.116
信风114.114.114.114/114.114.115.115
Google8.8.8.8/8.8.4.42001:4860:4860::8888/2001:4860:4860::8844
CloudFlare1.1.1.1/1.0.0.1
IBM9.9.9.9
微软4.2.2.1/4.2.2.2
DNS派(电信,移动,铁通)101.226.4.6/218.30.118.6
DNS派(联通)123.125.81.6/140.207.198.6
114家庭版114.114.114.110/114.114.115.110
114安全版114.114.114.119/114.114.115.119
TWNIC101.101.101.101
CNNIC1.2.4.8/210.2.4.8
One(拦截版)117.50.11.11/52.80.66.662620:0:ccc::2
One(纯净版)117.50.10.10/52.80.52.522620:0:ccc::2
上海交通大学202.120.2.100/202.120.2.1012001:da8:8000:1:202:120:2:100
中国科技大学202.38.64.12001:da8::666
北京邮电大学2001:da8:202:10::36/2001:da8:202:10::37
北京科技大学2001:da8:208:10::6
国家互联网中心240c::6666/240c::6644
CNNIC1.2.4.8/210.2.4.82001:dc7:1000::1
V2EX199.91.73.222/178.79.131.110
OpenDNS208.67.222.222/208.67.220.220
FREENOM80.80.80.80
HKBN203.80.96.10
DYN216.146.35.35/216.146.36.36
COMODO8.26.56.26/8.20.247.20
KT168.126.63.1/168.126.63.2

中国电信DNS

地区DNSDNS
安徽电信61.132.163.68202.102.213.68
北京电信219.141.136.10219.141.140.10
重庆电信61.128.192.6861.128.128.68
福建电信218.85.152.99218.85.157.99
甘肃电信202.100.64.6861.178.0.93
广东电信202.96.128.86202.96.128.166
广西电信202.103.225.68202.103.224.68
贵州电信202.98.192.67202.98.198.167
河南电信222.88.88.88222.85.85.85
湖北电信202.103.24.68202.103.0.68
湖南电信222.246.129.8059.51.78.211
江苏电信218.2.2.2218.4.4.4
江西电信202.101.224.69202.101.226.68
山东电信219.146.0.130219.150.32.132
陕西电信218.30.19.4061.134.1.4
上海电信202.96.209.133116.228.111.118
四川电信61.139.2.69218.6.200.139
天津电信219.150.32.132219.146.0.132
云南电信222.172.200.6861.166.150.123
浙江电信202.101.172.3561.153.177.196
内蒙古电信219.148.162.31222.74.39.50
黑龙江电信219.147.198.230219.147.198.242

中国联通DNS

地区DNSDNS
北京联通202.106.196.115202.106.46.151
重庆联通221.5.203.98221.7.92.98
广东联通210.21.196.6221.5.88.88
河北联通202.99.160.68202.99.166.4
河南联通202.102.224.68202.102.227.68
吉林联通202.98.0.68202.98.5.68
江苏联通221.6.4.66221.6.4.67
山东联通202.102.128.68202.102.152.3
山西联通202.99.192.66202.99.192.68
陕西联通221.11.1.67221.11.1.68
上海联通210.22.70.3210.22.84.3
四川联通119.6.6.6124.161.87.155
天津联通202.99.104.68202.99.96.68
浙江联通221.12.1.227221.12.33.227
内蒙古联通202.99.224.68202.99.224.8
黑龙江联通202.97.224.69202.97.224.68

中国移动DNS

地区DNSDNS
江苏移动221.131.143.69112.4.0.55
安徽移动211.138.180.2211.138.180.3
山东移动218.201.96.130211.137.191.26

Apple TV DNS

地区DNSDNS
南方电信180.153.225.13658.63.244.120
北方联通115.28.40.136
香港111.68.8.179
国外182.16.230.98