Go-协程求素数+管道的注意事项

协程求素数

image

package main

import (
	"fmt"
	"time"
)

func putNum(intChan chan int) {
	for i := 1; i <= 8000; i++ {
		intChan <- i
		//fmt.Println("写入数据", i)
	}
	close(intChan)
}

func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
	for {
		time.Sleep(time.Millisecond * 10)
		num, ok := <-intChan
		if !ok {
			break
		}
		//判断num是不是素数
		flag := true
		for i := 2; i < num; i++ {
			if num%i == 0 {
				flag = false
				break
			}
		}
		if flag {
			primeChan <- num
		}
	}
	fmt.Println("有一个primeNum 协程取不到数据了,退出")
	exitChan <- true
}

func main() {
	intChan := make(chan int, 1000)
	primeChan := make(chan int, 2000)
	exitChan := make(chan bool, 4)
	//intChan放人1-8000个数
	go putNum(intChan)
	//开启四个协程 从intChan中取出数据 并判断是否为素数
	//如果是就放入primeChan
	for i := 0; i < 4; i++ {
		go primeNum(intChan, primeChan, exitChan)
	}
	//判断主线程的关闭
	go func() {
		for i := 0; i < 4; i++ {
			<-exitChan
		}
		//当我们取出了4个结果 就可以放心的关闭了
		close(primeChan)
	}()
	for {
		res, ok := <-primeChan
		if !ok {
			break
		}
		fmt.Printf("素数=%d\n", res)
	}
	fmt.Println("主线程退出")
}

image

管道只读只写

image

package main

import "fmt"

func main() {
	//管道可以声明为只读只写
	//只写
	chan2 := make(chan<- int, 3)
	chan2 <- 20
	fmt.Println("chan2=", chan2)
	//只读
	var chan3 <-chan int
	num2 := <-chan3
	fmt.Println("num2", num2)
}

Select语句 解决拥塞控制

package main

import "fmt"

func main() {
	intChan := make(chan int, 10)
	for i := 0; i < 10; i++ {
		intChan <- i
	}
	stringChan := make(chan string, 5)
	for i := 0; i < 5; i++ {
		stringChan <- "hello" + fmt.Sprintf("%d", i)
	}
	//如果不关闭管道 会发生死锁
	//可以用select解决这个问题
	for {
		select {
		case v := <-intChan:
			fmt.Printf("从intChan读取的数据%d\n", v)
		case v := <-stringChan:
			fmt.Printf("从stringChan读取的数据%s\n", v)
		default:
			fmt.Printf("加入逻辑\n")
			return
		}
	}
}

image

posted @ 2022-06-13 10:32  司砚章  阅读(26)  评论(0编辑  收藏  举报