国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

php異步編程

antyiwei / 1552人閱讀

摘要:配合或者自身的已經可以滿足很多請求異步化的需求。協程與異步既然協程可以被中斷,那么只要在程序發起請求后發起事件循環,然后用返回,然后程序繼續執行主程序部分,等事件返回后觸發函數,執行或來繼續執行協程部分。

前言

我對 php 異步的知識還比較混亂,寫這篇是為了整理,可能有錯。

傳統的 php-fpm 一個進程執行一個請求,要達到多少并發,就要生成多少個進程。更糟糕的是每次請求都需要重新編譯執行,導致并發一直上不來。因此出現了 Swoole 和 WorkerMan 兩個國內流行的常駐內存框架[1]。這兩個框架原理都是通過事件循環,讓程序一直停留在內存,等待外部請求,達到高并發。

為什么需要異步 先來看一個例子

在工作目錄下新建文件 slowServer.php


開啟服務

$ php -S localhost:8081 slowServer.php

開另一個終端,安裝依賴

$ pecl install event # 安裝 event 擴展
$ composer require workerman/workerman
$ composer require react/http-client:^0.5.9

新建文件 worker.php

require_once __DIR__ . "/vendor/autoload.php";
use WorkermanWorker;
use WorkermanConnectionAsyncTcpConnection;
use AmpArtaxResponse;

$http_worker = new Worker("http://0.0.0.0:8082");

$http_worker->count = 1; // 只開一個進程

$http_worker->onMessage = function($connection, $host) {
    echo 1;
    $data = file_get_contents("http://localhost:8081");
    $connection->send($data);
};

Worker::runAll();

開啟服務器

php worker.php start

在瀏覽器開啟兩個標簽,都打開網址 http://localhost:8082 。這時可以看到終端輸出“1”,過了一會兒又輸出“1”,原因是8081服務器在處理第一個請求的時候阻塞在了等待8081返回之中,等第一個請求結束后,才開始處理第二個請求。也就是說請求是一個一個執行的,要達到多少個并發,就要建立多少個進程,跟 php-fpm 一樣。現在修改一下代碼

$http_worker->onMessage = function($connection, $host) {
    echo 1;
    $loop    = Worker::getEventLoop();
    $client  = new ReactHttpClientClient($loop);
    $request = $client->request("GET", "http://localhost:8081");
    $request->on("error", function(Exception $e) use ($connection) {
        $connection->send($e);
    });
    $request->on("response", function ($response) use ($connection) {
        $response->on("data", function ($data) use ($connection) {
            $connection->send($data);
        });
    });
    $request->end();
};

現在打開服務,再在瀏覽器發起請求,發現第二個“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

add();
$eventBase->loop(); // 開始循環

開始執行

$ php react.php

在另一個終端執行

telnet 127.0.0.1 8081

這時就會看到第一個終端輸出"1"。

我之前寫過一篇文章《php使用epoll》,是這篇文章的基礎。那篇文章里事件回調是通過定時來實現,即

$event->add($seconds);

而這里,事件回調是通過檢測 fd 是否有寫入內容來實現,這個過程不需要 cpu 參與。當 fd 有內容寫入時,會調函數 "react",這時開始使用 cpu。如果這時候進程執行另一個異步請求,比如用 reactphp 框架請求一個網頁,那么程序會讓出 cpu,此時如果有另一個請求進來,就可以回調執行另一個 "react" 函數。由此提高了并發量。

協程 生成器 Generater

這是生成器的 PHP 官方文檔 http://php.net/manual/zh/lang...


生成器就是每次程序執行到 yield 的時候保存狀態,然后返回 $i,是否繼續執行 gen_one_to_three 里的循環,取決于主程序是否繼續調用

什么是協程

上面的程序另一種寫法是


由此可見,協程就是一種對函數的封裝,使其變成一種可以被中斷的函數,行為更像是子進程或子線程,而不是函數。協程的具體寫法這里不細寫,因為協程的寫法十分復雜,可能需要再做一層封裝才能好用。

協程與異步

既然協程可以被中斷,那么只要在程序發起請求后發起事件循環,然后用 yield 返回,然后程序繼續執行主程序部分,等事件返回后觸發函數,執行 Generatot::next() 或 Generator::send() 來繼續執行協程部分。封裝好后就好像沒有異步回調函數一樣,和同步函數很像。

現在已經有 ampphp 和 swoole 兩個框架封裝了協程,有興趣可以了解一下。


國外還有 https://amphp.org 和 https://reactphp.org 這兩個框架

博客地址:http://b.ljj.pub

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30010.html

相關文章

  • PHP并發IO編程之路

    摘要:下文如無特殊聲明將使用進程同時表示進程線程。收到數據后服務器程序進行處理然后使用向客戶端發送響應。現在各種高并發異步的服務器程序都是基于實現的,比如。 并發 IO 問題一直是服務器端編程中的技術難題,從最早的同步阻塞直接 Fork 進程,到 Worker 進程池/線程池,到現在的異步IO、協程。PHP 程序員因為有強大的 LAMP 框架,對這類底層方面的知識知之甚少,本文目的就是詳細介...

    Riddler 評論0 收藏0
  • nodejs異步編程詳解

    摘要:四異步編程解決方案模式模式一定程度上緩解了嵌套回調的問題,只會處在未完成完成態失敗態中的一種,只會從未完成轉化為完成態或者失敗態,不能逆轉。 一、從一個簡單的案例開始 fs.readdir(path.join(__dirname, ./index.js), (err, files) => { files.foreach((filename, index) => { ...

    inapt 評論0 收藏0
  • PHP異步編程異步的本質

    摘要:實現異步的方式有哪些提供了一些異步方法那它們底層是用哪種方式實現的呢實現異步的方式有線程方式進程方式復用線程方式和進程方式類似有異步請求時開一個線程或者進程獲取到數據后線程間可以直接共享數據進程間可以通過進程通信機制,如共享內存管道等方式進 實現異步的方式有哪些? swoole提供了一些異步方法, 那它們底層是用哪種方式實現的呢? 實現異步的方式有: 線程方式 進程方式 IO復用 ...

    lushan 評論0 收藏0
  • PHP異步編程: 基于PHP實(chao)現(xi) NODEJS web框架KOA

    摘要:異步編程基于實現框架說明偶然間在上看到有贊官方倉庫的手把手教你實現與。由于此前用過,對于的洋蔥模型嘆為觀止。文檔中是基于擴展進行開發,而對并不友好,向來習慣在下開發的我一鼓作氣,將改寫并兼容了此項目。 PHP異步編程: 基于 PHP 實(chao)現(xi) NODEJS web框架 KOA 說明 偶然間在 GITHUB 上看到有贊官方倉庫的 手把手教你實現co與Koa 。由于此前用過...

    freewolf 評論0 收藏0
  • 聊聊 2018 年后端技術趨勢

    摘要:現在在后端業務開發編程方面,技術力量強的團隊已經開始將技術棧從同步模式切換為異步了。使用這些技術方案是無法兼容已有程序的。影響了異步回調技術棧的普及。將會成為未來后端開發領域的主流技術方案。 今天太忙,少寫一點,后面再補充。 異步模式 Go 語言越來越熱門,很多大型互聯網公司后端正在轉向 GO 。Java 圈知名的服務化框架 Dubbo 也宣布轉型異步模式。這是一個大趨勢,異步模式已經...

    Miyang 評論0 收藏0

發表評論

0條評論

antyiwei

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<