go 协程初体验 [模拟用户线程池,处理 50 个任务 jobs]

这是我第一次用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 协议》,转载必须注明作者和本文链接
一切皆自学
讨论数量: 1

notifyCh 这个channel不需要关闭吗

2年前 评论
夜幕下的风之 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!