GoLang协程和管道

1.1~8000查找素数的例子

package main

import "fmt"

// 向intChan放入1-8000个数
func putNum(intChan chan int){
    for i:=1;i<=80000;i++{
        intChan<-i
    }
    // 关闭intChan
    close(intChan)
}

// 从 intChan 取出数据,并且判断是否为素数,如果是,就放入到primeChan
func primeNum(intChan chan int,primeChan chan int,exitChan chan bool){
    // 使用for 循环
    var flag bool   // 是否为素数
    for{
        num,ok :=<-intChan
        if !ok{
            break   // 表示管道已关闭
        }
        flag=true
        for i:=2;i<num;i++{
            if num %i==0{ // 说明不是素数
                flag=false
                break
            }
        }
        if flag{
            primeChan<-num
        }
    }
    fmt.Println("当前协程运行结束")
    exitChan<-true   // 向管道内标志协程运行结速
}

func main(){
    // 数据管道
    intChan :=make(chan int,1000)
    // 将素数放入该管道
    primeChan :=make(chan int,2000)
    // 每个协程运行结束向该管道内写入一个bool值
    exitChan :=make(chan bool,4)
    go putNum(intChan)
    for i:=0;i<4;i++{
        // 使用协程找素数
        go primeNum(intChan,primeChan,exitChan)
    }
    go func() {
        for i:=0;i<4;i++{
            <-exitChan
        }
        // 当exitChan 取出了4个协程结束标志时,可以关闭primeChan管道
        // 表示所有数据查完成,相关协程已运行结束
        close(primeChan)
        // 运行结束管道此时也可以关闭,他的任务已结完成
        close(exitChan)
    }()

    // 主线程遍历我们的查找的素数结果
    for{
        res,ok :=<-primeChan
        if !ok{
            break
        }
        fmt.Println("素数:",res)
    }
    fmt.Println("程序运行结束~")

}

2. 个人使用引用类型变量来处理了一个程序结束问题 (注意:千万不要这么写,可能你的程序永远也结不了束,应加上lock)

package main

import (
    "fmt"
)

func whriteChanOne(dataChan chan int,voerCode *int){
    for i:=1;i<10000;i++{
        dataChan<- i
        fmt.Println("协程1写入",i)
    }
    *voerCode++

}
func whriteChanTwo(dataChan chan int,voerCode *int){
    for i:=10000;i<20000;i++{
        dataChan<- i
        fmt.Println("协程2写入",i)
    }
    *voerCode++

}
func whriteChanThree(dataChan chan int,voerCode *int){
    for i:=20000;i<30000;i++{
        dataChan<- i
        fmt.Println("协程3写入",i)
    }
    *voerCode++
}
func readChanData(dataChan chan int,readChan chan bool,voerCode *int){
    isClose :=false
    for {
        if *voerCode ==3&&!isClose{
            close(dataChan)
            isClose=true
        }
        v,ok :=<-dataChan
        if !ok{
            readChan<- true
            close(readChan)
            break
        }
        fmt.Println("协程读取",v)

    }
}

func main()  {
    dataChan :=make(chan int,30000)
    readChan :=make(chan bool,1)
    voerCode :=0
    go whriteChanOne(dataChan,&voerCode)
    go whriteChanTwo(dataChan,&voerCode)
    go whriteChanThree(dataChan,&voerCode)
    go readChanData(dataChan,readChan,&voerCode)
    for {
        _,ok := <-readChan
        if !ok{
            break
        }
    }
    fmt.Println("协程读取结束")
}
原文地址:https://www.cnblogs.com/yingger/p/13306720.html