clllll  

计算素数 通道 协程之间的关系

并发的俩种思想:

  • 第一个通过共享内存,需要锁来保证并发安全。
  • 第二个通过通信来。go语言通过channel. channel是协程安全的。

通道 intchan 来传递要计算的数
通道 primechan 来传递结果是素数
通道 exitchan 来保证计算的协程都完毕

协程 inttochan 给intchan输入 1-120000
协程 prime 从intchan获取数,然后将是素数的数输入给primechan ,计算完毕将 bool true输入给exitchan .
协程 exit 从 exitchan获取数据,达到prime协程的个数,就关闭 primechan
协程 printprime 从 primechan获取数据打印。

package main

import (
	"fmt"
	"sync"
)

var wg sync.WaitGroup
var go_sum_prime int = 16 //计算素数的协程数量
func finttochan(ch chan int) {
	defer close(ch) //输出完就关闭
	wg.Add(1)
	for i := 2; i < 120000; i++ {
		ch <- i
	}
	wg.Done()
}

func fprimechan(intchan chan int, primechan chan int, exitchan chan bool) {
	wg.Add(1)
	for v := range intchan {
		flag := true
		for i := 2; i < v; i++ {
			if v%i == 0 {
				flag = false
				break
			}
		}
		if flag {
			primechan <- v
		}
	}
	//计算完毕就输出给exitchan
	exitchan <- true
	wg.Done()
}

func exit(exitchan chan bool, primechan chan int) {
	wg.Add(1)
	for i := 0; i < go_sum_prime; i++ {

		f := <-exitchan
		fmt.Printf("i=%v, --> %v ", i, f)
	}
	close(exitchan)
	close(primechan)
	wg.Done()

}

func printprime(primechan chan int) {
	wg.Add(1)
	for v := range primechan {
		fmt.Println(v)
	}
	wg.Done()

}

func main() {

	inttochan := make(chan int, 50000)
	primechan := make(chan int, 50000)
	exitchan := make(chan bool, go_sum_prime)

	go finttochan(inttochan)

	for i := 0; i < go_sum_prime; i++ {

		go fprimechan(inttochan, primechan, exitchan)
	}

	go printprime(primechan)
	go exit(exitchan, primechan)

	wg.Wait()
}

posted on 2024-06-02 12:57  llcl  阅读(11)  评论(0编辑  收藏  举报