非同步編程 - php如何非同步地執行代碼?

來源:互聯網
上載者:User
比如要記錄些日誌資料,我並不需要即時入庫,我想代碼非同步執行後立馬執行下面的代碼,我也並不需要回調處理,如果把資料發給訊息佇列,這也需要時間吧,我想在毫秒級就繼續下面的代碼了,至於他把資料傳給誰,入庫花了多少時間我並不關心,舉個例子,
echo 1;
log(資料);
echo 2;
我想log函數後台執行,至於花多少時間,我不管,但是我不用去等待他,對於我來說就是毫秒級執行完了似的。

回複內容:

比如要記錄些日誌資料,我並不需要即時入庫,我想代碼非同步執行後立馬執行下面的代碼,我也並不需要回調處理,如果把資料發給訊息佇列,這也需要時間吧,我想在毫秒級就繼續下面的代碼了,至於他把資料傳給誰,入庫花了多少時間我並不關心,舉個例子,
echo 1;
log(資料);
echo 2;
我想log函數後台執行,至於花多少時間,我不管,但是我不用去等待他,對於我來說就是毫秒級執行完了似的。

發給訊息佇列 VS 毫秒層級 >>> 矛盾點在哪裡?

用 Redis 可以做隊列吧,Redis 操作每秒讀寫上萬次 ,你把訊息放到 Redis 裡面也就 1次寫操作吧,時間消耗低於毫秒吧。
所以我覺得 使用隊列,完全可以達到你說的毫秒級的需求吧。

另外,不管通過何種手段執行非同步作業,總要伴隨時間開銷,不可避免。

//程式被阻塞10秒shell_exec('timeout 10 vmstat 1 >/dev/null 2>&1 &');//程式不會被阻塞pclose(popen('timeout 10 vmstat 1 >/dev/null 2>&1 &', 'r'));//因此可以非同步執行任務pclose(popen("timeout 60 php /path/to/task.php '$arg' >/dev/null 2>&1 &", 'r'));

其中變數$arg是傳遞給指令碼task.php的參數,task.php裡通過$argv[1]拿到這個參數.
timeout 60 表示task.php指令碼的最大執行時間60秒,不需要的話可以去掉.
pclose(popen())實現非同步本質是開啟一個進程去執行阻塞代碼,
適用於不要求執行完成後自動返回結果(回調)的非同步情境.

字串參數$arg可以用單引號括起來,可以避免一些空格的影響,但還是有缺陷.
字串參數最好還是serialize序列化到檔案,
然後給指令碼task.php傳檔案路徑這個參數,
讓task.php自己讀檔案unserialize還原序列化拿資料.
檔案名稱應該做到唯一,比如可以是使用者ID或者進程PID加上時間隨機數:

$filename = md5(uniqid($uid.'_',        true));$filename = md5(uniqid($getmypid().'_', true));
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.