最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

go chan基本使用詳解

 更新時間:2023年04月28日 14:26:23   作者:@小碼哥  
本文主要介紹了go chan基本使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1、有緩沖的chan 與無緩沖的chan

怎么理解這個緩沖,我個人的理解是是執(zhí)行這個chan 操作的時候是否發(fā)送阻塞。
操作:讀和寫。
讀取的時候,我們都應(yīng)該要是阻塞的,例如我們的socket、的recv函數(shù)。當然取決于你設(shè)置的是阻塞的套接字還是非阻塞的套接字了。
無緩沖的chan,講究讀寫對稱,也就是你在讀的時候會阻塞,看下面這個例子:ch是一個無緩沖的chan,在主線程里面,ch<-發(fā)送了阻塞。所以后面沒法執(zhí)行了。

func TestChan1(t *testing.T) {
	ch := make(chan int)
	<-ch
	ch<-1
}

我們對此進行修改,同樣的也是無緩沖的chan,只不過讓讀操作異步,也就是不是阻塞在主線程了,讓主線程可以繼續(xù)執(zhí)行。

func TestChan1(t *testing.T) {
	ch := make(chan int)
	go func() {
		val := <-ch
		fmt.Println(val)
	}()
	ch<-1
	time.Sleep(1*time.Second)
}

以上是無緩沖chan 的讀操作,假設(shè)我們是先寫呢?我們應(yīng)該可以猜想到,寫可能發(fā)生阻塞也可能不發(fā)生阻塞。那么無緩沖的chan 到底會不會阻塞呢?我們看下面的例子

func TestChan1(t *testing.T) {
	ch := make(chan int)
	ch <- 1
	<-ch
}

運行之后,發(fā)生了死鎖。
對此我們可以得出的初步結(jié)論是:無緩沖的chan 讀寫都是阻塞的。
同理我們對此進行修改

func TestChan1(t *testing.T) {
	ch := make(chan int)
	go func() {
		ch <- 1
	}()
	val := <-ch
	fmt.Println(val)
}

無緩沖的chan的介紹,到以上就結(jié)束,我們看一下有緩沖的chan。

2、有緩沖的chan

猜想一下有緩沖的chan 是什么存在緩沖,也就是說是讀寫操作哪個是非阻塞的,還是都是非阻塞的。我們看下面的例子。
第一個例子

func TestChan1(t *testing.T) {
	ch := make(chan int,1)
	ch <- 1
	val := <-ch
	fmt.Println(val)
}

先寫入ch 然后讀取。運行

這里我們得到結(jié)論:寫是非阻塞。
第2 個例子:

func TestChan1(t *testing.T) {
	ch := make(chan int,1)
	<-ch
	ch <- 1
}

很顯然我們可以猜到,會死鎖。運行

對此我們對于有緩沖的chan得出的結(jié)論:讀取是阻塞的。

同理,針對上面的修改:

func TestChan1(t *testing.T) {
	ch := make(chan int,1)
	go func() {
		val := <-ch
		fmt.Println(val)
	}()
	ch <- 1
	time.Sleep(1 *time.Second)
}

對此我們對于chan有了一個基本的認識與使用。接下來看一下chan 幾個應(yīng)用實例。

3、利用chan 實現(xiàn)生產(chǎn)者消費者

生產(chǎn)者與消費者,說白了就是一個線程負責產(chǎn)生數(shù)據(jù),另外一端消費數(shù)據(jù)。對應(yīng)于我們的讀寫操作上來,生產(chǎn)者寫數(shù)據(jù),消費者讀數(shù)據(jù)。對于該模型是不是,很容易利用chan來實現(xiàn)呢?假設(shè)我們現(xiàn)在是1個生產(chǎn)者,1個消費者,那么我們應(yīng)該利用幾個chan呢,很顯然是一個chan 就夠了,因為寫入需要阻塞,那么我們的produce 是需要一個線程的,對于消費者,我們也需要一個線程,具體實現(xiàn):

func TestChan1(t *testing.T) {
	ch := make(chan int,1)
	defer close(ch)
	go func() {
		for i := 0;i<10;i++ {
			ch<-i
			fmt.Println("send:",i)
		}
	}()
	go func() {
		for {
			select {
			case val, ok := <-ch:
				if ok {
					fmt.Println("recv:", val)
				} else {
					return
				}
			}
		}
	}()
	/*go func() {
		for c := range ch {
			fmt.Println(c)
			fmt.Println("recv:",c)
		}
	}()*/
	time.Sleep(1 *time.Second)
}

針對接收數(shù)據(jù),我們通常采用以下這種模式。

for {
 select {
   case <- ch:
   case <-ctx.Down:
   ....
 }
}

4、利用chan 實現(xiàn)同步

兩條線程交替打印,例如:1-100,兩條線程交替打印。
分析一下這個操作,時間上我們利用的是chan的讀取阻塞的特性,實際上就是利用chan 實現(xiàn)同步。

func TestChan1(t *testing.T) {
	ch1 := make(chan int)
	ch2 := make(chan int)
	go func() {
		for i := 0; i < 50; i++ {
			<-ch1
			fmt.Println(2*i + 1)
			ch2 <- 1
		}
	}()
	go func() {
		for i := 0; i < 50; i++ {
			<-ch2
			fmt.Println(2*i + 2)
			ch1 <- 1
		}
	}()
	ch1 <- 1
	time.Sleep(1 * time.Second)
}

5、并發(fā)處理

假設(shè)我們有一個任務(wù),這個任務(wù)可以分成很多份,每個任務(wù)處理的都是相同的內(nèi)容,例如多線程查詢,匯總。多線程上傳。具體的chan 模板代碼:

// eg1: 假設(shè)10條線程處理,采用10個chan的方式
var res = 0
func TestChan() {
	ch := make(chan int,1)
	closeCh := make(chan int,1)
	defer close(ch)
	for i := 1;i<=10;i++ {
		item := i
		go func() {
			ch <- item
		}()
	}
	go func() {
		for i := 0;i<10;i++{
			c := <- ch
			res += c
			//fmt.Println(val)
		}
		closeCh<-1
	}()
	<-closeCh
	fmt.Println(res)
}

運行結(jié)果

使用waitgroup

func WgTest() {
	ch := make(chan int, 1)
	closeCh := make(chan int,1)
	wg := sync.WaitGroup{}
	wg.Add(2)
	go Produce(ch,&wg)
	go Produce(ch,&wg)
	go Merge(ch,closeCh)
	wg.Wait()
	close(ch)
	<-closeCh
	fmt.Println(result)
	return
}
func Produce(ch chan int, wg *sync.WaitGroup) {
	defer func() {
		wg.Done()
	}()
	for i := 0; i < 10; i++ {
		ch <- i
	}
	return
}
var result = 0
func Merge(ch,closeCh chan int) {
	for {
		select {
		case val,ok := <-ch:
			if ok {
				result += val
			}else {
				closeCh<-1
				return
			}
		}
	}
}

到此這篇關(guān)于go chan基本使用詳解的文章就介紹到這了,更多相關(guān)go chan使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入探索Golang中的SM4加密解密算法

    深入探索Golang中的SM4加密解密算法

    SM4加密算法在安全性、高效性、簡單性、標準化和廣泛支持等方面具有優(yōu)勢,適用于各種數(shù)據(jù)保護和加密應(yīng)用場景,這篇文章就來和大家探索一下Golang中的SM4加密解密算法吧
    2023-06-06
  • Golang中的泛型你真的了解嗎

    Golang中的泛型你真的了解嗎

    Golang?在?1.18?版本更新后引入了泛型,這是一個重要的更新,Gopher?萬眾矚目,為?Golang?帶來了更多的靈活性和可重用性,今天,我們將深入探討泛型的概念、為什么需要泛型、泛型的語法,并探討如何在實踐中使用它
    2023-05-05
  • Golang控制協(xié)程執(zhí)行順序方法詳解

    Golang控制協(xié)程執(zhí)行順序方法詳解

    這篇文章主要介紹了Golang控制協(xié)程執(zhí)行順序的方法,Golang的語法和運行時直接內(nèi)置了對并發(fā)的支持。Golang里的并發(fā)指的是能讓某個函數(shù)獨立于其他函數(shù)運行的能力
    2022-11-11
  • 深入解析golang編程中函數(shù)的用法

    深入解析golang編程中函數(shù)的用法

    這篇文章主要介紹了golang編程中函數(shù)的用法,是Go語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • GO語言基礎(chǔ)庫os包的函數(shù)全面解析

    GO語言基礎(chǔ)庫os包的函數(shù)全面解析

    這篇文章主要為大家介紹了GO語言基礎(chǔ)庫os包的函數(shù)全面解析, 有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Go語言大揭秘:適用于哪些類型的項目開發(fā)?

    Go語言大揭秘:適用于哪些類型的項目開發(fā)?

    想知道Go編程語言適合開發(fā)哪些類型的項目嗎?無論是網(wǎng)絡(luò)服務(wù)、分布式系統(tǒng)還是嵌入式設(shè)備,Go都能輕松應(yīng)對,本文將帶你了解Go在各種場景下的應(yīng)用,讓你更好地選擇和使用Go進行開發(fā),需要的朋友可以參考下
    2024-01-01
  • Go分布式鏈路追蹤實戰(zhàn)探索

    Go分布式鏈路追蹤實戰(zhàn)探索

    這篇文章主要為大家介紹了Go分布式鏈路追蹤實戰(zhàn)示例探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01
  • Go語言標準庫中math模塊詳細功能介紹與示例代碼

    Go語言標準庫中math模塊詳細功能介紹與示例代碼

    Go語言的標準庫math提供了一系列基礎(chǔ)數(shù)學(xué)函數(shù)和常量,用于進行科學(xué)計算、幾何計算和其他數(shù)學(xué)相關(guān)的操作,這篇文章主要介紹了Go語言標準庫中math模塊詳細功能介紹與示例代碼,需要的朋友可以參考下
    2025-03-03
  • GoLang內(nèi)存泄漏原因排查詳解

    GoLang內(nèi)存泄漏原因排查詳解

    內(nèi)存溢出是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,簡單點說就是你要求分配的內(nèi)存超出了系統(tǒng)能給你的,系統(tǒng)不能滿足需求,于是產(chǎn)生溢出出現(xiàn)out of memory異常
    2022-12-12
  • Golang異??刂铺幚沓绦蝈e誤流程

    Golang異常控制處理程序錯誤流程

    這篇文章主要介紹了Golang異??刂铺幚沓绦蝈e誤流程,Golang異常處理機制包括錯誤處理、panic和defer,可控制程序錯誤流程,保證程序穩(wěn)定性和安全性,是Golang編程的關(guān)鍵方式
    2023-04-04

最新評論

隆回县| 唐山市| 甘泉县| 德钦县| 邢台县| 宜良县| 清徐县| 鄱阳县| 乌鲁木齐县| 托克托县| 布尔津县| 平罗县| 娱乐| 托克托县| 武强县| 广宁县| 汝城县| 株洲市| 泗阳县| 泾川县| 松原市| 唐河县| 合江县| 宣化县| 珲春市| 忻州市| 宝兴县| 巴彦县| 宁安市| 沿河| 弥渡县| 奉新县| 岑溪市| 资源县| 双鸭山市| 阳西县| 稻城县| 大埔区| 吴桥县| 和田市| 苏尼特左旗|