go 協程初體驗 [模擬使用者執行緒池,處理 50 個任務 jobs]

jfaWei發表於2020-03-17

這是我第一次用Go,體驗一下和PHP的區別;Go語言天然併發的能力;

用到的知識:goroutinechannel

goroutine通過go關鍵字開啟一個使用者態執行緒,channel通道,實現協程間的通訊即通過通訊實現記憶體共享;
感覺Go太有趣了,程式碼如下:

package main

import (
    "fmt"
    "time"
)

//使用空結構體,作為任務結束的通知
var notifyCh = make(chan struct{}, 50)

func worker(n int, jobs <-chan int, results chan<- int) {
    for x := range jobs {
        fmt.Printf("協程:%d處理開始\n", n)
        //模擬處理時間
        time.Sleep(time.Second)
        results <- x * 2
        //每完成一個job,計數一次
        notifyCh <- struct{}{}
        fmt.Printf("協程:%d處理結束\n", n)
    }
}
func main() {
    jobs := make(chan int, 50)
    results := make(chan int, 50)
    //使用一個協程生成50個任務;
    go func() {
        for i := 1; i <= 50; i++ {
            jobs <- i
        }
        close(jobs)
    }()
    //使用3個goroutine處理任務;
    for j := 1; j <= 3; j++ {
        go worker(j, jobs, results)
    }
    //使用一個goroutine去notifyCh取值,通知通道有50次,說明50個任務處理結束
    go func() {
        for w := 1; w <= 50; w++ {
            <-notifyCh
        }
        //關閉result通道
        close(results)
    }()
    //輸出
    for r := range results {
        fmt.Println(r)
    }
}

go run ./main.go執行結果如下:

協程:1處理開始
協程:3處理開始
協程:2處理開始
協程:1處理結束
協程:1處理開始
協程:2處理結束
協程:2處理開始
協程:3處理結束
2
4
6
協程:3處理開始
協程:2處理結束
協程:2處理開始
10
8
12
協程:1處理結束
協程:1處理開始
協程:3處理結束
協程:3處理開始
14
協程:2處理結束
協程:2處理開始
協程:1處理結束
協程:1處理開始
16
協程:3處理結束
協程:3處理開始
18
協程:2處理結束
協程:2處理開始
20
22
24
協程:1處理結束
協程:3處理結束
協程:3處理開始
協程:1處理開始
協程:2處理結束
協程:2處理開始
26
30
協程:3處理結束
協程:3處理開始
28
協程:1處理結束
協程:1處理開始
協程:2處理結束
協程:2處理開始
32
協程:3處理結束
協程:3處理開始
34
36
協程:1處理結束
協程:1處理開始
協程:2處理結束
協程:2處理開始
38
協程:3處理結束
協程:3處理開始
40
協程:1處理結束
協程:1處理開始
42
協程:2處理結束
協程:2處理開始
44
協程:3處理結束
協程:3處理開始
46
協程:1處理結束
協程:1處理開始
48
協程:2處理結束
協程:2處理開始
50
協程:3處理結束
協程:3處理開始
52
協程:1處理結束
協程:1處理開始
54
協程:2處理結束
協程:2處理開始
56
協程:3處理結束
協程:3處理開始
58
60
協程:1處理結束
協程:1處理開始
協程:2處理結束
協程:2處理開始
62
64
協程:3處理結束
協程:3處理開始
協程:1處理結束
協程:1處理開始
66
協程:2處理結束
協程:2處理開始
68
協程:3處理結束
協程:3處理開始
70
協程:1處理結束
協程:1處理開始
72
協程:2處理結束
協程:2處理開始
74
協程:3處理結束
協程:3處理開始
76
協程:1處理結束
協程:1處理開始
78
協程:2處理結束
協程:2處理開始
80
協程:3處理結束
協程:3處理開始
協程:1處理結束
協程:1處理開始
82
84
協程:2處理結束
協程:2處理開始
86
協程:3處理結束
協程:3處理開始
88
協程:1處理結束
協程:1處理開始
90
協程:2處理結束
協程:2處理開始
92
協程:3處理結束
協程:3處理開始
94
協程:1處理結束
96
協程:2處理結束
98
協程:3處理結束
100

通過教程,模仿寫的程式碼,:bowtie:有點意思 :heart_eyes:

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章