<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 使用類靜態變量/全局變量保存上下文 [TOC] 多個協程是并發執行的,因此不能使用類靜態變量/全局變量保存協程上下文內容。使用局部變量是安全的,因為局部變量的值會自動保存在協程棧中,其他協程訪問不到協程的局部變量。 ## 實例 #### 錯誤的代碼 ~~~ $_array = []; $serv->on("Request", function ($req, $resp){ global $_array; //請求 /a(協程 1 ) if ($request->server['request_uri'] == '/a') { $_array['name'] = 'a'; co::sleep(1.0); echo $_array['name']; $resp->end($_array['name']); } //請求 /b(協程 2 ) else { $_array['name'] = 'b'; $resp->end(); } }); ~~~ 發起`2`個并發請求。 ~~~ curl http://127.0.0.1:9501/a curl http://127.0.0.1:9501/b ~~~ * 協程`1`中設置了全局變量`$_array['name']`的值為`a` * 協程`1`調用`co::sleep`掛起 * 協程`2`執行,將`$_array['name']`的值為`b`,協程2結束 * 這時定時器返回,底層恢復協程1的運行。而協程1的邏輯中有一個上下文的依賴關系。當再次打印`$_array['name']`的值時,程序預期是`a`,但這個值已經被協程`2`所修改,實際結果卻是`b`,這樣就造成了邏輯錯誤 * 同理,使用類靜態變量`Class::$array`、全局對象屬性`$object->array`、其他超全局變量`$GLOBALS`等,進行上下文保存在協程程序中是非常危險的。可能會出現不符合預期的行為。 ## 使用 Context 管理上下文 * 可以使用一個`Context`類來管理協程上下文,在`Context`類中,使用`Coroutine::getUid`獲取了協程`ID`,然后隔離不同協程之間的全局變量 * 協程退出時清理上下文數據 #### Context ~~~ use Swoole\Coroutine; class Context { protected static $pool = []; static function get($key) { $cid = Coroutine::getuid(); if ($cid < 0) { return null; } if(isset(self::$pool[$cid][$key])){ return self::$pool[$cid][$key]; } return null; } static function put($key, $item) { $cid = Coroutine::getuid(); if ($cid > 0) { self::$pool[$cid][$key] = $item; } } static function delete($key = null) { $cid = Coroutine::getuid(); if ($cid > 0) { if($key){ unset(self::$pool[$cid][$key]); }else{ unset(self::$pool[$cid]); } } } } ~~~ #### 正確的代碼 ~~~ $serv->on("Request", function ($req, $resp) { if ($request->server['request_uri'] == '/a') { Context::put('name', 'a'); co::sleep(1.0); echo Context::get('name'); $resp->end(Context::get('name')); //退出協程時清理 Context::delete('name'); } else { Context::put('name', 'b'); $resp->end(); //退出協程時清理 Context::delete(); } }); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看