golang grqueue

前言

工作以來(lái)做項(xiàng)目大部分的使用的輪子(第三方庫(kù))都是一些大牛寫(xiě)好開(kāi)源出來(lái)的蟆盐,自己只是拼拼湊湊利用現(xiàn)有的輪子完成工作就算完事了。現(xiàn)在我也來(lái)造個(gè)小輪子吧室谚,不過(guò)這個(gè)輪子是在寫(xiě)測(cè)試程序和分析程序時(shí)提取的毡鉴,并沒(méi)有用在線上項(xiàng)目中。這里記錄下來(lái)秒赤,也看看有沒(méi)有人用得上猪瞬。

簡(jiǎn)介

grqueue是goroutine queue是縮寫(xiě),實(shí)際是一個(gè)利用goroutine實(shí)現(xiàn)的一個(gè)同步隊(duì)列入篮,用于程序中可同步任務(wù)的并發(fā)執(zhí)行陈瘦,可以減少等待時(shí)間。比如批量日志分析潮售,并發(fā)請(qǐng)求等等痊项。

原理及實(shí)現(xiàn)

qrqueue的原理很簡(jiǎn)單,利用channel將需要執(zhí)行的task存起來(lái)酥诽,通過(guò)go routine不斷從channel中取出task執(zhí)行鞍泉,再利用官方sync包的WaitGroup等待執(zhí)行完畢。具體routine的數(shù)量和channel的容量可以由使用者自定義盆均,使用者也可以設(shè)置回調(diào)函數(shù)用于處理每個(gè)task結(jié)束后和所有task結(jié)束時(shí)需要處理的事務(wù)塞弊。簡(jiǎn)單畫(huà)了個(gè)圖

實(shí)現(xiàn)代碼也很簡(jiǎn)單,一百行不到泪姨,具體可以看看代碼和注釋游沿,各位發(fā)現(xiàn)有問(wèn)題或者可改進(jìn)的點(diǎn)歡迎拍磚評(píng)論。

package grqueue

import (
    "sync"
)

type GoroutineQueue struct {
    Number int //并發(fā)執(zhí)行的任務(wù)個(gè)數(shù)
    Total  int //總?cè)蝿?wù)數(shù)

    tasks             chan func() interface{}
    task_end_callback func(result interface{})
    finish_callback   func()

        wg sync.WaitGroup
}

func NewGoroutineQueue(number int, total int) *GoroutineQueue {
    queue := &GoroutineQueue{
        tasks:  make(chan func() interface{}, total),
        Number: number,
        Total:  total}
    return queue
}



//開(kāi)始執(zhí)行task
func (queue *GoroutineQueue) Start() {
    defer close(queue.tasks)
    //加鎖肮砾,鎖的數(shù)量是tasks的數(shù)量
    queue.wg.Add(len(queue.tasks))
    for i := 0; i < queue.Number; i++ {

        //分number個(gè)routine執(zhí)行work
        go queue.work()
    }

    //等待routine執(zhí)行完畢
    queue.wg.Wait()

    //所有task完畢诀黍,若finish回調(diào)函數(shù)存在則執(zhí)行則回調(diào)
    if queue.finish_callback != nil {
        queue.finish_callback()
    }
}

func (queue *GoroutineQueue) work() {

    for {

        //不斷取出task執(zhí)行,直到chan關(guān)閉
        task, ok := <-queue.tasks
        if !ok {
            break
        }
        res := task()

        //完成一個(gè)task立即回調(diào)
        if queue.task_end_callback != nil {
            queue.task_end_callback(res)
        }

        //每執(zhí)行完一個(gè)task仗处,解鎖一次
        wg.Done()
    }

}

func (queue *GoroutineQueue) AddTask(task func() interface{}) {
    queue.tasks <- task
}
func (queue *GoroutineQueue) SetFinishCallback(callback func()) {
    queue.finish_callback = callback
}
func (queue *GoroutineQueue) SetTaskEndCallback(callback func(result interface{})) {
    queue.task_end_callback = callback
}

使用

代碼已放github眯勾,直接使用直接go get就可以了

go get github.com/yaodd/grqueue

使用示例在github的README有寫(xiě),這里就不重復(fù)敘述了婆誓。

以上

--------------2018-03-23更新-------------
實(shí)際項(xiàng)目中應(yīng)用發(fā)現(xiàn)wg不應(yīng)該作為全局變量使用吃环,而是應(yīng)該作為GoroutineQueue成員變量使用,已修正洋幻。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末郁轻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌好唯,老刑警劉巖竭沫,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異骑篙,居然都是意外死亡蜕提,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門靶端,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谎势,“玉大人,你說(shuō)我怎么就攤上這事躲查∷常” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵镣煮,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鄙麦,道長(zhǎng)典唇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任胯府,我火速辦了婚禮介衔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘骂因。我一直安慰自己炎咖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布寒波。 她就那樣靜靜地躺著乘盼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪俄烁。 梳的紋絲不亂的頭發(fā)上绸栅,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音页屠,去河邊找鬼粹胯。 笑死,一個(gè)胖子當(dāng)著我的面吹牛辰企,可吹牛的內(nèi)容都是我干的风纠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼牢贸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼竹观!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起十减,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤栈幸,失蹤者是張志新(化名)和其女友劉穎愤估,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體速址,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玩焰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芍锚。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昔园。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖并炮,靈堂內(nèi)的尸體忽然破棺而出默刚,到底是詐尸還是另有隱情,我是刑警寧澤逃魄,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布荤西,位于F島的核電站,受9級(jí)特大地震影響伍俘,放射性物質(zhì)發(fā)生泄漏邪锌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一癌瘾、第九天 我趴在偏房一處隱蔽的房頂上張望觅丰。 院中可真熱鬧,春花似錦妨退、人聲如沸妇萄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)冠句。三九已至,卻和暖如春萍丐,著一層夾襖步出監(jiān)牢的瞬間轩端,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工逝变, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留基茵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓壳影,卻偏偏與公主長(zhǎng)得像拱层,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宴咧,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容