go 协程示例:获取指定范围的质数
package main import ( "fmt" "time" ) func main() { //非协程版 begin2 := time.Now() getPrime2(99999) fmt.Println("非协程版执行时间:" + time.Since(begin2).String()) // 2.1484798s //协程版 begin := time.Now() getPrime(99999) fmt.Println("协程版执行时间:" + time.Since(begin).String()) // 901.0676ms } type primeNumber struct { } var P primeNumber func getPrime(maxInt int64) { //初始化数据 //maxInt := int64(9000) chanNum := 50 // 开启协程数量 chanPutNum := make(chan int64, 200) // 协程通道,存放待处理的数据 chanResult := make(chan int64, 100) // 协程通道,存放质数 chanExit := make(chan bool, chanNum) // 协程通道,判断协程是否退出 //开启一个协程,向 chanPutNum 放入 1-maxInt个数,存入待处理的数据 go P.putNum(maxInt, chanPutNum) //开启 chanNum 个协程,从 intChan取出数据,并判断是否为质数,如果是,就放入到 chanResult for i := 0; i < chanNum; i++ { go P.Prime(chanPutNum, chanResult, chanExit) } //判断是否执行完毕 go func() { for i := 0; i < chanNum; i++ { <-chanExit } //当从 chanExit 取出了 chanNum 个结果,就可以放心的关闭 chanResult close(chanResult) close(chanExit) }() // 遍历 chanResult 通道,把结果取出 for val := range chanResult { fmt.Println(val) } } // 向 chanPutNum 放入 1-maxInt个数 func (primeNumber) putNum(maxInt int64, chanPutNum chan int64) { for i := int64(1); i <= maxInt; i++ { chanPutNum <- i } close(chanPutNum) } // Prime 从 intChan取出数据,并判断是否为质数,如果是,就放入到 chanResult func (primeNumber) Prime(chanPutNum chan int64, chanResult chan int64, chanExit chan bool) { for { n, ok := <-chanPutNum if !ok { break } if P.isPrime(n) { //fmt.Printf("==%v \n", n) chanResult <- n } } //当前协程执行完毕,存入待关闭协程通道 chanExit chanExit <- true } // isPrime 判断n是不是质数 func (primeNumber) isPrime(n int64) bool { boolean := true for i, m := int64(2), n/2; i <= m; i++ { if n%i == 0 { boolean = false break } } return boolean } // 非协程版,判断并输出质数 func getPrime2(maxInt int64) { for i := int64(1); i <= maxInt; i++ { if P.isPrime(i) { fmt.Println(i) } } }