宅男在线永久免费观看网直播,亚洲欧洲日产国码无码久久99,野花社区在线观看视频,亚洲人交乣女bbw,一本一本久久a久久精品综合不卡

全部
常見問題
產(chǎn)品動態(tài)
精選推薦

swoole的強大之處,你可能只是略知一二!

管理 管理 編輯 刪除

首先 swoole 是 php 的一個擴展程序

swoole 是一個為 php 用 c 和 c++ 編寫的基于事件的高性能異步 & 協(xié)程并行網(wǎng)絡(luò)通信引擎

swoole 是一個多進程模型的框架,當(dāng)啟動一個進程 swoole 應(yīng)用時,一共會創(chuàng)建 2+n+m 個進程,n 為 worker 進程數(shù),m 為 TaskWorker 進程數(shù),1 個 master 進程和一個 manager 進程,關(guān)系如下圖所示

Master 進程為主進程,該進程會創(chuàng)建 Manager 進程、Reactor 線程等工作進 / 線程

c9dd3202302221845054868.png

1、Reactor 線程:

  • 負(fù)責(zé)維護客戶端 TCP 連接、處理網(wǎng)絡(luò) IO、處理協(xié)議、收發(fā)數(shù)據(jù)
  • 完全是異步非阻塞的模式
  • 全部為 C 代碼,除 Start/Shudown 事件回調(diào)外,不執(zhí)行任何 PHP 代碼
  • TCP 客戶端發(fā)來的數(shù)據(jù)緩沖、拼接、拆分成完整的一個請求數(shù)據(jù)包
  • Reactor 以多線程的方式運行

2、Worker 進程:

  • 接受由 Reactor 線程投遞的請求數(shù)據(jù)包,并執(zhí)行 PHP 回調(diào)函數(shù)處理數(shù)據(jù)
  • 生成響應(yīng)數(shù)據(jù)并發(fā)給 Reactor 線程,由 Reactor 線程發(fā)送給 TCP 客戶端
  • 可以是異步非阻塞模式,也可以是同步阻塞模式
  • Worker 以多進程的方式運行

3、TaskWorker 進程 :

  • 接受由 Worker 進程通過 swoole_server->task/taskwait 方法投遞的任務(wù)
  • 處理任務(wù),并將結(jié)果數(shù)據(jù)返回(使用 swoole_server->finish)給 Worker 進程
  • 完全是同步阻塞模式
  • TaskWorker 以多進程的方式運行

A: 網(wǎng)絡(luò)通信引擎

網(wǎng)絡(luò)通信引擎,是為 php 提供網(wǎng)絡(luò)通信能力的,傳統(tǒng)的 php 程序都是啟動 php-fpm,前邊再有一層 nginx 或者 apache,打開瀏覽器訪問就 OK,但是從瀏覽器訪問到服務(wù)器這一階段涉及到了網(wǎng)絡(luò)強求,但是這一階段跟 php 腳本沒有任何的關(guān)系,php 只需要處理好數(shù)據(jù)生成需要展示的內(nèi)容就完成使命了,聲明周期當(dāng)中,請求到來前和請求完成后都沒有 php 腳本什么事,而 swoole 提供的一大能力就是擴展了 php 的生命周期,無需 php-fpm 或者 nginx 或者 apache 之類的工具幫助就可以啟動一個 web 服務(wù),并且從服務(wù)啟動前,啟動后,鏈接進入,請求到來,請求結(jié)束,鏈接切斷,服務(wù)終止都在 php 腳本的掌控之中,這樣的話 php 腳本就會涉及到大量的網(wǎng)絡(luò)通訊處理,而這個網(wǎng)絡(luò)通訊處理的能力正是來源于 swoole! 網(wǎng)絡(luò)通信引擎,是為 php 提供網(wǎng)絡(luò)通信能力的,傳統(tǒng)的 php 程序都是啟動 php-fpm,前邊再有一層 nginx 或者 apache,打開瀏覽器訪問就 OK,但是從瀏覽器訪問到服務(wù)器這一階段涉及到了網(wǎng)絡(luò)強求,但是這一階段跟 php 腳本沒有任何的關(guān)系,php 只需要處理好數(shù)據(jù)生成需要展示的內(nèi)容就完成使命了,聲明周期當(dāng)中,請求到來前和請求完成后都沒有 php 腳本什么事,而 swoole 提供的一大能力就是擴展了 php 的生命周期,無需 php-fpm 或者 nginx 或者 apache 之類的工具幫助就可以啟動一個 web 服務(wù),并且從服務(wù)啟動前,啟動后,鏈接進入,請求到來,請求結(jié)束,鏈接切斷,服務(wù)終止都在 php 腳本的掌控之中,這樣的話 php 腳本就會涉及到大量的網(wǎng)絡(luò)通訊處理,而這個網(wǎng)絡(luò)通訊處理的能力正是來源于 swoole!

B:基于事件的高性能異步

同步:

f4e25202302221845386680.png

就拿讀取文件內(nèi)容來說吧

file_get_contents () 執(zhí)行完才能執(zhí)行下邊的代碼 這樣就很容易造成程序的阻塞

否則下邊的代碼就無法輸出文件的內(nèi)容

傳統(tǒng) php 都是這樣阻塞式的順序執(zhí)行的

這是常見的同步編程

異步:

e3e13202302221846042990.png

代碼在執(zhí)行到 ajax 的時候,函數(shù)會直接返回,你馬上就可以看到屏幕上打印出的 lol

這就是異步,這樣你永遠不會被 IO 阻塞,但是它帶來了新的問題,在你運行到 lol 之后你就不知道現(xiàn)在代碼運行到哪里去了,你只能等待回調(diào)被觸發(fā),然后屏幕上打印響應(yīng)的 log, 它的執(zhí)行不是單層順序的,而是嵌套的

如果在業(yè)務(wù)代碼當(dāng)中 這樣層層嵌套可讀性可想而知

當(dāng)然這是前端異步請求后端接口

swoole 當(dāng)中處理異步回調(diào)嵌套使用的是協(xié)程

你知道什么叫協(xié)程嗎?你知道線程是干啥的嗎?你又知道進程嗎?

如果想深入了解 swoole 的強大之處 你還得要了解傳統(tǒng) php 的 lnmp 環(huán)境的整套運行機制,這些你都了解嗎?

目前 swoole 當(dāng)中的異步也是協(xié)程化的,所以你必須充分理解協(xié)程到底是個什么東西!

C:協(xié)程

到底什么是協(xié)程?

通俗的說,協(xié)程就是一段段協(xié)作方式執(zhí)行的程序,協(xié)作來完成一件事,協(xié)作就是協(xié)同作業(yè)。我們知道團隊協(xié)同來做事,比個人單獨來做事,效率肯定要高,因為團隊協(xié)同可以發(fā)揮各成員的能動性、優(yōu)勢互補。這是拿人來比喻。我們拿做事來比喻舉個例子:比如我們做飯,比如有以下環(huán)節(jié)洗菜、切菜、燒水、炒菜、煮米飯,人作為主體來操作,那么如果按部就班的做,先燒水,再洗菜,在切菜,再炒菜,再煮飯,那這頓飯要做很長時間比如總共 30 分鐘吧,如果我們通過協(xié)同方式,先燒水,放灶火上就可以做其他洗菜、切菜的準(zhǔn)備,再煮米飯,然后再來洗菜、切菜,再查看煮米飯,再炒菜,…,如此循環(huán)往復(fù)切換,最后水燒好,米飯也煮好了,菜也炒好了,飯也 OK 了,這樣我們耗時可能只有 10-15 分鐘,看到了嗎,這就是生活中的 “協(xié)程”,由人來合理調(diào)度安排不同的環(huán)節(jié),充分利用各種不同的資源和時間,來達到提高效率。協(xié)程是計算機程序,調(diào)用的則是不同的程序,處理者主要由 CPU 完成,處理對象是各種 IO 資源,處理的方式是不同的語言編寫的程序。我們知道,CPU 可以調(diào)度不同的程序,讓程序調(diào)用不同的 IO 資源,最初的進程是通過 CPU 頻繁的切換來完成調(diào)用程序的,是操作系統(tǒng)按一定算法分配的時間片搶占被動方式來切換的,未考慮程序?qū)嶋H執(zhí)行狀況,這樣切換程序會帶來一定問題,而協(xié)程作為一種新的工作模式,可以讓程序協(xié)作方式來執(zhí)行,在需要使用 CPU 時,交給程序處理,遇到耗時的 IO 資源操作時會讓出 CPU,交給處理其他程序,這樣互相協(xié)作來執(zhí)行,而不是搶占式的,就像交通規(guī)則,大家都遵守按一定規(guī)則禮讓先行,不隨便搶道,協(xié)同方式,程序都會執(zhí)行的良好。

我們來看具體的案例:


go(function () {
    echo "hello go1 \n";
});
echo "hello main \n";
go(function () {
    echo "hello go2 \n";
});

上面的代碼執(zhí)行結(jié)果:


root@b98940b00a9b /v/w/c/p/swoole# php co.php
hello go1
hello main
hello go2

執(zhí)行結(jié)果和我們平時寫代碼的順序,好像沒啥區(qū)別。實際執(zhí)行過程:

  • 運行此段代碼,系統(tǒng)啟動一個新進程
  • 遇到 go(), 當(dāng)前進程中生成一個協(xié)程,協(xié)程中輸出 heelo go1, 協(xié)程退出
  • 進程繼續(xù)向下執(zhí)行代碼,輸出 hello main
  • 再生成一個協(xié)程,協(xié)程中輸出 heelo go2, 協(xié)程退出

我們來稍微改一改,體驗協(xié)程的調(diào)度:


use Co;
go(function () {
Co::sleep(1); // 只新增了一行代碼
echo "hello go1 \n";
});
echo "hello main \n";
go(function () {
echo "hello go2 \n";
});

\Co::sleep () 函數(shù)功能和 sleep () 差不多,但是它模擬的是 IO 等待 (IO 后面會細講). 執(zhí)行的結(jié)果如下:


root@b98940b00a9b /v/w/c/p/swoole# php co.php
hello main
hello go2
hello go1

怎么不是順序執(zhí)行的呢?實際執(zhí)行過程:

  • 運行此段代碼,系統(tǒng)啟動一個新進程
  • 遇到 go(), 當(dāng)前進程中生成一個協(xié)程
  • 協(xié)程中遇到 IO 阻塞 (這里是 Co::sleep() 模擬出的 IO 等待), 協(xié)程讓出控制,進入?yún)f(xié)程調(diào)度隊列
  • 進程繼續(xù)向下執(zhí)行,輸出 hello main
  • 執(zhí)行下一個協(xié)程,輸出 hello go2
  • 之前的協(xié)程準(zhǔn)備就緒,繼續(xù)執(zhí)行,輸出 hello go1

到這里,已經(jīng)可以看到 swoole 中 協(xié)程與進程的關(guān)系 , 以及 協(xié)程的調(diào)度 , 我們再改一改剛才的程序


go(function () {
Co::sleep(1);
echo "hello go1 \n";
});
echo "hello main \n";
go(function () {
Co::sleep(1);
echo "hello go2 \n";
});

我想你已經(jīng)知道輸出是什么樣子了:


root@b98940b00a9b /v/w/c/p/swoole# php co.php
hello main
hello go1
hello go2

協(xié)程快在哪?減少 IO 阻塞導(dǎo)致的性能損失

大家可能聽到使用協(xié)程的最多的理由,可能就是 協(xié)程快. 那看起來和平時寫得差不多的代碼,為什么就要快一些呢?一個常見的理由是,可以創(chuàng)建很多個協(xié)程來執(zhí)行任務(wù),所以快. 這種說法是對的,不過還停留在表面

首先,一般的計算機任務(wù)分為 2 種

  • CPU 密集型,比如加減乘除等科學(xué)計算
  • IO 密集型,比如網(wǎng)絡(luò)請求,文件讀寫等
    其次,高性能相關(guān)的 2 個概念
    • 并行:同一個時刻,同一個 CPU 只能執(zhí)行同一個任務(wù),要同時執(zhí)行多個任務(wù),就需要有多個 CPU 才行
    • 并發(fā):由于 CPU 切換任務(wù)非??欤斓饺祟惪梢愿兄臉O限,就會有很多任務(wù) 同時執(zhí)行 的錯覺


了解了這些,我們再來看協(xié)程,協(xié)程適合的是 IO 密集型 應(yīng)用,因為協(xié)程在 IO 阻塞 時會自動調(diào)度,減少 IO 阻塞導(dǎo)致的時間損失!

協(xié)程在遇到 IO 阻塞的時候會讓出 cpu 的控制權(quán),其他協(xié)程拿到去執(zhí)行其他協(xié)程的任務(wù),當(dāng) IO 阻塞過去之后回過頭來繼續(xù)往下執(zhí)行!

要點:

  1. 協(xié)程在阻塞的時候只是阻塞了當(dāng)前這個協(xié)程 并不會阻塞整個的進程 因為協(xié)程是在線程內(nèi)部的,即使阻塞了也會讓出控制權(quán),掛起,等待當(dāng)前協(xié)程的 IO 不阻塞在回過頭來繼續(xù)執(zhí)行,也就是同步的代碼完成了異步的功能!相當(dāng)強悍!
  2. 從宏觀的角度看,程序員搞出來的多個協(xié)程在不發(fā)生任何協(xié)程阻塞的前提是是順序執(zhí)行的 一旦發(fā)生阻塞 你可以把多個協(xié)程理解為并行的 同時在執(zhí)行的!
  3. 協(xié)程是在單進程單線程當(dāng)中實現(xiàn)的 你可以在里面實現(xiàn)成千上萬的協(xié)程 并且效果極高! 每個協(xié)程去干不同的事!協(xié)作制的無需加鎖沒有搶占,串行的!什么叫串行呢?每次執(zhí)行一個協(xié)程 遇到 IO 阻塞 掛起 執(zhí)行接下來的程序 可能還是個協(xié)程 如果再遇到 IO 阻塞再掛起 繼續(xù)往下執(zhí)行 當(dāng) IO 阻塞完成回過頭來繼續(xù)往下執(zhí)行沒執(zhí)行完的協(xié)程程序 每次都是一個協(xié)程在執(zhí)行,串行化的!
  4. 協(xié)程之間每秒可以進行百萬千萬次切換! 線程之間切換需要加鎖 加鎖就很浪費資源!進程間切換更浪費資源,因為上線文很大!更多詳細內(nèi)容請自行百度!
  5. 協(xié)程很小切換還快 每秒百萬千萬級別的切換 所以 一個進程里面 只要你的內(nèi)存夠用 你就可以無止境的創(chuàng)造協(xié)程出來干事情!
  6. 事件驅(qū)動和異步為 swoole 提供了高性能 而協(xié)程解決了異步回調(diào)代碼嵌套的問題 提高了代碼可讀性和維護性 也是 swoole 最大的特色!

d:混合服務(wù)器

你可以隨意創(chuàng)建一個 http tcp websocket http2 服務(wù) 并且能輕松承載成千上萬的請求

這個可以去官網(wǎng) 看如何創(chuàng)建 http 服務(wù) tcp 服務(wù) websocket 服務(wù)

websocket 是 http 升級而來的 創(chuàng)建了 websocket 服務(wù)就自帶了 http 服務(wù)

創(chuàng)建好服務(wù) 直接 start 就可以運行一個 http 服務(wù)或者其他 tcp 等的服務(wù)了 而無需 nginx apache 的任何參與!

有服務(wù)端必有客戶端 我們可以在代碼里面通過
new Swoole\Coroutine\Http\Client(127.0.0.1,9501);
去鏈接 http 服務(wù)器

當(dāng)然其他的也一樣 自己去看手冊 這里只是說明 swoole 有多么的強大

e:協(xié)程之間通訊 channel

通道(channel)是協(xié)程之間通信交換數(shù)據(jù)的唯一渠道,而協(xié)程 + 通道的開發(fā)組合即為著名的 csp 編程模型

在 swoole 當(dāng)中 channel 常用于連接池的實現(xiàn)和協(xié)程并發(fā)的調(diào)度

如圖所示 第一個協(xié)程執(zhí)行完成之后我們會往 channel 通道當(dāng)中 push 一個元素 第二個也是 當(dāng)然第一個一定是 IO 阻塞的 第二個沒有 我們在 for 循環(huán)里面 獲取 channel 里面的值的時候由于第一個阻塞 $chan->pop () 也是阻塞的 因為整體都是在一個協(xié)程里面 只有當(dāng)大的協(xié)程里面的兩個小協(xié)程都完成了 這里的 $chan->pop 才會執(zhí)行 接觸阻塞 最后才會執(zhí)行 echo 語句! 這是 swoole 當(dāng)中協(xié)程并發(fā)的一個很好的案例應(yīng)用

1f375202302221846441751.png

f:毫秒定時器

毫秒定時器是異步回調(diào)的方式來實現(xiàn)的!

還可以使用協(xié)程方式 采用同步阻塞的方式來實現(xiàn)定時器!
之前用 sleep 會阻塞整個進程 現(xiàn)在你在協(xié)程里面搞 Co:sleep (0.1) 阻塞的是當(dāng)前協(xié)程 而不會阻塞整個進程!

b5d61202302221847257673.png


請登錄后查看

徐斗明 最后編輯于2023-09-11 16:59:08

快捷回復(fù)
回復(fù)
回復(fù)
回復(fù)({{post_count}}) {{!is_user ? '我的回復(fù)' :'全部回復(fù)'}}
排序 默認(rèn)正序 回復(fù)倒序 點贊倒序

{{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level || item.bbs_level }}

作者 管理員 企業(yè)

{{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
{{item.is_suggest == 1? '取消推薦': '推薦'}}
沙發(fā) 板凳 地板 {{item.floor}}#
{{item.user_info.title || '暫無簡介'}}
附件

{{itemf.name}}

{{item.created_at}}  {{item.ip_address}}
打賞
已打賞¥{{item.reward_price}}
{{item.like_count}}
{{item.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)

{{itemc.user_info.nickname}}

{{itemc.user_name}}

回復(fù) {{itemc.comment_user_info.nickname}}

附件

{{itemf.name}}

{{itemc.created_at}}
打賞
已打賞¥{{itemc.reward_price}}
{{itemc.like_count}}
{{itemc.showReply ? '取消回復(fù)' : '回復(fù)'}}
刪除
回復(fù)
回復(fù)
查看更多
打賞
已打賞¥{{reward_price}}
2151
{{like_count}}
{{collect_count}}
添加回復(fù) ({{post_count}})

相關(guān)推薦

快速安全登錄

使用微信掃碼登錄
{{item.label}} 加精
{{item.label}} {{item.label}} 板塊推薦 常見問題 產(chǎn)品動態(tài) 精選推薦 首頁頭條 首頁動態(tài) 首頁推薦
取 消 確 定
回復(fù)
回復(fù)
問題:
問題自動獲取的帖子內(nèi)容,不準(zhǔn)確時需要手動修改. [獲取答案]
答案:
提交
bug 需求 取 消 確 定
打賞金額
當(dāng)前余額:¥{{rewardUserInfo.reward_price}}
{{item.price}}元
請輸入 0.1-{{reward_max_price}} 范圍內(nèi)的數(shù)值
打賞成功
¥{{price}}
完成 確認(rèn)打賞

微信登錄/注冊

切換手機號登錄

{{ bind_phone ? '綁定手機' : '手機登錄'}}

{{codeText}}
切換微信登錄/注冊
暫不綁定
CRMEB客服

CRMEB咨詢熱線 咨詢熱線

400-8888-794

微信掃碼咨詢

CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
返回頂部 返回頂部
CRMEB客服