当被问到为什么用Go语言,一定不得不提的是Go语言的并发程序编写。在C语言中编写非常繁琐复杂的并发程序在Go语言中总是显得如此便捷。

Go中并发程序依靠的是两个:goroutine和channel

理解什么是goroutine?

对于初学者,goroutine直接理解成为线程就可以了。当对一个函数调用go,启动一个goroutine的时候,就相当于起来一个线程,执行这个函数。

实际上,一个goroutine并不相当于一个线程,goroutine的出现正是为了替代原来的线程概念成为最小的调度单位。

一旦运行goroutine时,先去当先线程查找,如果线程阻塞了,则被分配到空闲的线程,如果没有空闲的线程,那么就会新建一个线程。注意的是,当goroutine执行完毕后,线程不会回收推出,而是成为了空闲的线程。

goroutine的使用

使用非常简单,在函数前增加一个go

f(11)

go f(11) //这个是让f()函数作为goroutine运行

但是go有一个缺点,主线程要等待一个goroutine结束再处理怎么办?拿《学习go语言》中的一个例子说明。

1.jpg

这里的第18行为什么要sleep? 这里是为了等上面两个go ready处理完成。

好了,这里就出来了一个需求:一个goroutine结束后必须要向主线程传输数据,告诉主线程这个goroutine已经结束了。

这里就引进了channel的概念

channel的使用

channel的意思用白话可以这么理解:主线程告诉大家你开goroutine可以,但是我在我的主线程开了一个管道,你做完了你要做的事情之后,往管道里面塞个东西告诉我你已经完成了。

上面的例子就可以改为:

2.jpg

从这个程序得到的几点信息:

1 channel只能使用make来进行创建

基本格式是 c := make(chan int)

int是说明这个管道能传输什么类型的数据

2 往channel中插入数据的操作

c <- 1

是不是很形象

3 从channel中输出数据

<- c

4 为什么需要输出两次(4和5两行?)

因为2和3启动了两个goroutine,每个goroutine都往管道输出一个1,因此主线程要接收两次才能说明两个goroutine都结束了

channel的进一步理解:

channel分为两种:一种是有buffer的,一种是没有buffer的,默认是没有buffer的

ci := make(chan int) //无buffer

cj := make(chan int, 0) //无buffer

cs := make(chan int, 100) //有buffer

有缓冲的channel,因此要注意“放”先于“取”

无缓冲的channel,因此要注意“取”先于“放”

同样要先输出hello world,使用有缓冲的channel和无缓冲的channel分别是这样的:

有缓冲的channel:

var a stringvar c = make(chan int, 10)  func f() {    a = "hello, world"    c <- 0}  func main() {    go f()    <-c    print(a) }

这里有个缓冲,因此放入数据的操作c<- 0先于取数据操作 <-c

无缓冲的channel:

var a stringvar c = make(chan int)  func f() {    a = "hello, world"    <-c}  func main() {    go f()    c <- 0    print(a) }

由于c是无缓冲的channel,因此必须保证取操作<-c 先于放操作c<- 0

推荐:golang教程栏目

更多相关文章

  1. golang中协程和线程的区别是什么?
  2. golang 管道线程安全吗
  3. golang是多线程模式吗?
  4. 深入SQLite多线程的使用总结详解
  5. 关于SQLite多线程的用法详解
  6. 没想到,这么简单的线程池用法,深藏这么多坑
  7. 协作,才能更好的中断线程
  8. Node.js多线程完全指南[每日前端夜话0x43]
  9. 实战 | Python爬取B站柯南弹幕+Gephi梳理主线剧情

随机推荐

  1. gdb捕获syscall条件和字符串比较
  2. Linux命令-网络命令:netstat
  3. 学linux向那方面发展比较好
  4. 【Linux】Linux下使用wget 命令下载JDK7
  5. 我是这样学习Linux下C语言编程的-编译命
  6. Debian 7开启ssh、telnet
  7. Linux如何查找大文件
  8. linux中ioremap与ioremap_cachable的区别
  9. 应用程序利用init.rc service获得root权
  10. Linux系统调用过程分析