• 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("协程读取结束")
    }
  • 相关阅读:
    垂死挣扎-3
    垂死挣扎-2
    垂死挣扎-1
    【互联网考试系列-1】进程与线程
    【iOS基础学习随笔-2】SQLite的使用
    【iOS面试系列-2】多线程中同步、异步和串行、并行之间的逻辑关系(必考,必须掌握)
    docker
    给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
    621. 任务调度器
    204. 计数质数
  • 原文地址:https://www.cnblogs.com/yingger/p/13306720.html
Copyright © 2020-2023  润新知