1. 程式人生 > 實用技巧 >Swoole 中協程的使用注意事項及協程中的異常捕獲

Swoole 中協程的使用注意事項及協程中的異常捕獲

協程使用注意事項

  • 協程內部禁止使用全域性變數,以免發生資料錯亂;
  • 協程使用 use 關鍵字引入外部變數到當前作用域禁止使用引用,以免發生資料錯亂;
  • 不能使用類靜態變數 Class::$array / 全域性變數 $_array / 全域性物件屬性 $object->array / 其他超全域性變數 $GLOBALS 等儲存協程上下文內容,以免發生資料錯亂;
  • 協程之間通訊必須使用通道(Channel);
  • 不能在多個協程間共用一個客戶端連線,以免發生資料錯亂;可以使用連線池實現;
  • 必須在協程內捕獲異常,不得跨協程捕獲異常;
  • __get / __set 魔術方法中不能有協程切換。

協程中的異常捕獲

示例一:協程中使用exit函式丟擲 ExitException 異常

function route()
{
    controller();
}

function controller()
{
    your_code();
}

function your_code()
{
    co::sleep(.001);
    exit(1);
}

go(function () {
    try {
        route();
    } catch (\Swoole\ExitException $e) {
        var_dump($e->getMessage());
        var_dump($e->getStatus() === 1);
        var_dump($e->getFlags());
    }
});

示例二:協程中使用exit函式丟擲 ExitException 異常

$exit_status = 0;
go(function () {
    try {
        exit(123);
    } catch (\Swoole\ExitException $e) {
        global $exit_status;
        $exit_status = $e->getStatus();
    }
});
swoole_event_wait();
var_dump($exit_status);

示例三:協程中直接丟擲 RuntimeException 異常

function test() {
    throw new \RuntimeException(__FILE__, __LINE__);
}

Swoole\Coroutine::create(function () {
    try {
        test();
    }
    catch (\Throwable $e) {
        echo $e;
    }
});