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

GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn)

 更新時(shí)間:2023年05月25日 08:31:24   作者:JetTsang  
本文主要介紹了GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

go 當(dāng)中的并發(fā)編程是通過goroutine來實(shí)現(xiàn)的,利用channel(管道)可以在協(xié)程之間傳遞數(shù)據(jù),實(shí)現(xiàn)協(xié)程的協(xié)調(diào)與同步。

使用

新建一個(gè)管道,使用make channel 來構(gòu)建

// 構(gòu)建一個(gè)緩存長度為8 的管道
ch := make(chan int ,8)
// 寫入
ch <- 10
// 取出
number := <-ch
// 關(guān)閉
close(ch)

注意??: 取數(shù)據(jù)的時(shí)候,如果沒得取,會阻塞代碼的執(zhí)行,如果一直沒有取到,那就是死鎖

實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式

兩個(gè)生產(chǎn)者者協(xié)程和一個(gè)消費(fèi)者協(xié)程

使用waitGroup

func main() { ?
? ? ch := make(chan int, 100) ?
? ? wg := sync.WaitGroup{} ?
? ? wg.Add(2) ?
? ? // 生產(chǎn)者
? ? go func() { ?
? ? ? ? defer wg.Done() ?
? ? ? ? // 寫入數(shù)據(jù) ?
? ? ? ? for i := 0; i < 10; i++ { ?
? ? ? ? ? ? ch <- i ?
? ? ? ? } ?
? ? }() ?
? ? // 生產(chǎn)者
? ? go func() { ?
? ? ? ? defer wg.Done() ?
? ? ? ? // 寫入數(shù)據(jù) ?
? ? ? ? for i := 0; i < 10; i++ { ?
? ? ? ? ? ? ch <- i ?
? ? ? ? } ?
? ? }() ?
? ? wg2 := sync.WaitGroup{} ?
? ? wg2.Add(1) ?
? ? // 消費(fèi)者
? ? go func() { ?
? ? ? ? sum := 0 ?
? ? ? ? fmt.Printf("sum %d \n", sum) ?
? ? ? ? for { ?
? ? ? ? ? ? // 這里會等待 ?
? ? ? ? ? ? temp, ok := <-ch ?
? ? ? ? ? ? // close 并且 管道為空,ok = false ?
? ? ? ? ? ? if !ok { ? ?
? ? ? ? ? ? ? ? break ?
? ? ? ? ? ? } else { ?
? ? ? ? ? ? ? ? sum += temp ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? fmt.Printf("sum %d \n", sum) ?
? ? ? ? wg2.Done() ?
? ? }() ?
? ? // 等待倆生產(chǎn)者結(jié)束 ?
? ? wg.Wait() ?
? ? // 生產(chǎn)數(shù)據(jù)之后,消費(fèi)者也并行讀完了,此時(shí)可以關(guān)閉 管道 來 跳出for循環(huán)了?
? ? close(ch) ?
? ? // 等待消費(fèi)者協(xié)程結(jié)束 ?
? ? wg2.Wait() ?
}

使用管道則將wg2相關(guān)的代碼改掉

func main() { ?
? ? //...?
? ? //...
? ? ch2 := make(chan struct{}, 0) ?
? ? go func() { ?
? ? ? ? sum := 0 ?
? ? ? ? fmt.Printf("sum %d \n", sum) ?
? ? ? ? for { ?
? ? ? ? ? ? // 這里會等待 ?
? ? ? ? ? ? temp, ok := <- ch ?
? ? ? ? ? ? // close 并且 管道為空,ok = false ?
? ? ? ? ? ? if !ok { ?
? ? ? ? ? ? ? ? break ?
? ? ? ? ? ? } else { ?
? ? ? ? ? ? ? ? sum += temp ?
? ? ? ? ? ? } ?
? ? ? ? } ?
? ? ? ? fmt.Printf("sum %d \n", sum) ?
? ? ? ? ch2 <- struct{}{} ?
? ? }() ?
? ? // 等待倆生產(chǎn)者結(jié)束 ?
? ? wg.Wait() ?
? ? // 關(guān)閉管道
? ? close(ch) ?
? ? // 等待消費(fèi)者協(xié)程結(jié)束 ?
? ? <-ch2
}

實(shí)戰(zhàn)面試題: 「交替打印數(shù)字和字母」

題目

使用兩個(gè) goroutine 交替打印序列,一個(gè) goroutine 打印數(shù)字, 另外一個(gè) goroutine 打印字母, 最終效果如下:

12AB34CD56EF78GH910IJ1112KL1314MN1516OP1718QR1920ST2122UV2324WX2526YZ2728

解題思路

利用channel的 阻塞 來協(xié)調(diào)線程,達(dá)到線程交叉執(zhí)行的效果。

代碼

func main() {  
    letter, number := make(chan bool), make(chan bool)  
    wait := sync.WaitGroup{}  
    go func() {  
        i := 1  
        for {  
            if <-number {  
                fmt.Print(i)  
                i++  
                fmt.Print(i)  
                i++  
                letter <- true  
            }  
        }  
    }()  
    wait.Add(1)  
    go func() {  
        // 獲得ASCII碼  
        i := 'A'  
        for {  
            if <-letter {  
                // 當(dāng)前已經(jīng)超過Z時(shí),無需再打印
                if i > 'Z' {  
                    // 停止等待,并且跳出循環(huán)
                    wait.Done()  
                    break  
                }  
                // 將ASCII碼強(qiáng)轉(zhuǎn)成字母輸出  
                fmt.Print(string(i))  
                i++  
                fmt.Print(string(i))  
                i++  
                number <- true  
            }  
        }  
    }()  
    // 放行數(shù)字打印的阻塞 
    number <- true  
    // 等待關(guān)閉主線程
    wait.Wait()  
}

其實(shí)完全也可以將waitGroup換成管道

func main() {  
    letter, number := make(chan bool), make(chan bool)  
    // 再定義一個(gè)管道來等待,替代waitGroup的作用
    wait := make(chan bool)
    // 打印數(shù)字
    go func() {  
        i := 1  
        for {  
            if <-number {  
                fmt.Print(i)  
                i++  
                fmt.Print(i)  
                i++  
                letter <- true  
            }  
        }  
    }()  
    // 打印字母
    go func() {  
        // 獲得ASCII碼  
        i := 'A'  
        for {  
            if <-letter {  
                if i > 'Z' {  
                    wait <- true  
                    break  
                }  
                // 將ASCII碼強(qiáng)轉(zhuǎn)成字母輸出  
                fmt.Print(string(i))  
                i++  
                fmt.Print(string(i))  
                i++  
                number <- true  
            }  
        }  
    }()  
    number <- true  
    // 等待管道取值
    <- wait 
}

結(jié)尾

到此這篇關(guān)于GO利用channel協(xié)調(diào)協(xié)程的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)GO  channel協(xié)調(diào)協(xié)程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go時(shí)間/時(shí)間戳操作大全(小結(jié))

    go時(shí)間/時(shí)間戳操作大全(小結(jié))

    這篇文章主要介紹了go時(shí)間/時(shí)間戳操作大全,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • golang解析網(wǎng)頁利器goquery的使用方法

    golang解析網(wǎng)頁利器goquery的使用方法

    這篇文章主要給大家介紹了關(guān)于golang解析網(wǎng)頁利器goquery的使用方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • Golang信號量設(shè)計(jì)實(shí)現(xiàn)示例詳解

    Golang信號量設(shè)計(jì)實(shí)現(xiàn)示例詳解

    這篇文章主要為大家介紹了Golang信號量設(shè)計(jì)實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • Golang時(shí)間處理中容易踩的坑分析解決

    Golang時(shí)間處理中容易踩的坑分析解決

    這篇文章主要為大家介紹了Golang時(shí)間處理中容易踩的坑分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Go?viper讀取配置文件的示例詳解

    Go?viper讀取配置文件的示例詳解

    這篇文章主要為大家詳細(xì)介紹了Go語言如何利用viper實(shí)現(xiàn)讀取配置文件,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2023-08-08
  • Go內(nèi)置序列化庫gob的使用

    Go內(nèi)置序列化庫gob的使用

    本文主要介紹了Go內(nèi)置序列化庫gob的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go語言利用heap實(shí)現(xiàn)優(yōu)先級隊(duì)列

    Go語言利用heap實(shí)現(xiàn)優(yōu)先級隊(duì)列

    這篇文章主要為大家詳細(xì)介紹了Go語言中heap的使用以及如何利用heap實(shí)現(xiàn)優(yōu)先級隊(duì)列的相關(guān)資料,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-05-05
  • golang變量uint、int大小溢出后的結(jié)果方式

    golang變量uint、int大小溢出后的結(jié)果方式

    在Go語言中,變量的大小溢出后,`uint`類型會回繞到最小值,而`int`類型會回繞到最大值的相反數(shù),例如,`uint8`溢出后會變成0,`int64`溢出后會變成最小的負(fù)數(shù)
    2024-12-12
  • 聊聊Go語言編譯github上的項(xiàng)目遇到的坑

    聊聊Go語言編譯github上的項(xiàng)目遇到的坑

    這篇文章主要介紹了解決Go語言編譯github上的項(xiàng)目遇到的坑,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • go語言中的二維切片賦值

    go語言中的二維切片賦值

    這篇文章主要介紹了go語言中的二維切片賦值操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04

最新評論