golang - concurrency

zjlmxn · · 1805 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

并发(Concurrency)不是并行(Parallelism)


并发

  • 将相互独立的执行过程综合到一起
  • 同时处理很多事情
  • 重点在组合

并行

  • 同时执行多个计算任务
  • 同时能完成很多事情
  • 重点在执行

golang的并发


将一个程序分解成小片段独立执行,各个独立的执行任务之间的合作通过通信实现。
golang提供:

  • 并发执行(goroutines)
  • 通信,同步和消息传输(channels)
  • 多路并发控制(select)

一个简单形象的golang经典教程(地鼠烧书):

http://www.vaikan.com/docs/Concurrency-is-not-Parallelism/#landing-slide

Goroutines

A goroutine is a lightweight thread managed by the Go runtime.

go function(x, y, z)

每个goroutine独立执行,互不干扰。

package main

import (
    "fmt"
)

func main() {
    //每次执行该程序,0~5输出的顺序都不一定一致
    //因为每个goroutine独立执行,互不干扰
    for i := 0; i < 5; i++ {
        go func(i int) {
            fmt.Println(i)
        }(i)
    }

    //等待5个goroutine执行完成,
    //没有这部分代码会没有输出,因为goroutine独立执行,
    //main函数不需要等goroutine执行完就退出了。
    var input string
    fmt.Scanln(&input)
}

Channels

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

ch := make(chan int)
...
ch <- v    // Send v to channel ch.
v := <-ch  // Receive from ch, and
           // assign value to v.

By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.
Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channel:

ch := make(chan int, 100)

Select

select 语句使得一个 goroutine 在多个通讯操作上等待。
select 会阻塞,直到条件分支中的某个可以继续执行,这时就会执行那个条件分支。当多个都准备好的时候,会随机选择一个。
当 select 中的其他条件分支都没有准备好的时候,default 分支会被执行。为了非阻塞的发送或者接收,可使用 default 分支:

package main

import (
    "fmt"
    "time"
)

func main() {
    tick := time.Tick(100 * time.Millisecond)
    boom := time.After(500 * time.Millisecond)
    for {
        select {
        case <-tick:
            fmt.Println("tick.")
        case <-boom:
            fmt.Println("BOOM!")
            return
        default:
            fmt.Println("    .")
            time.Sleep(50 * time.Millisecond)
        }
    }
}

Example - 斐波那契数列


package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

参考资料


The Go Programming Language

https://golang.org/

Effective Go

http://www.hellogcc.org/effective_go.html

golang - Concurrency-is-not-Parallelism

http://www.vaikan.com/docs/Concurrency-is-not-Parallelism


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:zjlmxn

查看原文:golang - concurrency

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1805 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传