zoukankan      html  css  js  c++  java
  • 《go语言程序设计》学习(五)

    一,并发

    package main
    import (
        "bufio"
        "fmt"
        "math"
        "os"
    )
    const result = "Polar radius=%.02f θ=%.02f° → Cartesian x=%.02f y=%.02f
    "
    var prompt = "Enter a radius and an angle (in degrees), e.g., 12.5 90, " +
        "or %s to quit."
    type polar struct {
        radius float64
        tt     float64
    }
    type cartesian struct {
        x float64
        y float64
    }
    func init() {
        prompt = fmt.Sprintf(prompt, "Ctrl+D")
    }
    func main() {
        questions := make(chan polar)
        defer close(questions)
        answers := CreateSolver(questions)
        defer close(answers)
        interact(questions, answers)
    }
    func CreateSolver(questions chan polar) chan cartesian {
        answers := make(chan cartesian)
        go func() {
            for {
                polarCoord := <-questions
                tt := polarCoord.tt * math.Pi / 180
                x := polarCoord.radius * math.Cos(tt)
                y := polarCoord.radius * math.Sin(tt)
                answers <- cartesian{x, y}
            }
        }()
        return answers
    }
    func interact(questions chan polar, answers chan cartesian) {
        reader := bufio.NewReader(os.Stdin)
        fmt.Println(prompt)
        for {
            fmt.Printf("radius and angle :")
            line, err := reader.ReadString('
    ')
            if err != nil {
                break
            }
            var radius, tt float64
            if _, err := fmt.Sscanf(line, "%f %f", &radius, &tt); err != nil {
                fmt.Println(os.Stderr, "invalid input")
                continue
            }
            questions <- polar{radius, tt}
            coord := <-answers
            fmt.Printf(result, radius, tt, coord.x, coord.y)
        }
        fmt.Println()
    }

    main函数做了几个事情

    1.创建questions通道

    2.创建solver通道,启动计算协程

    3.进行主循环(使用了没有条件的for)

    这个程序使用了go的协程,协程的创建方法:go 函数。协程要和主进程通信,所以创建了两个通道,一个通道是主进程写入数据,协程来读取,一个通道协程创建,主进程读取。

    二,协程。

    goroutine是程序中与其他goroutine完全相互独立而并发执行的函数活着方法调用。每一个go程序都至少有一个goroutine,即会执行main包中main函数的主goroutine。goroutine非常像轻量级的线程或者协程,他们可以批量的创建。所有的goroutine享有相同的地址空间,同时go语言提供了锁原语来保证数据能够安全的跨goroutine共享。然而go语言推荐的并发编程方式是通信,而非数据共享。

    关于通道,如果给定了一个缓冲区的容量,那么通信就是异步的,只要缓冲区有未使用的空间用于发送数据,或还包含可以接收的数据,那么其通信酒会无阻塞的进行。如果是没有缓冲区的通道,或者通道满了,那么就将变成同步的通信。

    goroutine接收数据的时候,可以使用select同时监听多个通道,任意一个通道有数据,就会激活对应通道的处理。

  • 相关阅读:
    每周总结13
    每周总结12
    每周总结11
    每周总结10
    每周总结9
    启明5-1总结
    启明4-30团队进度博客
    期末总结
    每日日报2021.6.11
    每日日报2021.6.10
  • 原文地址:https://www.cnblogs.com/mruoli/p/4699292.html
Copyright © 2011-2022 走看看