本篇文章給大家帶來的內容是關于php為什么需要異步編程?php異步編程的詳解(附示例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助,
我對 php 異步的知識還比較混亂,寫這篇是為了整理,可能有錯,
傳統的 php-fpm 一個行程執行一個請求,要達到多少并發,就要生成多少個行程,更糟糕的是每次請求都需要重新編譯執行,導致并發一直上不來,因此出現了 Swoole 和 WorkerMan 兩個國內流行的常駐記憶體框架[1],這兩個框架原理都是通過事件回圈,讓程式一直停留在記憶體,等待外部請求,達到高并發,
為什么需要異步
先來看一個例子
在作業目錄下新建檔案 slowServer.php
|
1 2 3 |
|
開啟服務
|
1 |
|
開另一個終端,安裝依賴
|
1 2 3 |
|
新建檔案 worker.php
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
開啟服務器
|
1 |
|
在瀏覽器開啟兩個標簽,都打開網址 http://localhost:8082 ,這時可以看到終端輸出“1”,過了一會兒又輸出“1”,原因是8081服務器在處理第一個請求的時候阻塞在了等待8081回傳之中,等第一個請求結束后,才開始處理第二個請求,也就是說請求是一個一個執行的,要達到多少個并發,就要建立多少個行程,跟 php-fpm 一樣,現在修改一下代碼
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
現在打開服務,再在瀏覽器發起請求,發現第二個“1”在請求后就馬上輸出了,而這時第一個請求還沒結束,這表明行程不再阻塞,并發量取決于 cpu 和 記憶體,而不是行程數,
為什么需要異步
通過上面的例子已經很明白了,reactphp 框架通過把 http 請求變成異步,讓 onMessage 函式變成非阻塞,cpu 可以去處理下一個請求,即從 cpu 回圈等待 8081 回傳,變成了 epoll 等待,
異步的意義在于把 cpu 從 io 等待中解放出來,可以處理其他計算任務, 如果你想知道怎么用框架實作異步,看到這里就可以了,WorkerMan 配合 ReactPHP 或者自身的 AsyncTcpConnection 已經可以滿足很多 io 請求異步化的需求,下面繼續討論這些框架是怎么做到異步的,
哪些地方應該被做成異步
通過上面的例子已經知道一旦執行到不需要 cpu,但是要等待 io 的時候,應該把 io 的程序做成異步,
實作事件回圈
上面的例子是通過 reactphp 把 http 請求變成了異步,其實 WorkerMan 框架本身也是異步的,下面來看看 WorkerMan 是怎么使 onMessage 函式可以異步接受請求,先來新建下面這個檔案 react.php
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
開始執行
|
1 |
|
在另一個終端執行
|
1 |
|
這時就會看到第一個終端輸出'1',
我之前寫過一篇文章《php使用epoll》,是這篇文章的基礎,那篇文章里事件回呼是通過定時來實作,即
|
1 |
|
而這里,事件回呼是通過檢測 fd 是否有寫入內容來實作,這個程序不需要 cpu 參與,當 fd 有內容寫入時,會調函式 'react',這時開始使用 cpu,如果這時候行程執行另一個異步請求,比如用 reactphp 框架請求一個網頁,那么程式會讓出 cpu,此時如果有另一個請求進來,就可以回呼執行另一個 'react' 函式,由此提高了并發量,
協程
生成器 Generater
這是生成器的 PHP 官方檔案 http://php.net/manual/zh/lang...
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
生成器就是每次程式執行到 yield 的時候保存狀態,然后回傳 $i,是否繼續執行 gen_one_to_three 里的回圈,取決于主程式是否繼續呼叫
什么是協程
上面的程式另一種寫法是
|
1 2 3 4 5 6 7 8 9 10 11 12 |
|
由此可見,協程就是一種對函式的封裝,使其變成一種可以被中斷的函式,行為更像是子行程或子執行緒,而不是函式,協程的具體寫法這里不細寫,因為協程的寫法十分復雜,可能需要再做一層封裝才能好用,
協程與異步
既然協程可以被中斷,那么只要在程式發起請求后發起事件回圈,然后用 yield 回傳,然后程式繼續執行主程式部分,等事件回傳后觸發函式,執行 Generatot::next() 或 Generator::send() 來繼續執行協程部分,封裝好后就好像沒有異步回呼函式一樣,和同步函式很像,
現在已經有 ampphp 和 swoole 兩個框架封裝了協程,有興趣可以了解一下,

明確的學習思路能更高效的學習

點擊加入該群學習
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/121056.html
標籤:PHP
上一篇:關于QEMU的問題
