
<!DOCTYPE html>
<html lang="zh" data-goose-resource data-theme="gf-light">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="color-scheme" content="light dark">
    <meta name="theme-color" content="#fbfdff" data-goose-theme-color>
    <title>php[027]fiber - GooseForum</title>
    <meta name="description" content="大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...">
    <link rel="canonical" href="https://gooseforum.online/p/post/334">
    
    
    <meta property="og:title" content="php[027]fiber">
    <meta property="og:description" content="大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...">
    <meta property="og:type" content="article">
    <meta property="og:url" content="https://gooseforum.online/p/post/334">
    <meta property="og:site_name" content="GooseForum">
    
    <meta property="article:published_time" content="2022-09-05T20:40:00&#43;08:00">
    <meta property="article:modified_time" content="2025-12-30T20:46:43&#43;08:00">
    <meta property="article:author" content="abandon1a2b">
    <meta property="article:section" content="Coding">
    <meta property="article:tag" content="Coding">
    
    
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="php[027]fiber">
    <meta name="twitter:description" content="大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...">
    
    
    <script type="application/ld+json" data-goose-jsonld="page">{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"php[027]fiber","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","text":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","author":{"@type":"Person","name":"abandon1a2b","url":"https://gooseforum.online/u/1"},"publisher":{"@type":"Organization","name":"GooseForum","url":"https://gooseforum.online"},"datePublished":"2022-09-05T20:40:00+08:00","dateModified":"2025-12-30T20:46:43+08:00","url":"https://gooseforum.online/p/post/334","mainEntityOfPage":"https://gooseforum.online/p/post/334","articleSection":"Coding","keywords":["Coding"],"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":501}]}</script>
    <link rel="icon" href="/static/pic/icon.webp">
    <script defer src="https://umami.leancodebox.online/script.js" data-website-id="0a633415-dd84-4264-98cd-a006e6a8fefc"></script>
    <link rel="stylesheet" href="/assets/assets/site-DMKa7mM5.css" crossorigin>
<script type="module" src="/assets/assets/site-BNzyJZpy.js" crossorigin></script>

    <link id="goose-site-theme-link" rel="stylesheet" href="/site-theme.css?v=3535d0c163954d2c">
</head>
<body class="bg-base-200 text-base-content antialiased">
    <script id="goose-payload" type="application/json">{"component":"article.detail","props":{"article":{"id":334,"title":"php[027]fiber","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","url":"/p/post/334","html":"\u003cblockquote\u003e\n\u003cp\u003e大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e拿平时大家写的 for 循环举例。像 go 你可以写两个 \u003ccode\u003ego\u003c/code\u003e 每个里面各写一个循环同时输入，你可以看到输出是交替。在过去的php版本中，如果只开启一个 cli 写多个 for 循环，那么他的输出一定是顺序的。无法做到交叉输出（也就是无法在第一个循环中执行若干次后，让b再执行，b执行一段时间后，再让A执行）。现在借助 fiber 我们也可以实现这种操作。下面这段代码就可以做到两个循环交叉执行。甚至可以控制两个程序执行的频率（比如A执行3次，B执行一次这样分配）\u003c/p\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003cpre\u003e\u003ccode class=\"language-php\"\u003e\u0026lt;?php\n$t1    = false;\n$t2    = false;\n$reg   = [];\n$reg[] = new \\Fiber(function () use (\u0026amp;$t1) {\n    for ($i = 1; $i \u0026lt; 10; $i++) {\n        echo $i;\n        echo PHP_EOL;\n        \\Fiber::suspend();\n\n    }\n    $t1 = true;\n});\n\n\n$reg[] = new \\Fiber(function () use (\u0026amp;$t2) {\n    for ($i = 1; $i \u0026lt; 10; $i++) {\n        echo $i;\n        echo PHP_EOL;\n        \\Fiber::suspend();\n    }\n    $t2 = true;\n});\n\n$startTag = true;\nwhile (count($reg) \u0026gt; 1) {\n\n    if ($startTag) foreach ($reg as $pI) {\n        $pI-\u0026gt;start();\n        $startTag = false;\n    }\n\n    foreach ($reg as $pI) {\n        $pI-\u0026gt;resume();\n    }\n\n    if ($t1 === true \u0026amp;\u0026amp; $t2 === true) {\n        break;\n    }\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cpre\u003e\u003ccode\u003e1\n1\n2\n2\n3\n3\n4\n4\n5\n5\n6\n6\n7\n7\n8\n8\n9\n9\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e你甚至可以控制两个循环的执行频率，比如 第一个循环 执行3次后，第二个循环执行一次。代码如下\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-php\"\u003e\u0026lt;?php\n$reg = [];\n$fId = 1;\n\n\n$reg[$fId] = new \\Fiber(function () use (\u0026amp;$reg, $fId) {\n    for ($i = 1; $i \u0026lt; 10; $i++) {\n        echo $fId . ':' . $i;\n        echo PHP_EOL;\n        if ($i % 3 == 0) {\n            \\Fiber::suspend();\n        }\n    }\n    unset($reg[$fId]);\n});\n$fId++;\n\n$reg[$fId] = new \\Fiber(function () use (\u0026amp;$reg, $fId) {\n    for ($i = 1; $i \u0026lt; 10; $i++) {\n        echo $fId . ':' . $i;\n        echo PHP_EOL;\n        \\Fiber::suspend();\n    }\n    unset($reg[$fId]);\n});\n\n$startTag = true;\nwhile (count($reg) \u0026gt; 0) {\n    if ($startTag) foreach ($reg as $pI) {\n        $pI-\u0026gt;start();\n        $startTag = false;\n    }\n    foreach ($reg as $pI) {\n        $pI-\u0026gt;resume();\n    }\n}\n\n\u003c/code\u003e\u003c/pre\u003e\n\u003cpre\u003e\u003ccode\u003e1:1\n1:2\n1:3\n2:1\n1:4\n1:5\n1:6\n2:2\n1:7\n1:8\n1:9\n2:3\n2:4\n2:5\n2:6\n2:7\n2:8\n2:9\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e通过消息通知完成\u003c/p\u003e\n\u003cpre\u003e\u003ccode class=\"language-php\"\u003e\u0026lt;?php\n\nnamespace App\\Command;\n\nuse Symfony\\Component\\Console\\Attribute\\AsCommand;\nuse Symfony\\Component\\Console\\Command\\Command;\nuse Symfony\\Component\\Console\\Input\\InputArgument;\nuse Symfony\\Component\\Console\\Input\\InputInterface;\nuse Symfony\\Component\\Console\\Input\\InputOption;\nuse Symfony\\Component\\Console\\Output\\OutputInterface;\nuse Symfony\\Component\\Console\\Style\\SymfonyStyle;\n\n#[AsCommand(\n    name: 'Sname',\n    description: 'Add a short description for your command',\n)]\nclass SnameCommand extends Command\n{\n    protected function configure(): void\n    {\n        $this\n            -\u0026gt;addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')\n            -\u0026gt;addOption('option1', null, InputOption::VALUE_NONE, 'Option description');\n    }\n\n    protected function execute(InputInterface $input, OutputInterface $output): int\n    {\n        $t1  = false;\n        $t2  = false;\n        $reg = [];\n        $fId = 1;\n\n\n        $reg[] = new \\Fiber(function () use ($fId) {\n            for ($i = 1; $i \u0026lt; 10; $i++) {\n                echo $fId . ':' . $i;\n                echo PHP_EOL;\n                if ($i % 3 == 0) {\n                    \\Fiber::suspend(new SuspendData(Status::Running));\n                }\n            }\n            \\Fiber::suspend(new SuspendData(Status::Stop));\n\n        });\n        $fId++;\n\n        $reg[] = new \\Fiber(function () use ($fId) {\n            for ($i = 1; $i \u0026lt; 10; $i++) {\n                echo $fId . ':' . $i;\n                echo PHP_EOL;\n                \\Fiber::suspend(new SuspendData(Status::Running));\n            }\n            \\Fiber::suspend(new SuspendData(Status::Stop));\n        });\n\n        $startTag = true;\n        while (count($reg) \u0026gt; 0) {\n            if ($startTag) foreach ($reg as $pI) {\n                $pI-\u0026gt;start();\n                $startTag = false;\n            }\n            foreach ($reg as $key =\u0026gt; $pI) {\n                $r = $pI-\u0026gt;resume();\n                if ($r-\u0026gt;status === Status::Stop) {\n                  unset($reg[$key]);\n                }\n            }\n        }\n\n\n        return Command::SUCCESS;\n    }\n}\n\nclass SuspendData\n{\n    public readonly Status $status;\n\n    public function __construct($status)\n    {\n        $this-\u0026gt;status = $status;\n    }\n}\n\nenum Status\n{\n    case Stop;\n    case Running;\n}\n\u003c/code\u003e\u003c/pre\u003e\n\u003cp\u003e欢迎大家补充\u003c/p\u003e\n","articleStatus":1,"processStatus":0,"author":{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp","wornBadge":{"code":"king","type":"system","grantMode":"manual","name":"King","description":"社区之王","iconType":"asset","iconKey":"","iconUrl":"/static/badges/king.svg","color":"amber","level":"special","isEnabled":true,"isWearable":true,"sortOrder":1,"source":"manual","reason":"管理员手动授予","grantedAt":"2026-06-07 18:52:33"}},"participants":[{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp","wornBadge":{"code":"king","type":"system","grantMode":"manual","name":"King","description":"社区之王","iconType":"asset","iconKey":"","iconUrl":"/static/badges/king.svg","color":"amber","level":"special","isEnabled":true,"isWearable":true,"sortOrder":1,"source":"manual","reason":"管理员手动授予","grantedAt":"2026-06-07 18:52:33"}}],"categories":[{"id":4,"name":"Coding","url":"/c/Coding/4","color":"#8241d6"}],"replyCount":0,"maxReplyNo":0,"viewCount":501,"likeCount":0,"isLiked":false,"isBookmarked":false,"isWatched":false,"createdAt":"2022-09-05 20:40:00","updatedAt":"2025-12-30 20:46:43"},"replies":[],"hotTopics":[{"id":432,"title":"一些建议和bug","description":"Footer 中的 Primary 类使用 Html，无法编译 url 和 a 标签，会显示纯 Html 代码 下方文字内容 （Primary）\"，还是会出现原html， Power by \u003ca href=\"https://github.com/leancodebox/GooseForum\"\u003eGooseForum\u003c/a\u003e. “外部资源链接 / Meta 标签” 若为空，则会导致无法保存，500错误...","url":"/p/post/432","pinWeight":0,"processStatus":0,"author":{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"},"participants":[{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":52,"viewCount":628,"activityText":"2026-06-16 09:40:52","lastUpdateTime":"2026-06-16 09:40:52"},{"id":467,"title":"震惊！！点进标题帖子，返回键会回到顶部？？","description":"顶部往下刷到底点进标题帖子，返回键会回到顶部，没有返回到刚刚点进标题帖子的停留！每次返回还得往下刷找找刚刚点进的帖子😅","url":"/p/post/467","pinWeight":0,"processStatus":0,"author":{"id":51,"username":"weilaimeng","avatarUrl":"/static/pic/8.webp"},"participants":[{"id":51,"username":"weilaimeng","avatarUrl":"/static/pic/8.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":18,"viewCount":142,"activityText":"2026-06-18 09:55:30","lastUpdateTime":"2026-06-18 09:55:30"},{"id":439,"title":"请问大佬怎么用宝塔部署此项目","description":"这个有没有宝塔的安装教程，看这个论坛系统不错，界面也好看，但是不会安装，因为doxker有其他的项目，这个不会安装，能不能出个宝塔安装的教程？。","url":"/p/post/439","pinWeight":0,"processStatus":0,"author":{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},"participants":[{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"}],"replyCount":13,"viewCount":204,"activityText":"2026-05-27 23:59:39","lastUpdateTime":"2026-05-27 23:59:39"},{"id":475,"title":"正文内容的背景和右侧卡片相连了？","description":"RT RT","url":"/p/post/475","pinWeight":0,"processStatus":0,"author":{"id":44,"username":"yannisme","avatarUrl":"/static/pic/3.webp"},"participants":[{"id":44,"username":"yannisme","avatarUrl":"/static/pic/3.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":28,"username":"yannis","avatarUrl":"/file/img/avatars/avatar_28_1779205979/ebd0888e-11d4-439f-8a99-fc5de7bd00eb.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"},{"id":8,"name":"吐槽/脑洞","url":"/c/%E5%90%90%E6%A7%BD%2F%E8%84%91%E6%B4%9E/8","color":"#5d41d6"}],"replyCount":9,"viewCount":61,"activityText":"2026-06-29 15:49:51","lastUpdateTime":"2026-06-29 15:49:51"},{"id":453,"title":"纪念一下第一次王者上百星","description":"","firstImageUrl":"/file/img/2026/06/04/664129e0-2015-4d58-bb01-b9abd5def8ea.webp","url":"/p/post/453","pinWeight":0,"processStatus":0,"author":{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},"participants":[{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"},{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"}],"categories":[{"id":11,"name":"Game","url":"/c/Game/11","color":"#d66e41"}],"replyCount":8,"viewCount":124,"activityText":"2026-06-06 21:20:10","lastUpdateTime":"2026-06-06 21:20:10"},{"id":443,"title":"部署有没有内存限制","description":"1h1g可以呀玩不，有没有限制，大佬用的什么配置服务器说说呗","url":"/p/post/443","pinWeight":0,"processStatus":0,"author":{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},"participants":[{"id":31,"username":"mopwang","avatarUrl":"/static/pic/5.webp"},{"id":1,"username":"abandon1a2b","avatarUrl":"/file/img/avatars/1/1779889413613587649/avatar.webp"}],"categories":[{"id":6,"name":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"}],"replyCount":8,"viewCount":142,"activityText":"2026-05-30 11:38:25","lastUpdateTime":"2026-05-30 11:38:25"}],"permissions":{"isOwnArticle":false,"canReply":false,"canModerateArticle":false}},"meta":{"title":"php[027]fiber - GooseForum","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","canonical":"https://gooseforum.online/p/post/334","openGraph":{"title":"php[027]fiber","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","type":"article","url":"https://gooseforum.online/p/post/334","siteName":"GooseForum","publishedTime":"2022-09-05T20:40:00+08:00","modifiedTime":"2025-12-30T20:46:43+08:00","author":"abandon1a2b","section":"Coding","tags":["Coding"]},"twitter":{"card":"summary","title":"php[027]fiber","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的..."},"jsonLd":{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"php[027]fiber","description":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","text":"大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...","author":{"@type":"Person","name":"abandon1a2b","url":"https://gooseforum.online/u/1"},"publisher":{"@type":"Organization","name":"GooseForum","url":"https://gooseforum.online"},"datePublished":"2022-09-05T20:40:00+08:00","dateModified":"2025-12-30T20:46:43+08:00","url":"https://gooseforum.online/p/post/334","mainEntityOfPage":"https://gooseforum.online/p/post/334","articleSection":"Coding","keywords":["Coding"],"interactionStatistic":[{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/LikeAction","userInteractionCount":0},{"@type":"InteractionCounter","interactionType":"https://schema.org/ViewAction","userInteractionCount":501}]}},"layout":{"site":{"name":"GooseForum","description":"🦢 大鹅栖息地 | 自由漫谈的江湖茶馆","logo":"/static/pic/icon.webp","favicon":"/static/pic/icon.webp","externalLinks":"\u003cscript defer src=\"https://umami.leancodebox.online/script.js\" data-website-id=\"0a633415-dd84-4264-98cd-a006e6a8fefc\"\u003e\u003c/script\u003e","brandType":"default","brandText":"","brandImage":""},"viewer":{"id":0,"username":"","email":"","avatarUrl":"","isAuthenticated":false,"canAccessAdmin":false,"isModerator":false,"requiresEmailVerification":false,"adminPermissions":[]},"sidebar":{"categories":[{"id":6,"label":"GooseForum","url":"/c/GooseForum/6","color":"#41d641"},{"id":7,"label":"AI","url":"/c/AI/7","color":"#b941d6"},{"id":4,"label":"Coding","url":"/c/Coding/4","color":"#8241d6"},{"id":8,"label":"吐槽/脑洞","url":"/c/happy/8","color":"#5d41d6"},{"id":10,"label":"HelpMe","url":"/c/HelpMe/10","color":"#41d644"},{"id":11,"label":"Game","url":"/c/Game/11","color":"#d66e41"}],"activeKey":"category_4"},"footer":{"links":[{"name":"RSS","url":"/rss.xml"},{"name":"Site Map","url":"/sitemap.xml"},{"name":"GooseForum","url":"https://github.com/leancodebox/GooseForum"}],"primary":["GooseForum © 2024"]},"unread":{"notifications":false,"messages":false,"moderationReports":false},"theme":{"enabled":true,"href":"/site-theme.css?v=3535d0c163954d2c","colors":{"gf-dark":"#101418","gf-light":"#fbfdff"},"current":"gf-light","themeColor":"#fbfdff"}},"url":"https://gooseforum.online/p/post/334","version":"1.0"}</script>

    <div id="goose-app" aria-live="polite"></div>

    <noscript>
        

<main>
    <article>
        <h1>php[027]fiber</h1>
        <p>大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。 拿平时大家写的...</p>
        <p>
            
            
            <a href="/c/Coding/4" rel="tag">Coding</a>
            
            
            <a href="/u/1">abandon1a2b</a>
            <time datetime="2022-09-05T20:40:00&#43;08:00">2022-09-05 20:40:00</time>
            <time datetime="2025-12-30T20:46:43&#43;08:00">更新于 2025-12-30 20:46:43</time>
            <span>0 回复</span>
            <span>0 赞</span>
            <span>501 浏览</span>
        </p>
        <div>
            <blockquote>
<p>大家的电脑应该都是大等于2核的了，但是大家电脑上同时运行的程序大多远远多于cpu的核心数量。这是因为操作系统在任务处理上采取了宏观上并行，微观上串行的做法。也就是cpu每个程序都执行了一点点时间然后就切换去执行别的程序。使得大家看上去都执行了很多。现在 php8.1 。推出了 fiber 。把调度权利赋予给了各位 php 开发。那么我们有 fiber 我们可以实现什么样的新操作呢。</p>
</blockquote>
<p>拿平时大家写的 for 循环举例。像 go 你可以写两个 <code>go</code> 每个里面各写一个循环同时输入，你可以看到输出是交替。在过去的php版本中，如果只开启一个 cli 写多个 for 循环，那么他的输出一定是顺序的。无法做到交叉输出（也就是无法在第一个循环中执行若干次后，让b再执行，b执行一段时间后，再让A执行）。现在借助 fiber 我们也可以实现这种操作。下面这段代码就可以做到两个循环交叉执行。甚至可以控制两个程序执行的频率（比如A执行3次，B执行一次这样分配）</p>
<!-- raw HTML omitted -->
<pre><code class="language-php">&lt;?php
$t1    = false;
$t2    = false;
$reg   = [];
$reg[] = new \Fiber(function () use (&amp;$t1) {
    for ($i = 1; $i &lt; 10; $i++) {
        echo $i;
        echo PHP_EOL;
        \Fiber::suspend();

    }
    $t1 = true;
});


$reg[] = new \Fiber(function () use (&amp;$t2) {
    for ($i = 1; $i &lt; 10; $i++) {
        echo $i;
        echo PHP_EOL;
        \Fiber::suspend();
    }
    $t2 = true;
});

$startTag = true;
while (count($reg) &gt; 1) {

    if ($startTag) foreach ($reg as $pI) {
        $pI-&gt;start();
        $startTag = false;
    }

    foreach ($reg as $pI) {
        $pI-&gt;resume();
    }

    if ($t1 === true &amp;&amp; $t2 === true) {
        break;
    }
}
</code></pre>
<pre><code>1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
</code></pre>
<p>你甚至可以控制两个循环的执行频率，比如 第一个循环 执行3次后，第二个循环执行一次。代码如下</p>
<pre><code class="language-php">&lt;?php
$reg = [];
$fId = 1;


$reg[$fId] = new \Fiber(function () use (&amp;$reg, $fId) {
    for ($i = 1; $i &lt; 10; $i++) {
        echo $fId . ':' . $i;
        echo PHP_EOL;
        if ($i % 3 == 0) {
            \Fiber::suspend();
        }
    }
    unset($reg[$fId]);
});
$fId++;

$reg[$fId] = new \Fiber(function () use (&amp;$reg, $fId) {
    for ($i = 1; $i &lt; 10; $i++) {
        echo $fId . ':' . $i;
        echo PHP_EOL;
        \Fiber::suspend();
    }
    unset($reg[$fId]);
});

$startTag = true;
while (count($reg) &gt; 0) {
    if ($startTag) foreach ($reg as $pI) {
        $pI-&gt;start();
        $startTag = false;
    }
    foreach ($reg as $pI) {
        $pI-&gt;resume();
    }
}

</code></pre>
<pre><code>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
</code></pre>
<p>通过消息通知完成</p>
<pre><code class="language-php">&lt;?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
            -&gt;addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
            -&gt;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 &lt; 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 &lt; 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) &gt; 0) {
            if ($startTag) foreach ($reg as $pI) {
                $pI-&gt;start();
                $startTag = false;
            }
            foreach ($reg as $key =&gt; $pI) {
                $r = $pI-&gt;resume();
                if ($r-&gt;status === Status::Stop) {
                  unset($reg[$key]);
                }
            }
        }


        return Command::SUCCESS;
    }
}

class SuspendData
{
    public readonly Status $status;

    public function __construct($status)
    {
        $this-&gt;status = $status;
    }
}

enum Status
{
    case Stop;
    case Running;
}
</code></pre>
<p>欢迎大家补充</p>

        </div>
    </article>

    
</main>


    </noscript>
</body>
</html>





