内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

使用golang的channel的坑

很多時候我們經(jīng)過使用有緩沖channel作為通信控制的功能,以至有一些誤解和坑出現(xiàn)。

成都創(chuàng)新互聯(lián)公司是少有的網(wǎng)站設計、網(wǎng)站制作、營銷型企業(yè)網(wǎng)站、小程序開發(fā)、手機APP,開發(fā)、制作、設計、買鏈接、推廣優(yōu)化一站式服務網(wǎng)絡公司,自2013年起,堅持透明化,價格低,無套路經(jīng)營理念。讓網(wǎng)頁驚喜每一位訪客多年來深受用戶好評

誤解一:有緩存channel是順序的

執(zhí)行下面代碼。

package mainimport (    "time"
    "math/rand")func main(){
    cache:=make(chan int,4)    go func() {        for i:=0;i< 10;i++ {
            cache<-i
        }
    }()    go getCache(cache)    go getCache(cache)    go getCache(cache)
    time.Sleep(3*time.Second)
}func getCache(cache <-chan int)  {    for  {        select {        case i:=<-cache:            println(i)
            time.Sleep(time.Duration(rand.Int31n(100))*time.Millisecond)
        }
    }

}

多執(zhí)行幾次看看結(jié)果,并不是每一次都是可以順序輸出的,有緩存channel是亂序的。因為這里讓一些同學誤解了,我在此多解釋一下。
針對通道的發(fā)送和接收操作都是可能造成相關的goroutine阻塞。試想一下,有多個goroutine向同一個channel發(fā)送數(shù)據(jù)而被阻塞,如果還channel有多余的緩存空間時候,最早被阻塞的goroutine會最先被喚醒。也就是說,這里的喚醒順序與發(fā)送操作的開始順序是一致的,對接收操作而言亦為如此。無論是發(fā)送還是接收操作,運行時系統(tǒng)每次只會喚醒一個goroutine。 而這里的亂序是指,如果像使用channel緩存中多個goroutine實現(xiàn)順序是正確的,因為每一個goroutine搶到處理器的時間點不一致,所以不能保證順序。

誤解二:channel緩存的大小就是并發(fā)度

如下代碼。

package mainimport (	"fmt"
	"sync"
	"time")var wg = sync.WaitGroup{}func main() {
	wg.Add(2)
	bf := make(chan string, 64)	go insert(bf)	go get(bf)
	wg.Wait()
}func insert(bf chan string) {
	str := "CockroachDB 的技術選型比較激進,比如依賴了 HLC 來做事務的時間戳。但是在 Spanner 的事務模型的 Commit Wait 階段等待時間的選擇,CockroachDB 并沒有辦法做到 10ms 內(nèi)的延遲;CockroachDB 的 Commit Wait 需要用戶自己指定,但是誰能拍胸脯說 NTP 的時鐘誤差在多少毫秒內(nèi)?我個人認為在處理跨洲際機房時鐘同步的問題上,基本只有硬件時鐘一種辦法。HLC 是沒辦法解決的。另外 Cockroach 采用了 gossip 來同步節(jié)點信息,當集群變得比較大的時候,gossip 心跳會是一個非常大的開銷。當然 CockroachDB 的這些技術選擇帶來的優(yōu)勢就是非常好的易用性,所有邏輯都在一個 binary 中,開箱即用,這個是非常大的優(yōu)點。"
	for i := 0; i < 10000000; i++ {
		bf <- fmt.Sprintf("%s%d", str, i)
	}
	wg.Done()
}func sprint(s string) {
	time.Sleep(1000 * time.Millisecond)
}func get(bf chan string) {	for {		go func() {			select {			case str := <-bf:
				sprint(str)			case <-time.After(3 * time.Second):
				wg.Done()
			}

		}()
	}
}

很多同學乍一看以為定義了

bf := make(chan string, 64)

就是說該程序的并發(fā)度控制在了64,執(zhí)行就會發(fā)現(xiàn)內(nèi)存一直在增長。 因為get()函數(shù)中啟動的goroutine會越來越多,因為get()每讀取一個數(shù)據(jù),insert()就會往channel插入一條數(shù)據(jù),此時并發(fā)度就不是64了。 需要修改為:

package mainimport (	"fmt"
	"sync"
	"time")var wg = sync.WaitGroup{}func main() {
	wg.Add(2)
	bf := make(chan string, 64)	go insert(bf)	//go get(bf)
    for i:=0;i<64;i++ {        go get1(bf)
    }

	wg.Wait()
}func insert(bf chan string) {
	str := "CockroachDB 的技術選型比較激進,比如依賴了 HLC 來做事務的時間戳。但是在 Spanner 的事務模型的 Commit Wait 階段等待時間的選擇,CockroachDB 并沒有辦法做到 10ms 內(nèi)的延遲;CockroachDB 的 Commit Wait 需要用戶自己指定,但是誰能拍胸脯說 NTP 的時鐘誤差在多少毫秒內(nèi)?我個人認為在處理跨洲際機房時鐘同步的問題上,基本只有硬件時鐘一種辦法。HLC 是沒辦法解決的。另外 Cockroach 采用了 gossip 來同步節(jié)點信息,當集群變得比較大的時候,gossip 心跳會是一個非常大的開銷。當然 CockroachDB 的這些技術選擇帶來的優(yōu)勢就是非常好的易用性,所有邏輯都在一個 binary 中,開箱即用,這個是非常大的優(yōu)點。"
	for i := 0; i < 10000000; i++ {
		bf <- fmt.Sprintf("%s%d", str, i)
	}
	wg.Done()
}func sprint(s string) {
	time.Sleep(1000 * time.Millisecond)
}func get1(bf chan string)  {    for {        select {        case str := <-bf:
            sprint(str)        case <-time.After(3 * time.Second):
            wg.Done()
        }
    }
}

標題名稱:使用golang的channel的坑
標題來源:http://www.rwnh.cn/article18/gpodgp.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站服務器托管、網(wǎng)站制作全網(wǎng)營銷推廣、App設計、定制網(wǎng)站

廣告

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

成都網(wǎng)站建設
通河县| 镇康县| 哈尔滨市| 通化市| 广宗县| 新郑市| 柳江县| 阿瓦提县| 陆良县| 原平市| 时尚| 隆回县| 永善县| 铜鼓县| 仙桃市| 康定县| 嘉善县| 西峡县| 岐山县| 威信县| 卢龙县| 嘉祥县| 龙州县| 凌海市| 沅江市| 简阳市| 濮阳市| 尉氏县| 闽侯县| 漾濞| 濮阳县| 泗水县| 和政县| 蒲江县| 呈贡县| 台北市| 广水市| 舟曲县| 长顺县| 宜都市| 沾化县|