使用gorutine和channels通过四个协程进行素数的判断取值打印

package main

import "fmt"

//将数写入管道中
func getNums(getNum chan int) {
	for i := 2; i < 200; i++ {
		getNum <- i
	}
	close(getNum)
}

//将管道中的数取出来,判断是否是素数,是的话放入新的管道中
func prineNums(getNum chan int, primeNum chan int, exitStat chan bool) {
	//通过死循环取数
	for {
		v, ok := <-getNum
		if !ok {
			break
		}
		//判断是否是素数
		flag := true //素数判断标志位
		for i := 2; i < v; i++ {
			if v%i == 0 { //说明不是素数
				flag = false
				break
			}
		}
		if flag {
			primeNum <- v //将素数存进去
		}
	}
	//取数操作时多个协程共同进行的,里不能close,不知道别的协程是否取数完毕,只能判断当前取数的协程
	fmt.Println("这里有一个协程取数完毕~~")
	//将完毕标志位放进去
	exitStat <- true
}

func main() {
	//创建三个管道
	//从8000取数放到管道
	getNum := make(chan int, 1000)
	//从管道中取素数放到新的管道
	primeNum := make(chan int, 1000)
	//标志位管道,判断程序协程是否执行完毕
	exitStat := make(chan bool, 4) //四个协程

	//首先放进去数
	getNums(getNum)
	//然后四个协程筛选素数
	for i := 0; i < 4; i++ {
		go prineNums(getNum, primeNum, exitStat)
	}
	//判断四个协程是否全部执行完毕、
	for i := 0; i < 4; i++ {
		<-exitStat //啥时候能取完,说明四个协程都运行结束
	}
	//关闭存素数管道,打印素数
	close(primeNum)
	for {
		v, ok := <-primeNum //取数据
		if !ok {
			break
		}
		fmt.Println(v)
	}
}

输出结果
在这里插入图片描述

加入了时间统计功能,使用的是time包中的time.Now().Unix(),并且将exitStat使用匿名函数封装起来并通过协程运行
package main

import (
	"fmt"
	"time"
)

//将数写入管道中
func getNums(getNum chan int) {
	for i := 2; i < 700000; i++ {
		getNum <- i
	}
	close(getNum)
}

//将管道中的数取出来,判断是否是素数,是的话放入新的管道中
func prineNums(getNum chan int, primeNum chan int, exitStat chan bool) {
	//通过死循环取数
	for {
		v, ok := <-getNum
		if !ok {
			break
		}
		//判断是否是素数
		flag := true //素数判断标志位
		for i := 2; i < v; i++ {
			if v%i == 0 { //说明不是素数
				flag = false
				break
			}
		}
		if flag {
			primeNum <- v //将素数存进去
		}
	}
	//取数操作时多个协程共同进行的,里不能close,不知道别的协程是否取数完毕,只能判断当前取数的协程
	fmt.Println("这里有一个协程取数完毕~~")
	//将完毕标志位放进去
	exitStat <- true
}

func main() {
	//创建三个管道
	//从8000取数放到管道
	getNum := make(chan int, 1000)
	//从管道中取素数放到新的管道
	primeNum := make(chan int, 700000)
	//标志位管道,判断程序协程是否执行完毕
	exitStat := make(chan bool, 4) //四个协程

	starttime := time.Now().Unix() //time.Now().Unix()
	//首先放进去数,也使用协程
	go getNums(getNum)
	//然后四个协程筛选素数
	for i := 0; i < 4; i++ {
		go prineNums(getNum, primeNum, exitStat)
	}
	//判断四个协程是否全部执行完毕、这里用匿名函数封装起来,同样使用协程运行
	go func() {
		for i := 0; i < 4; i++ {
			<-exitStat //啥时候能取完,说明四个协程都运行结束
			endtime := time.Now().Unix()
			//统计协程运行时间
			fmt.Println("使用协程耗费时间=", endtime-starttime)
		}
		close(primeNum) //关闭存素数管道,才可以打印素数
	}()
	//主线程,打印素数
	for {
		v, ok := <-primeNum //取数据
		if !ok {
			break
		}
		fmt.Println(v)
	}
	fmt.Println("主线程执行完毕~~")
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值