欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

GolangWaitGroup源碼分析

針對(duì)Golang 1.9的sync.WaitGroup進(jìn)行分析,與Golang 1.10基本一樣除了將panic改為了throw之外其他的都一樣。
源代碼位置:sync\waitgroup.go。

成都創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供社旗網(wǎng)站建設(shè)、社旗做網(wǎng)站、社旗網(wǎng)站設(shè)計(jì)、社旗網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、社旗企業(yè)網(wǎng)站模板建站服務(wù),10余年社旗做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

結(jié)構(gòu)體

type WaitGroup struct {
    noCopy noCopy  // noCopy可以嵌入到結(jié)構(gòu)中,在第一次使用后不可復(fù)制,使用go vet作為檢測(cè)使用
    // 位值:高32位是計(jì)數(shù)器,低32位是goroution等待計(jì)數(shù)。
    // 64位的原子操作需要64位的對(duì)齊,但是32位。編譯器不能確保它,所以分配了12個(gè)byte對(duì)齊的8個(gè)byte作為狀態(tài)。
    state1 [12]byte // byte=uint8范圍:0~255,只取前8個(gè)元素。轉(zhuǎn)為2進(jìn)制:0000 0000,0000 0000... ...0000 0000
    sema   uint32   // 信號(hào)量,用于喚醒goroution
}

不知道大家是否和我一樣,不論是使用Java的CountDownLatch還是Golang的WaitGroup,都會(huì)疑問(wèn),可以裝下多個(gè)線程|協(xié)程等待呢?看了源碼后可以回答了,可以裝下

1111 1111 1111 ... 1111
\________32___________/

2^32個(gè)辣么多!所以不需要擔(dān)心單機(jī)情況下會(huì)被撐爆了。

函數(shù)

以下代碼已經(jīng)去掉了與核心代碼無(wú)關(guān)的race代碼。

Add

添加或者減少等待goroutine的數(shù)量。

參數(shù)delta可能是負(fù)的,加到WaitGroup計(jì)數(shù)器,可能出現(xiàn)如下結(jié)果

  • 如果計(jì)數(shù)器變?yōu)榱?,所有被阻塞的goroutines都會(huì)被釋放。
  • 如果計(jì)數(shù)器變成負(fù)數(shù),就增加恐慌。
func (wg *WaitGroup) Add(delta int) {
    // 獲取到wg.state1數(shù)組中元素組成的二進(jìn)制對(duì)應(yīng)的十進(jìn)制的值
    statep := wg.state()
    // 高32位是計(jì)數(shù)器
    state := atomic.AddUint64(statep, uint64(delta)<<32)
    // 獲取計(jì)數(shù)器
    v := int32(state >> 32)
    w := uint32(state)
    // 計(jì)數(shù)器為負(fù)數(shù),報(bào)panic
    if v < 0 {
        panic("sync: negative WaitGroup counter")
    }
    // 添加與等待并發(fā)調(diào)用,報(bào)panic
    if w != 0 && delta > 0 && v == int32(delta) {
        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
    }
    // 計(jì)數(shù)器添加成功
    if v > 0 || w == 0 {
        return
    }

    // 當(dāng)?shù)却?jì)數(shù)器> 0時(shí),而goroutine設(shè)置為0。
    // 此時(shí)不可能有同時(shí)發(fā)生的狀態(tài)突變:
    // - 增加不能與等待同時(shí)發(fā)生,
    // - 如果計(jì)數(shù)器counter == 0,不再增加等待計(jì)數(shù)器
    if *statep != state {
        panic("sync: WaitGroup misuse: Add called concurrently with Wait")
    }
    // Reset waiters count to 0.
    *statep = 0
    for ; w != 0; w-- {
        // 目的是作為一個(gè)簡(jiǎn)單的wakeup原語(yǔ),以供同步使用。true為喚醒排在等待隊(duì)列的第一個(gè)goroutine
        runtime_Semrelease(&wg.sema, false)
    }
}
// unsafe.Pointer其實(shí)就是類似C的void *,在golang中是用于各種指針相互轉(zhuǎn)換的橋梁。
// uintptr是golang的內(nèi)置類型,是能存儲(chǔ)指針的整型,uintptr的底層類型是int,它和unsafe.Pointer可相互轉(zhuǎn)換。
// uintptr和unsafe.Pointer的區(qū)別就是:unsafe.Pointer只是單純的通用指針類型,用于轉(zhuǎn)換不同類型指針,它不可以參與指針運(yùn)算;
// 而uintptr是用于指針運(yùn)算的,GC 不把 uintptr 當(dāng)指針,也就是說(shuō) uintptr 無(wú)法持有對(duì)象,uintptr類型的目標(biāo)會(huì)被回收。
// state()函數(shù)可以獲取到wg.state1數(shù)組中元素組成的二進(jìn)制對(duì)應(yīng)的十進(jìn)制的值
func (wg *WaitGroup) state() *uint64 {
    if uintptr(unsafe.Pointer(&wg.state1))%8 == 0 {
        return (*uint64)(unsafe.Pointer(&wg.state1))
    } else {
        return (*uint64)(unsafe.Pointer(&wg.state1[4]))
    }
}

Done

相當(dāng)于Add(-1)。

func (wg *WaitGroup) Done() {
    // 計(jì)數(shù)器減一
    wg.Add(-1)
}

Wait

執(zhí)行阻塞,直到所有的WaitGroup數(shù)量變成0。

func (wg *WaitGroup) Wait() {
    // 獲取到wg.state1數(shù)組中元素組成的二進(jìn)制對(duì)應(yīng)的十進(jìn)制的值
    statep := wg.state()
    // cas算法
    for {
        state := atomic.LoadUint64(statep)
        // 高32位是計(jì)數(shù)器
        v := int32(state >> 32)
        w := uint32(state)
        // 計(jì)數(shù)器為0,結(jié)束等待
        if v == 0 {
            // Counter is 0, no need to wait.
            return
        }
        // 增加等待goroution計(jì)數(shù),對(duì)低32位加1,不需要移位
        if atomic.CompareAndSwapUint64(statep, state, state+1) {
            // 目的是作為一個(gè)簡(jiǎn)單的sleep原語(yǔ),以供同步使用
            runtime_Semacquire(&wg.sema)
            if *statep != 0 {
                panic("sync: WaitGroup is reused before previous Wait has returned")
            }
            return
        }
    }
}

使用注意事項(xiàng)

  1. WaitGroup不能保證多個(gè) goroutine 執(zhí)行次序
  2. WaitGroup無(wú)法指定固定的goroutine數(shù)目

本文名稱:GolangWaitGroup源碼分析
分享URL:http://aaarwkj.com/article4/ipdjie.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、手機(jī)網(wǎng)站建設(shè)移動(dòng)網(wǎng)站建設(shè)、網(wǎng)站內(nèi)鏈、、微信公眾號(hào)

廣告

聲明:本網(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áng)服務(wù)器托管
日韩欧美精品一区二区三区四区| 欧美在线观看日韩精品| 久久精品人妻麻豆尤物| 成熟女人毛茸茸的视频| 亚洲综合激情一区二区| 日本欧美中文字幕一区| 公侵犯人妻中文字幕一区| 欧美日韩亚洲精品综合网| 粉嫩美女精品一区二区| 国产av剧情精品亚洲| 在线播放国内自拍情侣酒店| 热久久青草精品欧美一区| 精品国产美女诱惑久久久| 日韩在线中文字幕三区| 精品蜜臀国产av一区二区| 婷婷亚洲五月伊人91| 久久91亚洲精品久久91| 91精品国产欧美在线| 久久久久四虎国产精品| 四虎国产最新在线免费| 美女性生活免费视频网站| 亚洲成人av在线直播| 亚洲国产av永久精品成人| 放荡精品少妇一区二区三区| 日本欧美激情在线观看| 日本不卡一区二区视频| 99精品人妻一区二区三区蜜桃| 美女网站色在线免费观看午夜精品 | 黄色三级视频一区二区三区| 午夜看片福利欧美熟女| av国产一区二区在线| 午夜最新福利在线视频| 九九99九九99九九精品在线观看| 玩弄丰满熟妇留守妇女| 人人妻人人澡人人爽人人老司机| 福利一区福利二区视频| 福利一区二区在线视频| 亚洲国产欧美日韩激情在线| 精品国产美女主播在线| 国产日韩熟女中文字幕| 国产av综合一区二区三区最新|