码迷,mamicode.com
首页 > 编程语言 > 详细

《go语言程序设计》学习(五)

时间:2015-08-03 16:26:39      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

一,并发

package main
import (
    "bufio"
    "fmt"
    "math"
    "os"
)
const result = "Polar radius=%.02f θ=%.02f° → Cartesian x=%.02f y=%.02f\n"
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(\n)
        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同时监听多个通道,任意一个通道有数据,就会激活对应通道的处理。

《go语言程序设计》学习(五)

标签:

原文地址:http://www.cnblogs.com/mruoli/p/4699292.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!