版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第第頁(yè)解析Go語(yǔ)言的高級(jí)特性:Goland貓
對(duì)于大型的互聯(lián)網(wǎng)應(yīng)用程序,如電商平臺(tái)、社交(網(wǎng)絡(luò))、金融交易平臺(tái)等,每秒鐘都會(huì)收到大量的請(qǐng)求。在這些應(yīng)用程序中,需要使用高效的技術(shù)來應(yīng)對(duì)高并發(fā)的請(qǐng)求,尤其是在短時(shí)間內(nèi)處理大量的請(qǐng)求,如1分鐘百萬(wàn)請(qǐng)求。
同時(shí),為了降低用戶的使用門檻和提升用戶體驗(yàn),前端需要實(shí)現(xiàn)參數(shù)的無(wú)感知傳遞。這樣用戶在使用時(shí),無(wú)需擔(dān)心參數(shù)傳遞的問題,能夠輕松地享受應(yīng)用程序的服務(wù)。
在處理1分鐘百萬(wàn)請(qǐng)求時(shí),需要使用高效的技術(shù)和(算法),以提高請(qǐng)求的響應(yīng)速度和處理能力。Go語(yǔ)言以其高效性和并發(fā)性而聞名,因此成為處理高并發(fā)請(qǐng)求的優(yōu)秀選擇。Go中有多種模式可供選擇,如基于gorou(ti)ne和channel的并發(fā)模型、使用池技術(shù)的協(xié)程模型等,以便根據(jù)具體應(yīng)用的需要來選擇適合的技術(shù)模式。
本文代碼參考搬至
W1
W1結(jié)構(gòu)體類型,它有五個(gè)成員:
WgSend用于等待任務(wù)發(fā)送的goroutine完成。
Wg用于等待任務(wù)處理的goroutine完成。
MaxNum表示goroutine池的大小。
Ch是一個(gè)字符串類型的通道,用于傳遞任務(wù)。
DispatchStop是一個(gè)空結(jié)構(gòu)體類型的通道,用于停止任務(wù)分發(fā)。
type
W1
struct
{
WgSend
*sync.W(ai)tGroup
Wg
*sync.WaitGroup
MaxNum
int
Ch
chan
string
DispatchStop
chan
struct{}}
接下來是Dispatch方法,它將任務(wù)發(fā)送到通道Ch中。它通過f(or)循環(huán)來發(fā)送10倍于MaxNum的任務(wù),每個(gè)任務(wù)都是一個(gè)goroutine。defer語(yǔ)句用于在任務(wù)完成時(shí)減少WgSend的計(jì)數(shù)。select語(yǔ)句用于在任務(wù)分發(fā)被中止時(shí)退出任務(wù)發(fā)送。
Dispatch
func
(w
*W1)
Dispatch(job
string)
{
w.WgSend.(Ad)d(10
*
w.MaxNum)
for
i
:=
0;
i
StartPool
然后是StartPool方法,它創(chuàng)建了一個(gè)goroutine池來處理從通道Ch中讀取到的任務(wù)。
如果通道Ch還沒有被創(chuàng)建,那么它將被創(chuàng)建。如果計(jì)數(shù)器WgSend還沒有被創(chuàng)建,那么它也將被創(chuàng)建。如果計(jì)數(shù)器Wg還沒有被創(chuàng)建,那么它也將被創(chuàng)建。
如果通道DispatchStop還沒有被創(chuàng)建,那么它也將被創(chuàng)建。
for循環(huán)用于創(chuàng)建MaxNum個(gè)goroutine來處理從通道中讀取到的任務(wù)。defer語(yǔ)句用于在任務(wù)完成時(shí)減少Wg的計(jì)數(shù)。
func
(w
*W1)
StartPool()
{
if
w.Ch
==
nil
{
w.Ch
=
make(chan
string,
w.MaxNum)
}
if
w.WgSend
==
nil
{
w.WgSend
=
i
Stop
最后是Stop方法,它停止任務(wù)分發(fā)并等待所有任務(wù)完成。
它關(guān)閉了通道DispatchStop,等待WgSend中的任務(wù)發(fā)送goroutine完成,然后關(guān)閉通道Ch,等待Wg中的任務(wù)處理goroutine完成。
func
(w
*W1)
Stop()
{
close(w.DispatchStop)
w.WgSend.Wait()
close(w.Ch)
w.Wg.Wait()}
W2
(Sub)Worker
type
SubWorker
struct
{
JobChan
chan
string}
子協(xié)程,它有一個(gè)JobChan,用于接收任務(wù)。
Run:SubWorker的方法,用于啟動(dòng)一個(gè)子協(xié)程,從JobChan中讀取任務(wù)并執(zhí)行。
func
(sw
*SubWorker)
Run(wg
*sync.WaitGroup,
poolCh
chan
chan
string,
quitCh
chan
struct{})
{
if
sw.JobChan
==
nil
{
sw.JobChan
=
make(chan
string)
}
wg.Add(1)
go
func()
{
defer
wg.Done()
for
{
poolCh
W2
type
W2
struct
{
SubWorke(rs)
[]SubWorker
Wg
*sync.WaitGroup
MaxNum
int
ChPool
chan
chan
string
QuitChan
chan
struct{}}
Dispatch
Dispatch:W2的方法,用于從ChPool中獲取TaskChan,將任務(wù)發(fā)送給一個(gè)SubWorker執(zhí)行。
func
(w
*W2)
Dispatch(job
string)
{
jobChan
:=
StartPool
StartPool:W2的方法,用于初始化協(xié)程池,啟動(dòng)所有子協(xié)程并把TaskChan存儲(chǔ)在ChPool中。
func
(w
*W2)
StartPool()
{
if
w.ChPool
==
nil
{
w.ChPool
=
make(chan
chan
string,
w.MaxNum)
}
if
w.SubWorkers
==
nil
{
w.SubWorkers
=
make([]SubWorker,
w.MaxNum)
}
if
w.Wg
==
nil
{
w.Wg
=
i
Stop
Stop:W2的方法,用于停止協(xié)程的工作,并等待所有協(xié)程結(jié)束。
func
(w
*W2)
Stop()
{
close(w.QuitChan)
w.Wg.Wait()
close(w.ChPool)}
DealW2函數(shù)則是整個(gè)協(xié)程池的入口,它通過NewWorker方法創(chuàng)建一個(gè)W2實(shí)例,然后調(diào)用StartPool啟動(dòng)協(xié)程池,并通過Dispatch發(fā)送任務(wù),最后調(diào)用Stop停止協(xié)程池。
func
DealW2(max
int)
{
w
:=
NewWorker(w2,
max)
w.StartPool()
for
i
:=
0;
i
個(gè)人見解
看到這里對(duì)于w2我已經(jīng)有點(diǎn)迷糊了,還能傳遞w.Wg,w.ChPool,w.QuitChan?
原來是golang里如果方法傳遞的不是地址,那么就會(huì)做一個(gè)拷貝,所以這里調(diào)用的wg根本就不是一個(gè)對(duì)象。傳遞的地方傳遞地址就可以了,如果不傳遞地址,將會(huì)出現(xiàn)死鎖go
doSomething(i,
i
但是有幾個(gè)點(diǎn)需要注意
1.沒有考慮JobChan通道的緩沖區(qū)大小,如果有大量任務(wù)被并發(fā)分配,容易導(dǎo)致內(nèi)存占用過高;
2.每個(gè)線程都會(huì)執(zhí)行無(wú)限循環(huán),此時(shí)線程退出的條件是接收到QuitChan通道的信號(hào),可能導(dǎo)致線程的阻塞等問題;
3.Dispatch函數(shù)的默認(rèn)情況下只會(huì)輸出"Allworkersbusy",而不是阻塞,這意味著當(dāng)所有線程都處于忙碌狀態(tài)時(shí),任務(wù)會(huì)丟失
4.線程池啟動(dòng)后無(wú)法動(dòng)態(tài)擴(kuò)展或縮小。
優(yōu)化
這個(gè)優(yōu)化版本改了很多次。有一些需要注意的點(diǎn)是,不然會(huì)一直死鎖
1.使用sync.WaitGroup來確保線程池中所有線程都能夠啟動(dòng)并運(yùn)行;2.在Stop函數(shù)中,先向SubWorker的JobChan中發(fā)送一個(gè)關(guān)閉信號(hào),再等待所有SubWorker線程退出;3.在Dispatch函數(shù)中,將默認(rèn)情況下的輸出改為阻塞等待可用通道;
w2new
package
handle_million_requestsimport
(
"fmt"
"sync"
"time")type
SubWorkerNew
struct
{
Id
int
JobChan
chan
string}type
W2New
struct
{
SubWorkers
[]SubWorkerNew
MaxNum
int
ChPool
chan
chan
string
QuitChan
chan
struct{}
Wg
*sync.WaitGroup}func
NewW2(maxNum
int)
*W2New
{
chPool
:=
make(chan
chan
string,
maxNum)
subWorkers
:=
make([]SubWorkerNew,
maxNum)
for
i
:=
0;
i
1
{
worker
:=
w.SubWorkers[w.MaxNum-1]
close(worker.JobChan)
w.MaxNum--
w.SubWorkers
=
w.SubWorkers[:w.MaxNum]
}}
AddWorker和RemoveWorker,用于動(dòng)態(tài)擴(kuò)展/縮小線程池。
在AddWorker函數(shù)中,我們首先將MaxNum增加了1,然后創(chuàng)建一個(gè)新的SubWorkerNew結(jié)構(gòu)體,將其添加到SubWorkers中,并將其JobChan通道添加到ChPool通道中。最后,我們創(chuàng)建一個(gè)新的協(xié)程來處理新添加的SubWorkerNew并讓它進(jìn)入無(wú)限循環(huán),等待接收任務(wù)。
在RemoveWorker函數(shù)中,我們首先將MaxNum減少1,然后獲取最后一個(gè)SubWorkerNew結(jié)構(gòu)體,將它的JobChan通道發(fā)送到ChPool通道中,并從其通道中讀取任何待處理的任務(wù),最后創(chuàng)建一個(gè)新的協(xié)程來處理SubWorkerNew,繼續(xù)處理任務(wù)。
測(cè)試用例
func
(Te)stW2New(t
*testing.T)
{
pool
:=
NewW2(3)
pool.StartPool()
pool.Dispatch("task
1")
pool.Dispatch("task
2")
pool.Dispatch("task
3")
pool.AddWorker()
pool.AddWorker()
pool.RemoveWorker()
pool.Stop()
}
當(dāng)Dispatch函數(shù)向ChPool通道獲取可用通道時(shí),會(huì)從通道中取出一個(gè)SubWorker的JobChan通道,并將任務(wù)發(fā)送到該通道中。而對(duì)于SubWorker來說,并沒有進(jìn)行任務(wù)的使用次數(shù)限制,所以它可以處理多個(gè)任務(wù)。
在這個(gè)例子中,當(dāng)任務(wù)數(shù)量比SubWorker數(shù)量多時(shí),一個(gè)SubWorker的JobChan通道會(huì)接收到多個(gè)任務(wù),它們會(huì)在SubWorker的循環(huán)中按順序依次處理,直到JobChan中沒有未處理的任務(wù)為止。因此,如
溫馨提示
- 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度綠色金融借款合同示范文本4篇
- 2025年度門面房租賃合同(含裝修限制條款)4篇
- 二零二五年度高品質(zhì)木枋原料供應(yīng)合同4篇
- 2025年度企業(yè)財(cái)務(wù)合規(guī)審計(jì)聘用合同
- 二零二五年度噴砂機(jī)銷售及零配件供應(yīng)合同4篇
- 2025版彩鋼房倉(cāng)儲(chǔ)服務(wù)合同范本3篇
- 二零二五年度苗木種植與生態(tài)城市建設(shè)合同4篇
- 二零二四年度智能校園物業(yè)管理與服務(wù)合同下載3篇
- 2025年度園林綠化養(yǎng)護(hù)勞務(wù)承包合同樣本2篇
- 二零二五年度創(chuàng)業(yè)投資借款合作協(xié)議合同-@-1
- 化學(xué)-河南省TOP二十名校2025屆高三調(diào)研考試(三)試題和答案
- 智慧農(nóng)貿(mào)批發(fā)市場(chǎng)平臺(tái)規(guī)劃建設(shè)方案
- 林下野雞養(yǎng)殖建設(shè)項(xiàng)目可行性研究報(bào)告
- 2023年水利部黃河水利委員會(huì)招聘考試真題
- Python編程基礎(chǔ)(項(xiàng)目式微課版)教案22
- 01J925-1壓型鋼板、夾芯板屋面及墻體建筑構(gòu)造
- 欠電費(fèi)合同范本
- 2024年新高考地區(qū)數(shù)學(xué)選擇題填空壓軸題匯編十八含解析
- 大型商場(chǎng)招商招租方案(2篇)
- 2022年袋鼠數(shù)學(xué)競(jìng)賽真題一二年級(jí)組含答案
- 三氟乙酰氯(CAS:354-32-5)理化性質(zhì)及危險(xiǎn)特性表
評(píng)論
0/150
提交評(píng)論