广告位联系
返回顶部
分享到

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

php 来源:互联网 作者:秩名 发布时间:2022-08-11 09:02:52 人浏览
摘要

拿平时大家写的 for 循环举例。像 go 你可以写两个go每个里面各写一个循环同时输入,你可以看到输出是交替。在过去的php版本中,如果只开启一个 cli 写多个 for 循环,那么他的输出一

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

现在借助 fiber 我们也可以实现这种操作。

下面这段代码就可以做到两个循环交叉执行。甚至可以控制两个程序执行的频率(比如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

<?php

$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

<?php

$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

<?php

 

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;

}


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。

您可能感兴趣的文章 :

原文链接 : https://www.php.cn/topic/php8/486174.html
相关文章
  • PHP数据加密方式的总结

    PHP数据加密方式的总结
    首先我们来了解一下为什么要加密? 在网络通信的过程中攻击者可以伪造请求和返回,从而达到不可告人的目的。如下图所示: 数据加密之
  • PHP四种统计在线人数方式介绍

    PHP四种统计在线人数方式介绍
    1 用表统计方式 用数据表统计在线人数,这种方式只能用在并发量不大的情况下。 首先我们先新建表:user_login 编辑 user_login 表 模拟用户登
  • PHP获取系统毫秒数时间方法
    前言 php中获取时间方法是date(),在php中获取时间戳方法有time()、strtotime(); date():date(format, timestamp),format为格式、timestamp为时间戳(可选
  • PHP中的DI依赖注入的详细介绍
    什么是 DI / 依赖注入 依赖注入DI 其实本质上是指对类的依赖通过构造器完成 自动注入 通俗来说,就是你当前操作一个类,但是这个类的某
  • PHP8.1 Fiber交叉执行多任务(附代码)
    拿平时大家写的 for 循环举例。像 go 你可以写两个go每个里面各写一个循环同时输入,你可以看到输出是交替。在过去的php版本中,如果只开
  • PHP8.0的编译安装与使用的介绍
    安装与配置 本次使用的操作系统Ubuntu 18.04.4 LTS 安装 1.准备必要库 1 2 apt-get install -y autoconf libxml2-dev libsqlite3-dev \ libcurl4-openssl-dev libssl-dev l
  • Mac如何编译PHP 8.0 到MxSrvs工具

    Mac如何编译PHP 8.0 到MxSrvs工具
    开始准备工作 下载 PHP 8.0 PHP 官方下载 https://www.php.net/downloads.php 进入到 MxSrvs 的主程序路径下的/Applications/MxSrvs/bin,根据 Mxsrvs 的命名规则,
  • PHP8 中的 JIT的详细介绍

    PHP8 中的 JIT的详细介绍
    PHP 8 的 JIT(Just In Time)编译器将作为扩展集成到 php 中 Opcache 扩展 用于运行时将某些操作码直接转换为从 cpu 指令。 这意味着使用JIT后,
  • PHP8.2不再支持字符串中用${}插入变量了

    PHP8.2不再支持字符串中用${}插入变量了
    PHP 社区 4 月底通过了一项只有一张反对票的提案,提案内容是在即将发布的 PHP 8.2 中,不再支持使用 ${} 在字符串中插入变量的语法(标记
  • PHP8.2两个新的强类型:null和false的详细介绍

    PHP8.2两个新的强类型:null和false的详细介绍
    PHP 从 7.0 开始不断地在完善强类型,我们可以给方法参数、返回值、类属性等声明类型。 强类型可以让代码更加健壮,易于维护,可读性增
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计