go 协程示例:获取指定范围的质数

 基础语法  2022-01-22  admin  606  818

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)
		}
	}
}


如果文章对您有帮助,点击下方的广告,支持一下作者吧!

相关推荐


在go协程中共享资源需要加锁处理

在go协程中共享资源需要加锁处理packagemain import( &quot;fmt&quot; &quot;sync&quot; ) //创建一个互斥锁 varmutex=&amp;sync.Mutex{} //定义一个共享资源 varsharedResource=0 //定义一个等待组 varwg=sync.WaitGroup{} //定义一

go WaitGroup 的使用方法

在 Go 中,sync 包下的 WaitGroup 能有助于我们控制协程之间的同步。当需要等待一组协程都执行完各自任务后,才能继续后续逻辑。这种场景,就非常适合使用它。WaitGroup 提供三个 API。Add(delta int) 函数提供了 WaitGroup 的任务计数,delta 的值可以为正也可以为负,通常在添加任务时使用。Done() 函数其实就是 Add(-1),在任务完成时调用。

go 协程管理及传参处理

Go语言中的goroutine虽然相对于系统线程来说比较轻量级(初始栈大小仅2KB),(并且支持动态扩容),而正常采用java,c++等语言启用的线程一般都是内核态的占用的内存资源一般在4m左右,而假设我们的服务器CPU内存为4G,那么很明显才用的内核态线程的并发总数量也就是1024个,相反查看一下Go语言的协程则可以达到4*1024*1024/2=200w.这么一看就明白了为什么Go语言天生支持

Go 协程计算圆周率

Go 协程计算圆周率//Concurrentcomputationofpi. //Seehttps://goo.gl/la6Kli. // //ThisdemonstratesGo&#39;sabilitytohandle //largenumbersofconcurrentprocesses. //Itisanunreasonablewaytocalculatepi. package