PHP協(xié)程中Go+Chan+Defer的示例分析

這篇文章主要為大家展示了“PHP協(xié)程中Go+Chan+Defer的示例分析”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“PHP協(xié)程中Go+Chan+Defer的示例分析”這篇文章吧。

10年的淅川網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都營(yíng)銷網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整淅川建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“淅川網(wǎng)站設(shè)計(jì)”,“淅川網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

Swoole4為PHP語(yǔ)言提供了強(qiáng)大的CSP協(xié)程編程模式。底層提供了3個(gè)關(guān)鍵詞,可以方便地實(shí)現(xiàn)各類功能

Swoole4提供的PHP協(xié)程語(yǔ)法借鑒自Golang,在此向GO開(kāi)發(fā)組致敬

PHP+Swoole協(xié)程可以與Golang很好地互補(bǔ)。Golang:靜態(tài)語(yǔ)言,嚴(yán)謹(jǐn)強(qiáng)大性能好,PHP+Swoole:動(dòng)態(tài)語(yǔ)言,靈活簡(jiǎn)單易用

關(guān)鍵詞

  •  go :創(chuàng)建一個(gè)協(xié)程

  •  chan :創(chuàng)建一個(gè)通道

  •  defer :延遲任務(wù),在協(xié)程退出時(shí)執(zhí)行,先進(jìn)后出

這3個(gè)功能底層實(shí)現(xiàn)全部為內(nèi)存操作,沒(méi)有任何IO資源消耗。就像PHP的Array一樣是非常廉價(jià)的。如果有需要就可以直接使用。這與socket和file操作不同,后者需要向操作系統(tǒng)申請(qǐng)端口和文件描述符,讀寫可能會(huì)產(chǎn)生阻塞的IO等待。

協(xié)程并發(fā)

使用go函數(shù)可以讓一個(gè)函數(shù)并發(fā)地去執(zhí)行。在編程過(guò)程中,如果某一段邏輯可以并發(fā)執(zhí)行,就可以將它放置到go協(xié)程中執(zhí)行。

順序執(zhí)行

function test1()   {      sleep(1);      echo "b";  }  function test2()   {      sleep(2);      echo "c";  }  test1();  test2();

執(zhí)行結(jié)果:

htf@LAPTOP-0K15EFQI:~$ time php b1.php  bc  real    0m3.080s  user    0m0.016s  sys     0m0.063s  htf@LAPTOP-0K15EFQI:~$

上述代碼中,test1和test2會(huì)順序執(zhí)行,需要3秒才能執(zhí)行完成。

并發(fā)執(zhí)行

使用go創(chuàng)建協(xié)程,可以讓test1和test2兩個(gè)函數(shù)變成并發(fā)執(zhí)行。

Swoole\Runtime::enableCoroutine();  go(function ()   {      sleep(1);      echo "b";  });    go(function ()   {      sleep(2);      echo "c";  });

Swoole\Runtime::enableCoroutine()作用是將PHP提供的stream、sleep、pdo、MySQLi、redis等功能從同步阻塞切換為協(xié)程的異步IO

執(zhí)行結(jié)果:

bchtf@LAPTOP-0K15EFQI:~$ time php co.php  bc  real    0m2.076s  user    0m0.000s  sys     0m0.078s  htf@LAPTOP-0K15EFQI:~$

可以看到這里只用了2秒就執(zhí)行完成了。

  •  順序執(zhí)行耗時(shí)等于所有任務(wù)執(zhí)行耗時(shí)的總和 :t1+t2+t3...

  •  并發(fā)執(zhí)行耗時(shí)等于所有任務(wù)執(zhí)行耗時(shí)的***值 :max(t1, t2, t3, ...)

協(xié)程通信

有了go關(guān)鍵詞之后,并發(fā)編程就簡(jiǎn)單多了。與此同時(shí)又帶來(lái)了新問(wèn)題,如果有2個(gè)協(xié)程并發(fā)執(zhí)行,另外一個(gè)協(xié)程,需要依賴這兩個(gè)協(xié)程的執(zhí)行結(jié)果,如果解決此問(wèn)題呢?

答案就是使用通道(Channel),在Swoole4協(xié)程中使用new chan就可以創(chuàng)建一個(gè)通道。通道可以理解為自帶協(xié)程調(diào)度的隊(duì)列。它有兩個(gè)接口push和pop:

  •  push:向通道中寫入內(nèi)容,如果已滿,它會(huì)進(jìn)入等待狀態(tài),有空間時(shí)自動(dòng)恢復(fù)

  •  pop:從通道中讀取內(nèi)容,如果為空,它會(huì)進(jìn)入等待狀態(tài),有數(shù)據(jù)時(shí)自動(dòng)恢復(fù)

使用通道可以很方便地實(shí)現(xiàn)并發(fā)管理。

$chan = new chan(2);  # 協(xié)程1  go (function () use ($chan) {      $result = [];      for ($i = 0; $i < 2; $i++)      {          $result += $chan->pop();      }      var_dump($result);  });  # 協(xié)程2  go(function () use ($chan) {     $cli = new Swoole\Coroutine\Http\Client('www.qq.com', 80);         $cli->set(['timeout' => 10]);         $cli->setHeaders([         'Host' => "www.qq.com",         "User-Agent" => 'Chrome/49.0.2587.3',         'Accept' => 'text/html,application/xhtml+xml,application/xml',         'Accept-Encoding' => 'gzip',     ]);     $ret = $cli->get('/');     // $cli->body 響應(yīng)內(nèi)容過(guò)大,這里用 Http 狀態(tài)碼作為測(cè)試     $chan->push(['www.qq.com' => $cli->statusCode]);  });  # 協(xié)程3  go(function () use ($chan) {     $cli = new Swoole\Coroutine\Http\Client('www.163.com', 80);     $cli->set(['timeout' => 10]);     $cli->setHeaders([         'Host' => "www.163.com",         "User-Agent" => 'Chrome/49.0.2587.3',         'Accept' => 'text/html,application/xhtml+xml,application/xml',         'Accept-Encoding' => 'gzip',     ]);     $ret = $cli->get('/');     // $cli->body 響應(yīng)內(nèi)容過(guò)大,這里用 Http 狀態(tài)碼作為測(cè)試     $chan->push(['www.163.com' => $cli->statusCode]);  });

執(zhí)行結(jié)果:

htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php co2.php  array(2) {    ["www.qq.com"]=>    int(302)    ["www.163.com"]=>    int(200) }  real    0m0.268s  user    0m0.016s  sys     0m0.109s  htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$

這里使用go創(chuàng)建了3個(gè)協(xié)程,協(xié)程2和協(xié)程3分別請(qǐng)求qq.com和163.com主頁(yè)。協(xié)程1需要拿到Http請(qǐng)求的結(jié)果。這里使用了chan來(lái)實(shí)現(xiàn)并發(fā)管理。

  •  協(xié)程1循環(huán)兩次對(duì)通道進(jìn)行pop,因?yàn)殛?duì)列為空,它會(huì)進(jìn)入等待狀態(tài)

  •  協(xié)程2和協(xié)程3執(zhí)行完成后,會(huì)push數(shù)據(jù),協(xié)程1拿到了結(jié)果,繼續(xù)向下執(zhí)行

延遲任務(wù)

在協(xié)程編程中,可能需要在協(xié)程退出時(shí)自動(dòng)實(shí)行一些任務(wù),做清理工作。類似于PHP的register_shutdown_function,在Swoole4中可以使用defer實(shí)現(xiàn)。

Swoole\Runtime::enableCoroutine();  go(function () {      echo "a";      defer(function () {          echo "~a";      });      echo "b";      defer(function () {          echo "~b";      });      sleep(1);      echo "c";  });

執(zhí)行結(jié)果:

htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$ time php defer.php  abc~b~a  real    0m1.068s  user    0m0.016s  sys     0m0.047s  htf@LAPTOP-0K15EFQI:~/swoole-src/examples/5.0$

以上是“PHP協(xié)程中Go+Chan+Defer的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當(dāng)前標(biāo)題:PHP協(xié)程中Go+Chan+Defer的示例分析
轉(zhuǎn)載源于:http://muchs.cn/article6/pipjig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、搜索引擎優(yōu)化、網(wǎng)站制作、域名注冊(cè)、微信小程序、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化