您的位置 首页 golang

golang goroutine与channel入门练习题一

题目

用goroutine与channel实现,计算出1-200内的素数

本例是一个goroutine与channel结合使用的必会题目,需要对goroutine与channel有一定基础知识才能完成。

结题思路

  1. 使用一个管道inChan保存需要处理的数据,启动一个协程writeData,依次将数据放入管道inChan
  2. 使用一个管道exitChan保存退出标记位,用于判断所有协程是否完成。
  3. 阻塞主线程,一直等到所有协程都完成

代码实现

 package main

import (
"fmt"
"runtime"
)
/*
1. 启动一个协程writedata将200个数据到,管道inChan
2. 启动一个readdata从管道inChan读数据,判断读到的数据是否素数,如果是素数则打印。
3. 管道exitChan用于判断所有协程是否都完成
 */
// 判断一个数是否是素数
func isPrieme(num int) bool {
for i:=2;i<num;i++{
if num % i == 0 {
return false
}
}
return true
}

// 将200个数写入管道
func writeData(inChan chan int)  {
// 依次写入200个数到管道inChan
for i:=1;i<=200;i++ {
inChan <- i
//time.Sleep(time.Second*2)
}
// 写入完成后关闭管道
close(inChan)
}

// 从inChan读取数据,计算判断是否为素数,如果是则打印
func readData(inChan chan int, exitChan chan bool)  {
//fmt.Println(time.Now() , " new goroutine")
for {
value ,ok := <-inChan
if !ok {
// 如果读不到,表示inChan内的数据已经取完了
break
}
// 读取到的数,计算判断是否为素数
if isPrieme(value){
fmt.Println("prime = ", value)
}
}
// 如果读取不到数据,表这个协程已经完成。
exitChan<- true

}

func init(){
// 设置可用处理器个数
cpuNum := runtime.NumCPU()
runtime.GOMAXPROCS(cpuNum-1)
fmt.Println("cpuNum=",cpuNum)
}

func main(){
fmt.Println("hello")

// 一个用于保存待处理数据的管道
var inChan chan int

// 用与标记判断协程是否完成的管道
var exitChan chan bool

// 启动协程的数量
var gorutNum int
inChan = make(chan int, 200)
exitChan = make(chan bool, 5)
gorutNum = 5

// 启动一个协程用于输入待处理的数据
go writeData(inChan)

// 启动多个协程用于处理数据
for i:=0;i<gorutNum;i++ {
go readData(inChan,exitChan)
}

// 阻塞主线程,等下协程的完成
for {
v,ok := <- exitChan
if ok {
fmt.Println(v)
break
}
}
fmt.Println("Done!")

}  

## 输出结果

 .....省略部分输出
prime =  139
prime =  149
prime =  151
prime =  157
prime =  163
prime =  167
prime =  173
prime =  179
prime =  181
prime =  191
prime =  193
prime =  197
prime =  199
true
Done!
prime =  2
prime =  3
prime =  17  

背景知识

  • 管道是线程安全的,也就是多协程同时操作一个协程,结果都是我们预期的效果。而golang中常用的内置数据结构,变量,切片,map都不是线程安全的。

  • 线程安全如何理解呢? 即当多个线程访问某个方法时,不管你通过怎样的调用方式或者说这些线程如何交替的执行,我们在主程序中不需要去做任何的同步,这个类的结果行为都是我们设想的正确行为,那么我们就可以说这个类时线程安全的。如果一段代码可以保证多个线程访问的时候正确操作共享数据,那么它是线程安全的

文章来源:智云一二三科技

文章标题:golang goroutine与channel入门练习题一

文章地址:https://www.zhihuclub.com/86302.shtml

关于作者: 智云科技

热门文章

网站地图