yjf512 · 2015-02-21 11:09:07 · 1076 次点击 · 预计阅读时间 2 分钟 · 大约1分钟之前 开始浏览    
这是一个创建于 2015-02-21 11:09:07 的文章,其中的信息可能已经有所发展或是发生改变。

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

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

理解什么是goroutine?

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

实际上,一个goroutine并不相当于一个线程,goroutine的出现正是为了替代原来的线程概念成为最小的调度单位。一旦运行goroutine时,先去当先线程查找,如果线程阻塞了,则被分配到空闲的线程,如果没有空闲的线程,那么就会新建一个线程。注意的是,当goroutine执行完毕后,线程不会回收推出,而是成为了空闲的线程。

关于goroutine的理解,推荐看这个帖子:http://groups.google.com/group/golang-china/browse_thread/thread/0e9d683ca766ec00

goroutine的使用

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

f(11)

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

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

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

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

这里就引进了channel的概念

channel的使用

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

上面的例子就可以改为:

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

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的进一步理解:

http://blog.dccmx.com/2011/05/magic-of-channel-in-go/

http://blog.dccmx.com/2012/03/small-problem-about-goroutine/

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

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

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

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

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

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

http://blog.dccmx.com/2011/05/magic-of-channel-in-go/ 里面的一个例子很好:

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

有缓冲的channel:

var a string
var 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 string
var c = make(chan int) func f() {
a = "hello, world"
<-c
} func main() {
go f()
c <- 0
print(a) }

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

参考文档:

Go语言中的channel魔法

http://blog.dccmx.com/2011/05/magic-of-channel-in-go/

谈点对goroutine的理解

http://comments.gmane.org/gmane.comp.lang.go.china/676

goroutine效果测试

http://webcache.googleusercontent.com/search?q=cache:Vwa9TGfQKtoJ:blog.weizhe.net/tag/goroutine%2520golang+&cd=6&hl=en&ct=clnk

Effective Go

http://golang.org/doc/effective_go.html#goroutines

go17---并发的更多相关文章

  1. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  2. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  3. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  4. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  5. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  6. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  7. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  8. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  9. 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)

    建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...

  10. 理解Storm并发

    作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 注:本文主要内容翻译自understanding-the-parall ...

随机推荐

  1. node.js 的介绍

    1.node.js是什么? (1)node.js不是一门编程语言, 是一个开发平台,就像Java开发平台,Net平台,PHP开发平台,Apple开发平台.(何为开发平台?有对应的编程语言,有语言运行时 ...

  2. rem怎么算

    * rem : html根标签的 font-size决定* em 相对于父标签的font-size 决定的* 设计稿的宽一般都是 750px ---> 20px* 750px 1rem = 10 ...

  3. PHP解惑(一)

    PHP给人的印象是入门简单的语言.当你的技术能力达到一定阶段时,会发现情况并非如此. PHP采用"极简主义",就是以入门容易为准则设计的,在十几年的持续发展历程中,它早已成为一个开 ...

  4. linux下硬盘分区、格式化以及文件管理系统

    1.添加虚拟硬盘 (1)点击编辑虚拟机位置,然后点击添加   (2)点击添加硬盘 (3)点击下一步 (4)创建新虚拟磁盘并点击下一步 (5)指定磁盘容量并且点击下一步 (6)点击完成 2.系统分区 当 ...

  5. UVa 10129 单词 (欧拉通路)

    题意: 输入n(n≤100000)个单词,是否可以把所有这些单词排成一个序列,使得每个单词的第一个字母和上一个单词的最后一个字母相同(例如acm.malform.mouse).每个单词最 多包含100 ...

  6. C语言基础--自加自减

    有如下代码: unsigned int temp1,temp2, i=5,j=5; temp1=i++; temp2=++j; 结果是 temp1=5,temp2=6: i=6,j=6: 版权声明:本 ...

  7. Mvc Action可以通过jsonp方式调取

    jsonp其实是一种特殊的数据获取格式,所以在Aicton直接调取的时候肯定会出现问题,下面代码是对于jsonp调取做的处理 protected virtual ActionResult Create ...

  8. Python模块:configparser、hashlib、(subprocess)

    configparser模块: 此模块用于生成和修改常见配置文档. 一个常见配置文件(.ini的后缀名)格式如下: [DEFAULT] # DEFAULT 是指后面的字典里都会默认有的内容 Serve ...

  9. 郁闷的出纳员(bzoj 1503)

    Description OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常 ...

  10. Ubuntu 16.04安装Ubuntu After Install工具实现常用软件批量安装

    这个软件集成了常用且好用的软件,且只需要选择需要的软件之后自动安装好,不需要额外设置. 安装: sudo add-apt-repository ppa:thefanclub/ubuntu-after- ...