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.

 

posted @ 2019-03-12 15:05  zerofl-diary  阅读(502)  评论(0编辑  收藏  举报