欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go chan基本使用詳解

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

1、有緩沖的chan 與無(wú)緩沖的chan

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

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

我們對(duì)此進(jìn)行修改,同樣的也是無(wú)緩沖的chan,只不過(guò)讓讀操作異步,也就是不是阻塞在主線程了,讓主線程可以繼續(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)
}

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

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

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

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

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

2、有緩沖的chan

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

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

先寫(xiě)入ch 然后讀取。運(yùn)行

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

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

很顯然我們可以猜到,會(huì)死鎖。運(yùn)行

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

同理,針對(duì)上面的修改:

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

對(duì)此我們對(duì)于chan有了一個(gè)基本的認(rèn)識(shí)與使用。接下來(lái)看一下chan 幾個(gè)應(yīng)用實(shí)例。

3、利用chan 實(shí)現(xiàn)生產(chǎn)者消費(fèi)者

生產(chǎn)者與消費(fèi)者,說(shuō)白了就是一個(gè)線程負(fù)責(zé)產(chǎn)生數(shù)據(jù),另外一端消費(fèi)數(shù)據(jù)。對(duì)應(yīng)于我們的讀寫(xiě)操作上來(lái),生產(chǎn)者寫(xiě)數(shù)據(jù),消費(fèi)者讀數(shù)據(jù)。對(duì)于該模型是不是,很容易利用chan來(lái)實(shí)現(xiàn)呢?假設(shè)我們現(xiàn)在是1個(gè)生產(chǎn)者,1個(gè)消費(fèi)者,那么我們應(yīng)該利用幾個(gè)chan呢,很顯然是一個(gè)chan 就夠了,因?yàn)閷?xiě)入需要阻塞,那么我們的produce 是需要一個(gè)線程的,對(duì)于消費(fèi)者,我們也需要一個(gè)線程,具體實(shí)現(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)
}

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

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

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

兩條線程交替打印,例如:1-100,兩條線程交替打印。
分析一下這個(gè)操作,時(shí)間上我們利用的是chan的讀取阻塞的特性,實(shí)際上就是利用chan 實(shí)現(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è)我們有一個(gè)任務(wù),這個(gè)任務(wù)可以分成很多份,每個(gè)任務(wù)處理的都是相同的內(nèi)容,例如多線程查詢,匯總。多線程上傳。具體的chan 模板代碼:

// eg1: 假設(shè)10條線程處理,采用10個(gè)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)
}

運(yùn)行結(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖問(wèn)題解析

    golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖問(wèn)題解析

    這篇文章主要介紹了golang?中?channel?的詳細(xì)使用、使用注意事項(xiàng)及死鎖分析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Go語(yǔ)言LeetCode題解1046最后一塊石頭的重量

    Go語(yǔ)言LeetCode題解1046最后一塊石頭的重量

    這篇文章主要為大家介紹了Go語(yǔ)言LeetCode題解1046最后一塊石頭的重量,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • Golang 經(jīng)典校驗(yàn)庫(kù) validator 用法解析

    Golang 經(jīng)典校驗(yàn)庫(kù) validator 用法解析

    這篇文章主要為大家介紹了Golang 經(jīng)典校驗(yàn)庫(kù) validator 用法解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • CSP communicating sequential processes并發(fā)模型

    CSP communicating sequential processes并發(fā)模型

    這篇文章主要為大家介紹了CSP communicating sequential processes并發(fā)模型,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • GoLang bytes.Buffer基礎(chǔ)使用方法詳解

    GoLang bytes.Buffer基礎(chǔ)使用方法詳解

    Go標(biāo)準(zhǔn)庫(kù)中的bytes.Buffer(下文用Buffer表示)類(lèi)似于一個(gè)FIFO的隊(duì)列,它是一個(gè)流式字節(jié)緩沖區(qū),我們可以持續(xù)向Buffer尾部寫(xiě)入數(shù)據(jù),從Buffer頭部讀取數(shù)據(jù)。當(dāng)Buffer內(nèi)部空間不足以滿足寫(xiě)入數(shù)據(jù)的大小時(shí),會(huì)自動(dòng)擴(kuò)容
    2023-03-03
  • Golang 獲取文件md5校驗(yàn)的方法以及效率對(duì)比

    Golang 獲取文件md5校驗(yàn)的方法以及效率對(duì)比

    這篇文章主要介紹了Golang 獲取文件md5校驗(yàn)的方法以及效率對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-05-05
  • Golang高效解析和生成XML的示例詳解

    Golang高效解析和生成XML的示例詳解

    這篇文章將從Golang中處理XML的基本概念開(kāi)始,詳細(xì)介紹如何讀取和解析XML文件,然后轉(zhuǎn)向如何創(chuàng)建和輸出XML數(shù)據(jù),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Go語(yǔ)言中ORM框架GORM使用介紹

    Go語(yǔ)言中ORM框架GORM使用介紹

    GORM是Go語(yǔ)言中最受歡迎的ORM庫(kù)之一,它提供了強(qiáng)大的功能和簡(jiǎn)潔的?API,讓數(shù)據(jù)庫(kù)操作變得更加簡(jiǎn)單和易維護(hù),本文將詳細(xì)介紹GORM的常見(jiàn)用法,包括數(shù)據(jù)庫(kù)連接、模型定義、CRUD、事務(wù)管理等方面,幫助大家快速上手使用GORM進(jìn)行Web后端開(kāi)發(fā)
    2023-06-06
  • 一站式解決方案:在Windows和Linux上快速搭建Go語(yǔ)言開(kāi)發(fā)環(huán)境

    一站式解決方案:在Windows和Linux上快速搭建Go語(yǔ)言開(kāi)發(fā)環(huán)境

    本文將介紹如何在Windows和Linux操作系統(tǒng)下搭建Go語(yǔ)言開(kāi)發(fā)環(huán)境,以幫助您更高效地進(jìn)行Go語(yǔ)言開(kāi)發(fā),需要的朋友可以參考下
    2023-10-10
  • golang順時(shí)針打印矩陣的方法示例

    golang順時(shí)針打印矩陣的方法示例

    這篇文章主要介紹了golang順時(shí)針打印矩陣的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01

最新評(píng)論