题目

计算出50万以内的素数。用普通方法后,再考虑用goroutine加快处理速度。

  • 要求
  1. 使用普通方法进行计算。
  2. 利用goroutine多协程方式实现。
  3. 对比两种方法的时间效率差。

说明: 本例是一个使用goroutine与channel比较综合的题目,有一定复杂度,需要先仔细分析,有思路后才上代码。

代码实现
  • 普通方式

即轮询1-50万的正整数,依次计算出素数

package main

import (
	"fmt"
	"time"
)

// 判断一个数是否是素数
func isPrieme(num int) bool {
	for i:=2;i
  • 执行结果
(base) ➜  study go run test.go


用时(s): 71
使用多协程方式实现
  • 思路分析

需要借用三个管道来完成题目

1. 用一个协程,将50万个数放入一个管道inChannel中,放入完成后关闭管道。

2. 启动多个协程,同时从inChannel中取数据,并判断是否为素数,如果是素数则将结果放入另一个管道 resultChannel

3. 当某个协程完成操作后,放入一个标记位True,到一个叫flagChannel的管道。这个channel用于标识某个协程已经完成退出,当flagChannel管道内的元素个数等于启动的协程数量时,表示所有协程都完成并退出了。

golang面试知识点(golanggoroutine与channel经典练习题)(1)

package main

import (
	"fmt"
	"runtime"
	"time"
)

/*
1. 用一个协程,将1-100个数放入一个channel inChannel中。
2. 启动10个协程,同时从inChannel中取数据,并计算n的平方,将结果值放入一个新的channel resultChannel
3. 10个协程,写完后,放入一个标记位True,到标记channel flagChannel,这个channel用于标识已经完成数据处理
4. 当标记位个数为10时,表示10个协程都不能取数据了(inChannel已经空了),这时才可以关闭管道resultChannel
 */


// 判断一个数是否是素数
func isPrieme(num int) bool {
	for i:=2;i
  • 执行结果
(base) ➜  04 go run main.go
hello world
cpuNum= 8
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
启动一个新的协程------------
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
一个协程处理完毕!
Done!
总共用时(s):  15

可以看出,使用多协程方式来计算50万以内的素数只用了15秒

结果对比

测试机

普通方式

多协程方式

macbook i7

71秒

15秒

所以看处理大数据计算密集时可以考虑用goroutine方式。但是从编码难度上考虑,goroutine方式要比普通方式要大一些。

,