277_尚硅谷_协程求素数的代码实现

1.协程求素数的实现_代码1.协程求素数的实现_代码

package main

import (
	"fmt"
	"time"
)

// * 2. 开启一个putNum 协程, 向管道 intChan 写入8000个整数
func putNum(intChan chan int) {
	fmt.Println("=============== writeData start ===============")
	for i := 1; i <= 8000; i++ {
		// for i := 1; i <= 80; i++ { // 暂定用80
		// * 2.1 放入数据
		intChan <- i
	}
	fmt.Println("=============== writeData end ===============")
	// * 2.2 放入数据结束后,关闭管道,关闭管道后
	close(intChan)
}

// * 3. 开启4个协程,从 intChan 取出数据,并判断是否为素数,就放到primeChan
func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
	// 使用for循环, 从intChan管道中取值
	var flag bool //
	for {
		//! 取值时需要休眠, 原因在于取的过快,导致还没存入就开始取值,导致判断取不到的情况
		time.Sleep(time.Millisecond * 10)
		// intChan管道取值
		num, ok := <-intChan
		// 如果管道取不到了值,终止管道取值循环
		if !ok {
			break
		}
		// 假设是素数, flag为true
		flag = true
		// 判断num是不是素数(prime) 素数只能被1和本身整除
		for i := 2; i < num; i++ {
			if num%i == 0 { // num % 2的余数如果是0, 说明该num不是素数
				flag = false
				break
			}
		}
		// 如果是素数, 将num这个数就放入到primeChan
		if flag {
			primeChan <- num
		}
	}
	fmt.Println("有一个primeNum 协程因为取不到数据, 退出")
	// ! 注: 这里不能关闭 primeChan, 会有其它程序在处理
	// 向exitChan 写入 true, 执行log操作
	exitChan <- true
}

func main() {
	// * 1. 创建3个管道
	intChan := make(chan int, 1000)
	primeChan := make(chan int, 1000) // 素数(prime)数量的结果管道
	exitChan := make(chan bool, 4)    // 标识退出的管道 4个

	// * 2. 开启一个协程, 向 intChan 填写8000个数
	go putNum(intChan)

	// * 3. 开启4个协程,从 intChan 取出数据,并判断是否为素数,就放到primeChan
	for i := 0; i < 4; i++ {
		go primeNum(intChan, primeChan, exitChan)
	}

	// * 4. 使用一个匿名函数, 将如下主线程处理运行起来
	go func() {
		// 主线程处理,从exitChan管道中有4个true记录,说明4个协程全部处理完毕
		for i := 0; i < 4; i++ {
			// 只需要从exitChan管道里取4个数据,数量够即可,因为上面只有执行成功时才会写入true
			// 不成功,不写东西
			<-exitChan
		}

		// 当从exitChan 取出了4个结果,就可以放心的关闭primeChan管道
		close(primeChan)
	}()

	// * 5. 遍历primeChan, 把结果取出
	for {
		res, ok := <-primeChan
		if !ok {
			break
		}
		// 将结果输出
		fmt.Printf("素数= %d\n", res)
	}
	fmt.Println("main线程退出")
}

2.协程求素数的实现_运行结果2.协程求素数的实现_运行结果

 

posted on 2026-03-05 18:29  与太阳肩并肩  阅读(1)  评论(0)    收藏  举报

导航