zoukankan      html  css  js  c++  java
  • (四十四)golang--协程(goroutine)和管道(channel)相结合实例

    统计1-8000之间的素数。

    整体框架:

    说明:有五个协程,三个管道。其中一个协程用于写入数字到intChan管道中,另外四个用于取出intChan管道中的数字并判断是否是素数,然后将素数写入到primeChan管道中,最后如果后面四个协程哪一个工作完了,就写入一个true到exit管道中,最后利用循环判断这四个协程是否都完成任务,并退出。

    main.go

    package main
    
    import (
        "fmt"
        "go_code/project_13/test"
        "time"
    )
    
    func putNum(intChan chan int) {
        for i := 1; i <= 80000; i++ {
            intChan <- i
        }
        close(intChan)
    }
    
    func isPrime(n int) bool {
        //这里本来i只需要到int(math.Sqrt(float64(n))),为了计算时间,就直接设置i-n了
        for i := 2; i <= n; i++ {
            if n%i == 0 {
                return false
            }
        }
        return true
    }
    
    func primeNum(intChan chan int, primeChan chan int, exitChan chan bool) {
        for {
            // time.Sleep(time.Millisecond * 10)
            num, ok := <-intChan
            if !ok {
                break
            }
            isp := isPrime(num)
            if !isp {
                continue
            } else {
                primeChan <- num
            }
        }
        fmt.Println("有一个协程取不到数据而退出了")
        exitChan <- true
    }
    
    func main() {
        intChan := make(chan int, 1000)
        primeChan := make(chan int, 20000)
        exitChan := make(chan bool, 4)
        //记录当前时间
        start := time.Now()
        //开启一个协程
        go putNum(intChan)
        //开启四个协程
        for i := 0; i < 4; i++ {
            go primeNum(intChan, primeChan, exitChan)
        }
        //当四个协程都完成任务后,计算消耗时间,并关闭primeChan管道
        go func() {
            for i := 0; i < 4; i++ {
                <-exitChan
            }
            cost := time.Since(start)
            fmt.Printf("使用协程耗费时间:%s
    ", cost)
            close(primeChan)
        }()
    
        for {
            // res, ok := <-primeChan
            _, ok := <-primeChan
            if !ok {
                break
            }
            //在这里计算已经完成了,为了计算时间,注释掉了打印的操作
            // fmt.Printf("素数=%d
    ", res)
        }
        fmt.Println("主线程退出")
        test.Test()
    }

    test.go

    package test
    
    import (
        "fmt"
        "time"
    )
    
    func isPrime(n int) bool {
        for i := 2; i <= n; i++ {
            if n%i == 0 {
                return false
            }
        }
        return true
    }
    func Test() {
        start := time.Now()
        for i := 1; i < 80000; i++ {
            isPrime(i)
        }
        cost := time.Since(start)
        fmt.Printf("传统方法消耗时间为:%s", cost)
    }

    最后运行一下看看结果。

    使用协程的方法的确是要比使用传统的方法要快的,有其是在数据量进一步的增大时。至此,一个管道和协程的实例就算完成了, 

  • 相关阅读:
    机器学习log
    shiro教程
    开源litemall学习
    开源mall学习
    elasticsearch 踩坑
    C#工具代码
    Java开发环境搭建——Tomcat配置
    Resource leak: 'context' is never closed
    JavaScript备忘录
    Java开发环境搭建——IntelliJ Idea开发环境
  • 原文地址:https://www.cnblogs.com/xiximayou/p/11959090.html
Copyright © 2011-2022 走看看