成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php異步編程

antyiwei / 1578人閱讀

摘要:配合或者自身的已經(jīng)可以滿足很多請(qǐng)求異步化的需求。協(xié)程與異步既然協(xié)程可以被中斷,那么只要在程序發(fā)起請(qǐng)求后發(fā)起事件循環(huán),然后用返回,然后程序繼續(xù)執(zhí)行主程序部分,等事件返回后觸發(fā)函數(shù),執(zhí)行或來(lái)繼續(xù)執(zhí)行協(xié)程部分。

前言

我對(duì) php 異步的知識(shí)還比較混亂,寫這篇是為了整理,可能有錯(cuò)。

傳統(tǒng)的 php-fpm 一個(gè)進(jìn)程執(zhí)行一個(gè)請(qǐng)求,要達(dá)到多少并發(fā),就要生成多少個(gè)進(jìn)程。更糟糕的是每次請(qǐng)求都需要重新編譯執(zhí)行,導(dǎo)致并發(fā)一直上不來(lái)。因此出現(xiàn)了 Swoole 和 WorkerMan 兩個(gè)國(guó)內(nèi)流行的常駐內(nèi)存框架[1]。這兩個(gè)框架原理都是通過(guò)事件循環(huán),讓程序一直停留在內(nèi)存,等待外部請(qǐng)求,達(dá)到高并發(fā)。

為什么需要異步 先來(lái)看一個(gè)例子

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


開啟服務(wù)

$ php -S localhost:8081 slowServer.php

開另一個(gè)終端,安裝依賴

$ pecl install event # 安裝 event 擴(kuò)展
$ 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; // 只開一個(gè)進(jìn)程

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

Worker::runAll();

開啟服務(wù)器

php worker.php start

在瀏覽器開啟兩個(gè)標(biāo)簽,都打開網(wǎng)址 http://localhost:8082 。這時(shí)可以看到終端輸出“1”,過(guò)了一會(huì)兒又輸出“1”,原因是8081服務(wù)器在處理第一個(gè)請(qǐng)求的時(shí)候阻塞在了等待8081返回之中,等第一個(gè)請(qǐng)求結(jié)束后,才開始處理第二個(gè)請(qǐng)求。也就是說(shuō)請(qǐng)求是一個(gè)一個(gè)執(zhí)行的,要達(dá)到多少個(gè)并發(fā),就要建立多少個(gè)進(jìn)程,跟 php-fpm 一樣?,F(xiàn)在修改一下代碼

$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();
};

現(xiàn)在打開服務(wù),再在瀏覽器發(fā)起請(qǐng)求,發(fā)現(xiàn)第二個(gè)“1”在請(qǐng)求后就馬上輸出了,而這時(shí)第一個(gè)請(qǐng)求還沒結(jié)束。這表明進(jìn)程不再阻塞,并發(fā)量取決于 cpu 和 內(nèi)存,而不是進(jìn)程數(shù)。

為什么需要異步

通過(guò)上面的例子已經(jīng)很明白了,reactphp 框架通過(guò)把 http 請(qǐng)求變成異步,讓 onMessage 函數(shù)變成非阻塞,cpu 可以去處理下一個(gè)請(qǐng)求。即從 cpu 循環(huán)等待 8081 返回,變成了 epoll 等待。

異步的意義在于把 cpu 從 io 等待中解放出來(lái),可以處理其他計(jì)算任務(wù)。 如果你想知道怎么用框架實(shí)現(xiàn)異步,看到這里就可以了。WorkerMan 配合 ReactPHP 或者自身的 AsyncTcpConnection 已經(jīng)可以滿足很多 io 請(qǐng)求異步化的需求。下面繼續(xù)討論這些框架是怎么做到異步的。

哪些地方應(yīng)該被做成異步

通過(guò)上面的例子已經(jīng)知道一旦執(zhí)行到不需要 cpu,但是要等待 io 的時(shí)候,應(yīng)該把 io 的過(guò)程做成異步。

實(shí)現(xiàn)事件循環(huán)

上面的例子是通過(guò) reactphp 把 http 請(qǐng)求變成了異步,其實(shí) WorkerMan 框架本身也是異步的,下面來(lái)看看 WorkerMan 是怎么使 onMessage 函數(shù)可以異步接受請(qǐng)求。先來(lái)新建下面這個(gè)文件 react.php

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

開始執(zhí)行

$ php react.php

在另一個(gè)終端執(zhí)行

telnet 127.0.0.1 8081

這時(shí)就會(huì)看到第一個(gè)終端輸出"1"。

我之前寫過(guò)一篇文章《php使用epoll》,是這篇文章的基礎(chǔ)。那篇文章里事件回調(diào)是通過(guò)定時(shí)來(lái)實(shí)現(xiàn),即

$event->add($seconds);

而這里,事件回調(diào)是通過(guò)檢測(cè) fd 是否有寫入內(nèi)容來(lái)實(shí)現(xiàn),這個(gè)過(guò)程不需要 cpu 參與。當(dāng) fd 有內(nèi)容寫入時(shí),會(huì)調(diào)函數(shù) "react",這時(shí)開始使用 cpu。如果這時(shí)候進(jìn)程執(zhí)行另一個(gè)異步請(qǐng)求,比如用 reactphp 框架請(qǐng)求一個(gè)網(wǎng)頁(yè),那么程序會(huì)讓出 cpu,此時(shí)如果有另一個(gè)請(qǐng)求進(jìn)來(lái),就可以回調(diào)執(zhí)行另一個(gè) "react" 函數(shù)。由此提高了并發(fā)量。

協(xié)程 生成器 Generater

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


生成器就是每次程序執(zhí)行到 yield 的時(shí)候保存狀態(tài),然后返回 $i,是否繼續(xù)執(zhí)行 gen_one_to_three 里的循環(huán),取決于主程序是否繼續(xù)調(diào)用

什么是協(xié)程

上面的程序另一種寫法是


由此可見,協(xié)程就是一種對(duì)函數(shù)的封裝,使其變成一種可以被中斷的函數(shù),行為更像是子進(jìn)程或子線程,而不是函數(shù)。協(xié)程的具體寫法這里不細(xì)寫,因?yàn)閰f(xié)程的寫法十分復(fù)雜,可能需要再做一層封裝才能好用。

協(xié)程與異步

既然協(xié)程可以被中斷,那么只要在程序發(fā)起請(qǐng)求后發(fā)起事件循環(huán),然后用 yield 返回,然后程序繼續(xù)執(zhí)行主程序部分,等事件返回后觸發(fā)函數(shù),執(zhí)行 Generatot::next() 或 Generator::send() 來(lái)繼續(xù)執(zhí)行協(xié)程部分。封裝好后就好像沒有異步回調(diào)函數(shù)一樣,和同步函數(shù)很像。

現(xiàn)在已經(jīng)有 ampphp 和 swoole 兩個(gè)框架封裝了協(xié)程,有興趣可以了解一下。


國(guó)外還有 https://amphp.org 和 https://reactphp.org 這兩個(gè)框架

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/30010.html

相關(guān)文章

  • PHP并發(fā)IO編程之路

    摘要:下文如無(wú)特殊聲明將使用進(jìn)程同時(shí)表示進(jìn)程線程。收到數(shù)據(jù)后服務(wù)器程序進(jìn)行處理然后使用向客戶端發(fā)送響應(yīng)?,F(xiàn)在各種高并發(fā)異步的服務(wù)器程序都是基于實(shí)現(xiàn)的,比如。 并發(fā) IO 問(wèn)題一直是服務(wù)器端編程中的技術(shù)難題,從最早的同步阻塞直接 Fork 進(jìn)程,到 Worker 進(jìn)程池/線程池,到現(xiàn)在的異步IO、協(xié)程。PHP 程序員因?yàn)橛袕?qiáng)大的 LAMP 框架,對(duì)這類底層方面的知識(shí)知之甚少,本文目的就是詳細(xì)介...

    Riddler 評(píng)論0 收藏0
  • nodejs異步編程詳解

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

    inapt 評(píng)論0 收藏0
  • PHP異步編程,異步的本質(zhì)

    摘要:實(shí)現(xiàn)異步的方式有哪些提供了一些異步方法那它們底層是用哪種方式實(shí)現(xiàn)的呢實(shí)現(xiàn)異步的方式有線程方式進(jìn)程方式復(fù)用線程方式和進(jìn)程方式類似有異步請(qǐng)求時(shí)開一個(gè)線程或者進(jìn)程獲取到數(shù)據(jù)后線程間可以直接共享數(shù)據(jù)進(jìn)程間可以通過(guò)進(jìn)程通信機(jī)制,如共享內(nèi)存管道等方式進(jìn) 實(shí)現(xiàn)異步的方式有哪些? swoole提供了一些異步方法, 那它們底層是用哪種方式實(shí)現(xiàn)的呢? 實(shí)現(xiàn)異步的方式有: 線程方式 進(jìn)程方式 IO復(fù)用 ...

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

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

    freewolf 評(píng)論0 收藏0
  • 聊聊 2018 年后端技術(shù)趨勢(shì)

    摘要:現(xiàn)在在后端業(yè)務(wù)開發(fā)編程方面,技術(shù)力量強(qiáng)的團(tuán)隊(duì)已經(jīng)開始將技術(shù)棧從同步模式切換為異步了。使用這些技術(shù)方案是無(wú)法兼容已有程序的。影響了異步回調(diào)技術(shù)棧的普及。將會(huì)成為未來(lái)后端開發(fā)領(lǐng)域的主流技術(shù)方案。 今天太忙,少寫一點(diǎn),后面再補(bǔ)充。 異步模式 Go 語(yǔ)言越來(lái)越熱門,很多大型互聯(lián)網(wǎng)公司后端正在轉(zhuǎn)向 GO 。Java 圈知名的服務(wù)化框架 Dubbo 也宣布轉(zhuǎn)型異步模式。這是一個(gè)大趨勢(shì),異步模式已經(jīng)...

    Miyang 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

antyiwei

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<