golang實現併發數控制

package main

import (
	"fmt"
	"time"
)

type Demo struct {
	input         chan string
	output        chan string
	goroutine_cnt chan int
}

func NewDemo() *Demo {
	d := new(Demo)
	d.input = make(chan string, 8192)
	d.output = make(chan string, 8192)
	d.goroutine_cnt = make(chan int, 10)
	return d
}

func (this *Demo) Goroutine() {
	this.input <- time.Now().Format("2006-01-02 15:04:05")
	time.Sleep(time.Millisecond * 500)
	<-this.goroutine_cnt
}

func (this *Demo) Handle() {
	for t := range this.input {
		fmt.Println("datatime is :", t, "goroutine count is :", len(this.goroutine_cnt))
		this.output <- t + "handle"
	}
}

func main() {
	demo := NewDemo()
	go demo.Handle()
	for i := 0; i < 10000; i++ {
		demo.goroutine_cnt <- 1
		go demo.Goroutine()
	}
	close(demo.input)
}

如上邊示例,Goroutine()函數,每隔500毫秒寫入一個時間戳到管道中,不考慮管道的讀取時間,也就是說,每個Goroutine會存在大概500毫秒時間,如果不做控制的話,一瞬間可以開啓上萬個甚至更多的goroutine出來,這樣系統就會奔潰。
在上述代碼中,我們引入了帶10個buffer的chan int字段,每創建一個goroutine時,就會向這個chan中寫入一個1,每完成一個goroutine時,就會從chan中彈出一個1。當chan中裝滿10個1時,就會自動阻塞,等待goroutine執行完,彈出chan中的值時,才能繼續開啓goroutine。通過chan阻塞特點,實現了goroutine的最大併發量控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章