協程使用注意事項
- 協程內部禁止使用全局變量,以免發生數據錯亂;
- 協程使用
use關鍵字引入外部變量到當前作用域禁止使用引用,以免發生數據錯亂; - 不能使用類靜態變量
Class::$array/ 全局變量$_array/ 全局對象屬性$object->array/ 其他超全局變量$GLOBALS等保存協程上下文內容,以免發生數據錯亂; - 協程之間通訊必須使用通道(Channel);
- 不能在多個協程間共用一個客戶端連接,以免發生數據錯亂;可以使用連接池實現;
- 在 Swoole\Server 中,客戶端連接應當在 onWorkerStart 中創建;
- 在 Swoole\Process 中,客戶端連接應當在 Swoole\Process->start 后,子進程的回調函數中創建;
- 必須在協程內捕獲異常,不得跨協程捕獲異常;
- 在
__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;
}
});
