zoukankan      html  css  js  c++  java
  • Go程序设计语言练习题-第9章(9.4-9.5)

    package main
    
    import (
        "fmt"
        "runtime"
        "time"
    )
    
    // 用通道串联goroutine流水线
    // 实现方式:将goroutine之间通讯所需的chan存入chs,
    // 创建流水线开始的goroutine,向chs[0]写入0,
    // 第二个goroutine从chs[0]读出数据并做加一处理,然后写入chs[1]交给流水线中下一个goroutine
    // ......
    // 统计程序消耗的内存,在超过1G时终止程序
    func ex9_4() {
        // 获得目前内存使用情况
        getMemSys := func() uint64 {
            mem := runtime.MemStats{}
            runtime.ReadMemStats(&mem)
            return mem.Sys
        }
        before := getMemSys()
    
        chs := []chan int{}
        start := make(chan int)
        chs = append(chs, start)
        go func() {
            for {
                start <- 0
            }
        }()
    
        for n := 0; ; n++ {
            out := chs[n]
            in := make(chan int)
            chs = append(chs, in)
            go func(n int, in, out chan int) {
                for {
                    num := <-in
                    out <- num + 1
                }
            }(n, in, out)
    
            // 获得程序使用内存情况
            memAlloc := getMemSys() - before
            if memAlloc > 1024*1024*1024 { // 消耗1G内存时终止程序
                fmt.Println(n, "Goroutines") // 大概11~12万,每个goroutine消耗内存9k左右
                break
            }
        }
    }
    
    // 通过两个无缓冲的通道实现两个goroutine通信,
    // 每次通信都将同通信计数加一,1s内大概通信200万次
    func ex9_5() {
        ch1 := make(chan int)
        ch2 := make(chan int)
        n := 1
        defer func() {
            fmt.Println(n)
        }()
    
        go func() {
            ch1 <- n
            for {
                n = <-ch2
                n++
                ch1 <- n
            }
        }()
    
        go func() {
            for {
                n = <-ch1
                n++
                ch2 <- n
            }
        }()
    
        time.Sleep(time.Second)
    }
    
    // 无缓冲通道
    // 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z
    func printNoCache() {
        ch1 := make(chan int)
        ch2 := make(chan int)
        end := make(chan struct{})
        go func() {
            for i := 0; i < 26; i++ {
                ch1 <- i + 1
                fmt.Printf("%c", <-ch2)
            }
            close(ch1)
        }()
    
        go func() {
            for i := range ch1 {
                fmt.Print(i)
                ch2 <- int('A') + i - 1
            }
            close(end)
        }()
    
        <-end
    }
    
    // 有缓冲通道
    // 打印1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z
    func printWithCache() {
        ch1 := make(chan int, 1)
        ch2 := make(chan int, 1)
        done := make(chan struct{})
    
        go func() {
            for i := 1; i <= 26; i++ {
                ch2 <- i
                fmt.Printf("%c", <-ch1)
            }
            close(ch2)
        }()
    
        go func() {
            for n := range ch2 {
                fmt.Print(n)
                ch1 <- int('A') + n - 1
            }
            close(ch1)
            close(done)
        }()
    
        <-done
    }
    
    func main() {
    ex9_4()
    ex9_5()
        printNoCache()
    printWithCache()
    }

    执行效果:

    117415 Goroutines
    2508193
    1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z
    1A2B3C4D5E6F7G8H9I10J11K12L13M14N15O16P17Q18R19S20T21U22V23W24X25Y26Z
    成功: 进程退出代码 0.
  • 相关阅读:
    创意十足!25个服饰行业的网站设计作品
    Web 项目可能会用到的20款优秀的开源工具
    Remodal – 支持 Hash 追踪的响应式模态窗口
    学习 Mobile App 网站制作的11个优秀案例
    CSS Shake – 摇摆摇摆!动感的 CSS 抖动效果
    10个最好的 JavaScript 动画库和开发框架
    流行时尚!21例创新的侧边栏菜单网页设计作品
    Bucky – 免费开源的实时用户监控工具
    五彩缤纷!13个学习网站配色技巧的绝佳案例
    充实你的素材库!10款免费的 PSD 素材下载
  • 原文地址:https://www.cnblogs.com/ling-diary/p/10516799.html
Copyright © 2011-2022 走看看