成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

協程篇 | Workerman 5.x 協程上下文 Context

開發 前端
協程是一種比線程更輕量級的用戶級并發機制,能夠在進程中實現多任務調度。它通過手動控制掛起和恢復來實現協程間的切換,避免了進程上下文切換的開銷。workerman提供了一個通用的協程接口,底層自動兼容Swoole/Swow/Fiber驅動。

協程

協程是一種比線程更輕量級的用戶級并發機制,能夠在進程中實現多任務調度。它通過手動控制掛起和恢復來實現協程間的切換,避免了進程上下文切換的開銷。workerman提供了一個通用的協程接口,底層自動兼容Swoole/Swow/Fiber驅動。

提示:此特性需要 workerman>=5.1.0

注意

  • 協程僅支持Swoole Swow Fiber驅動
  • 如果使用Fiber驅動時需要安裝 composer require revolt/event-loop
  • Swoole或者Swow驅動可以實現PHP阻塞函數自動協程化,從而實現原來的同步代碼異步執行
  • 但Fiber無法像Swoole和Swow那樣自動協程化,遇到PHP自帶的阻塞函數時會阻塞整個進程,并不會發生協程切換
  • 當使用Swoole Swow Fiber驅動時,workerman每次運行onWorkerStart onMessage onConnect onClose等回調時會自動創建一個協程來執行
  • 可以利用$worker->eventLoop=xxx;給不同worker設置不同的協程驅動

案例

coroutine.php文件

<?php
declare(strict_types=1);

use Workerman\Connection\TcpConnection;
use Workerman\Coroutine;
use Workerman\Events\Swoole;
use Workerman\Events\Fiber;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

$worker1 = new Worker('http://0.0.0.0:8201');
$worker1->eventLoop = Swoole::class; // 使用Swoole協程
$worker1->onMessage = function (TcpConnection $connection, Request $request) {
    Coroutine::create(function () {
        echo file_get_contents("http://www.baidu.com");
    });
    $connection->send('Swoole ok');
};

$worker2 = new Worker('http://0.0.0.0:8202');
$worker2->eventLoop = Fiber::class; // 使用自帶的Fiber協程
$worker2->onMessage = function (TcpConnection $connection, Request $request) {
    Coroutine::create(function () {
        echo file_get_contents("http://www.baidu.com");
    });
    $connection->send('Fiber ok');
};

Worker::runAll();

啟動服務

php coroutine.php start
Workerman[worker.php] start in DEBUG mode
-------------------------------------------- WORKERMAN ---------------------------------------------
Workerman/5.1.0         PHP/8.3.15 (Jit off)          Linux/5.10.102.1-microsoft-standard-WSL2
--------------------------------------------- WORKERS ----------------------------------------------
event-loop  proto       user        worker      listen                 count       state            
swoole      tcp         root        none        http://0.0.0.0:8201    1            [OK]            
fiber       tcp         root        none        http://0.0.0.0:8202    1            [OK]            
----------------------------------------------------------------------------------------------------
Press Ctrl+C to stop. Start success.

訪問

  • Swoole 服務 :http://127.0.0.1:8201
  • Fiber 服務 :http://127.0.0.1:8202

協程提供的接口

interface CoroutineInterface
{

    /**
     * 創建協程并立即執行
     */
    public static function create(callable $callable, ...$data): CoroutineInterface;

    /**
     * 開始協程運行
     */
    public function start(mixed ...$args): mixed;

    /**
     * 恢復協程運行
     */
    public function resume(mixed ...$args): mixed;

    /**
     * 獲取協程id
     */
    public function id(): int;

    /**
     * 設置協程銷毀時的回調
     */
    public static function defer(callable $callable): void;

    /**
     * 暫停當前協程
     */
    public static function suspend(mixed $value = null): mixed;

    /**
     * 獲取當前協程
     */
    public static function getCurrent(): CoroutineInterface|Fiber|SwowCoroutine|static;

    /**
     * 判斷當前是否是協程環境
     */
    public static function isCoroutine(): bool;

}

關于協程

優勢

PHP引入協程后最大的作用就是可以用同步的方式編寫異步代碼,避免了回調地獄,提高了代碼的可讀性和可維護性。

協程能大幅度提升IO密集型業務的彈性,可以用較少的進程提供更大的吞吐量。

劣勢

但是引入協程后開發者需要時刻注意全局變量污染、資源競爭、第三方庫改造等問題,開發維護成本增大,心智負擔明顯增加。

引入協程后產生了協程創建、調度、銷毀、連接池等額外開銷。通過大量壓測數據來看,在充分利用CPU的情況下,引入協程后極限性能比阻塞式IO下降約10%-20%。

Context 協程上下文

Context用于在協程中存儲和傳遞上下文信息,例如數據庫連接、用戶信息等。每個協程有自己的上下文,不同協程之間的上下文是隔離的。

案例

context.php

<?php

declare(strict_types=1);

use Workerman\Connection\TcpConnection;
use Workerman\Coroutine;
use Workerman\Coroutine\Context;
use Workerman\Events\Swoole;
use Workerman\Protocols\Http\Request;
use Workerman\Worker;

require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker('http://0.0.0.0:8201');

$worker->eventLoop = Swoole::class; // Or Swow::class or Fiber::class

$worker->onWorkerStart = function () {
    Context::set('user_info_onWorkerStart', ['id' => 1, 'name' => 'onWorkerStart']);
};
$worker->onMessage = function (TcpConnection $connection, Request $request) {
    // 協程間context數據是隔離的,所以onMessage協程里獲取onWorkerStart協程里的user_info_onWorkerStart是null
    var_dump(Context::get('user_info_onWorkerStart'));

    // 在當前協程設置context數據
    Context::set('user_info', ['id' => 2025, 'name' => 'Tinywan']);
    // 新建協程
    Coroutine::create(function () use ($connection) {
        // 協程間context數據是隔離的,所以新協程里獲取的是null
        $userInfo = Context::get('user_info');
        var_dump($userInfo); // 輸出null

        Context::set('user_info_new', ['id' => 1, 'name' => 'New Coroutine']);
    });
    // 協程間context數據是隔離的,所以獲取新協程里的數據是null
    var_dump(Context::get('user_info_new')); // 輸出null

    // 獲取當前協程的context數據
    $userInfo = Context::get('user_info'); // 得到['id' => 2025, 'name' => 'Tinywan']
    $connection->send(json_encode($userInfo));
};

Worker::runAll();

啟動服務

php context.php start

訪問服務

請求地址http://127.0.0.1:8201,響應輸出

{
  "id": 2025,
  "name": "Tinywan"
}

接口說明

interface ContextInterface
{
    /**
     * 獲取上下文中的值
     */
    public static function get(string $name, mixed $default = null): mixed;

    /**
     * 設置上下文中的值
     */
    public static function set(string $name, mixed $value): void;

    /**
     * 檢查上下文中是否存在指定名稱的值
     */
    public static function has(string $name): bool;

    /**
     * 重置當前協程上下文
     */
    public static function reset(?ArrayObject $data = null): void;

    /**
     * 銷毀上下文
     */
    public static function destroy(): void;

}


責任編輯:武曉燕 來源: 開源技術小棧
相關推薦

2024-08-27 09:46:39

Go協程效率

2021-09-16 09:59:13

PythonJavaScript代碼

2025-01-26 00:00:15

PHP協程控制權

2023-11-17 11:36:59

協程纖程操作系統

2025-06-26 04:10:00

2023-10-24 19:37:34

協程Java

2021-12-09 06:41:56

Python協程多并發

2021-02-19 06:56:33

架構協程應用

2022-09-06 20:30:48

協程Context主線程

2017-05-02 11:38:00

PHP協程實現過程

2023-08-08 07:18:17

協程管道函數

2023-12-24 12:56:36

協程

2023-11-04 20:00:02

C++20協程

2024-02-05 09:06:25

Python協程Asyncio庫

2020-11-29 17:03:08

進程線程協程

2016-10-28 17:39:47

phpgolangcoroutine

2020-12-17 10:00:16

Python協程線程

2024-06-27 07:56:49

2021-04-25 09:36:20

Go協程線程

2021-08-04 16:19:55

AndroidKotin協程Coroutines
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品黄色 | 99av成人精品国语自产拍 | 1级毛片| 97国产在线视频 | 黑人中文字幕一区二区三区 | 久色视频在线 | 亚洲一区二区在线视频 | 亚洲一区中文字幕在线观看 | 亚洲成人一区 | 国产精品久久久久久婷婷天堂 | 欧美日韩一区精品 | 欧美一级欧美三级在线观看 | 久久精品国产久精国产 | 欧美男人亚洲天堂 | 日韩在线视频一区二区三区 | 黑人一级片视频 | 久久aⅴ乱码一区二区三区 亚洲国产成人精品久久久国产成人一区 | 亚洲视频三区 | av毛片 | 一区二区三区免费 | 成人a视频在线观看 | 毛片免费观看 | 日本亚洲一区 | 国产免费福利在线 | 在线视频日韩 | 欧美成人二区 | 一区精品在线观看 | 亚洲风情在线观看 | 中文字幕 在线观看 | 色婷婷精品国产一区二区三区 | 中文字字幕在线中文乱码范文 | 农村黄性色生活片 | 午夜影院在线观看免费 | 99精品欧美一区二区三区 | 亚洲成人一区 | 成年人黄色一级毛片 | 欧美一区二区三区在线 | av在线播放网址 | 免费黄色的视频 | 欧美在线观看黄色 | 在线一区 |