16.3Go语言干货-并发编程之池与select

1.goroutine池(worker pool)

在平常工作中我们通常会指定启动goroutine数量

采用worker pool 模式,控制goroutine的数量,防止goroutine泄漏和暴涨。

package main

import (
	"fmt"
	"time"
)

func worker(id int, jobs <-chan int, results chan<- int) {
	for j := range jobs {
		fmt.Printf("worker:%d start job:%d\n", id, j)
		time.Sleep(time.Second)
		fmt.Printf("worker:%d end job:%d\n", id, j)
		results <- j * j
	}
}
func main() {
	jobs := make(chan int, 100)
	results := make(chan int, 100)

	//开启三个goroutine
	for n := 1; n <= 3; n++ {
		go worker(n, jobs, results)
	}
	// 创建五个任务
	for i := 0; i < 5; i++ {
		jobs <- i
	}
	//输出结果
	for a := 1; a <= 5; a++ {
		<-results
	}
}

2.select多路复用

在一些情况下需要同时从多个通道接收数据。在通道接收数据时,如果没有数据可能接收将发生阻塞。

Go内置了select关键字,可以同时响应多个通道的操作。

select的使用类似于switch语句,他有一些列case分支与一个默认分支。每一个case会对应一个通道的通信(接收或者发送)过程。select会一直等待,直到某个case的通信操作完成时,就会执行case分支对应的语句。

select{
    case <-ch1:
        ...
    case data := <-ch2:
        ...
    case ch3<-data:
        ...
    default:
        默认操作
}

举个栗子

func main() {
	ch := make(chan int, 1)
	for i := 0; i < 10; i++ {
		select {
		case x := <-ch:
			fmt.Println(x)
		case ch <- i:
		}
	}
}

使用select语句能提高代码的可读性

  1. 可处理一个或者多个channel的发送或者接收操作
  2. 如果多个case同时满足,select会随机选择一个。
  3. 对于没有case的select{}会一直等待,可用于阻塞main函数。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值