Go中查找素数的算法

go   2021-06-01 12:34   491   0  


第一种使用协程阻塞

直接使用主线程阻塞等待所有协程都处理完毕后退出

package main

import (
	"fmt"
	"sync"
)

func putNum(intChan chan int) {
	for i := 2; i < 10000; i++ {
		intChan <- i
	}
	close(intChan)
}

func calcPrime(intChan chan int, primeChan chan int, exitChan chan bool) {
	for num := range intChan {
		flag := true
		for i := 2; i < num; i++ {
			if num%i == 0 {
				flag = false
				break
			}
		}
		if flag {
			primeChan <- num
		}
	}
	exitChan <- true
}

func printPrime(primeChan chan int) {
	for prime := range primeChan {
		fmt.Println(prime)
	}
}

func main() {
	routineNum := 16
	intChant := make(chan int, 1000)
	primeChan := make(chan int, 1000)
	exitChan := make(chan bool, routineNum)

	// 写协程
	go putNum(intChant)

	// 计算协程
	for i := 0; i < routineNum; i++ {
		go calcPrime(intChant, primeChan, exitChan)
	}

	// 打印协程
	go printPrime(primeChan)

	// 处理退出,主线程阻塞直至所有协程都处理完毕
	for i := 0; i < 16; i++ {
		<-exitChan
	}
	close(primeChan)
	fmt.Println("执行完毕")
}

第二种使用waitGroup协程计数器

第二种利用waitGroup等待所有协程均完成

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup

func putNum(intChan chan int) {
	for i := 2; i < 10000; i++ {
		intChan <- i
	}
	close(intChan)
	wg.Done()
}

func calcPrime(intChan chan int, primeChan chan int, exitChan chan bool) {
	for num := range intChan {
		flag := true
		for i := 2; i < num; i++ {
			if num%i == 0 {
				flag = false
				break
			}
		}
		if flag {
			primeChan <- num
		}
	}
	exitChan <- true
	wg.Done()
}

func printPrime(primeChan chan int) {
	for prime := range primeChan {
		fmt.Println(prime)
	}
	wg.Done()
}

func closeChan(exitChan chan bool, primeChan chan int) {
	for i := 0; i < 16; i++ {
		<-exitChan
	}
	close(primeChan)
}

func main() {
	routineNum := 16
	intChant := make(chan int, 1000)
	primeChan := make(chan int, 1000)
	exitChan := make(chan bool, routineNum)

	// 写协程
	wg.Add(1)
	go putNum(intChant)

	// 计算协程
	for i := 0; i < routineNum; i++ {
		wg.Add(1)
		go calcPrime(intChant, primeChan, exitChan)
	}

	// 打印协程
	wg.Add(1)
	go printPrime(primeChan)

	// 处理退出
	go closeChan(exitChan, primeChan)
	wg.Wait()
	fmt.Println("执行完毕")
}


博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。