<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## redis 實現鎖 ```php // 其他服務 不在注冊 register_shutdown_function 而是添加 事件 $shutdownEvent = []; // 注冊一個會在php中止時執行的函數 register_shutdown_function('shutdown_function'); function shutdown_function() { global $shutdownEvent; // 執行注冊的事件 foreach ($shutdownEvent as $key => $f) { if (is_callable($f)) { $f(); } } $e = error_get_last(); if ($e) { $errorInfo = friendlyErrorType($e['type']); // print_r($e); switch ($e['type']) { case E_PARSE: case E_ERROR: case E_CORE_ERROR: case E_COMPILE_ERROR: case E_USER_ERROR: $errorStr = "appErrorHandler: type: {$e['type']} ({$errorInfo[0]} - {$errorInfo[1]}); message: {$e['message']}; file: {$e['file']}; line: {$e['line']}"; trace($errorStr, 'run_error'); trace('[shutdown_function:trace]', '', true); error(1, $errorStr); break; } } // 寫入日志 trace('[shutdown_function:trace]', '', true); } // 使用 redis實現的簡單無阻塞的鎖(沒有考慮復雜的情況) // https://www.cnblogs.com/fengff/p/10913492.html function lock($key, $ok, $gone) { global $redis, $shutdownEvent; $roomid = 'room_' . time() . rand(1, 9999); // 初始化一個空函數防止下面報錯,任何環節,代碼節點都有可能發生異常甚至不確定性故障 $delLock = function () { }; // trace('lock: ' . $key . PHP_EOL, '>debug-lock'); // exit; try { $isLockOk = $redis->setNX($key, $roomid); // var_dump($isLockOk);exit; if ($isLockOk) { // 獲得鎖 // echo PHP_EOL . 'lock ok!' . PHP_EOL . PHP_EOL; // 防止A進程獲得鎖后,由于A執行時間太長,鎖被回收了 // 此時B獲得鎖,等A執行完畢,刪除時刪除了B持有鎖,它以為刪除的是自己的,因為它并不是到自己的鎖被回收了 // 設置過期是因為防止任務掛了鎖沒被回收,這個問題不會有了,所以我們不設置過期 // 不能因為 執行時間長的 設置過期,不然還會有兩個進行并發了 // 但是為了規范嚴謹,我們刪除時還是嚴格檢查 $delLock = function () use ($key, $redis, $roomid) { if ($redis->get($key) == $roomid) { $redis->del($key); trace('delLock: ' . $key . ' ' . $roomid . PHP_EOL, '>debug-lock'); // echo 'delLock: ' . $key . ' ' . $roomid . PHP_EOL; } }; // trace('lock: ok!', '>debug-lock'); // 能保存上下文 // 像js的閉包一樣,贊! $shutdownEvent['unLock'] = function () use ($key, $redis, $roomid, $delLock) { // 只有發生錯誤時,才使用事件刪除key // ctrl + c 退出就沒辦法了(不算異常),除非能獲取腳本推出code if (!error_get_last()) { return; } // 獲取了鎖的腳本,腳本退出時 刪也沒事 // ctrl + c 退出 register_shutdown_function 不會執行 // 這種情況那就只有使用信號了 trace('shutdownEvent unLock: ' . $key . ' ' . $roomid . PHP_EOL, '>debug-lock'); // echo 'shutdownEvent unLock: ' . $key . ' ' . $roomid . PHP_EOL; // $redis 連接也可能失效,刪除有很多種失敗的情況 // 只能盡量將最容易失敗的地方處理好 $delLock(); }; // 注意: 注冊事件這段代碼必須放在這里: 獲得鎖之后 - 執行代碼之前 , 不可預料的 出錯主要是在 $ok() 這里 // trace('lock: ok -> shutdownEvent', '>debug-lock'); $res = $ok(); // 如果任務發生錯誤崩了,這下面不會執行,但是沒關系 shutdownEvent 事件還會執行 $delLock(); // unset($shutdownEvent['unLock']); // 如果 沒異常,delLock() 順利執行了,就不用繼續執行事件了 } else { // 當前已在運行,直接退出 // echo PHP_EOL . 'Be gone' . PHP_EOL . PHP_EOL; $res = $gone(); } } catch (\Exception $e) { $delLock(); throw $e; } // appErrorHandler: type: 1 (E_ERROR - 致命錯誤); message: Class 'sModel' not found; file: D:\wamp64\www\patent_management_system\include\rockFun.php; line: 564 // todo: 如果出現致命錯誤,會導致 key 沒刪掉 // https://www.php.net/manual/zh/function.register-shutdown-function.php // 是可以多次注冊的,是追加不是覆蓋,沒有問題 // 只注冊一次 // 這個無法 實現只注冊一次 // register_shutdown_function(); // 改用 注冊 shutdown 事件,框架調用 // 即使這樣肯定也不能萬無一失 return $res; } ``` ---- ### 用法: ```php // 使任務保持“單例”執行 lock('lock_' . $fun, function () use ($fun) { $fun(); }, function () use ($fun) { echo "crontab_run: {$fun} task running ..." . PHP_EOL; // 如果當前任務已經在執行了,就什么都不做 }); ``` ---- ### 待實現 - 可重入 - 阻塞等特性 ...
                  <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>

                              哎呀哎呀视频在线观看