Go语言为并发而生
随着处理器技术的发展,单核时代以处理器频率来提高运行效率的方式遇到了瓶颈,单核 CPU 发展的停滞,给多核 CPU 的发展带来了机遇。相应地,编程语言也开始逐步向并行化的方向发展。
虽然一些编程语言的框架在不断地提高多核资源使用效率,例如 Java 的 Netty 等,但仍然需要开发人员花费大量的时间和精力搞懂这些框架的运行原理后才能熟练掌握。
作为程序员,要开发出能充分利用硬件资源的应用程序是一件很难的事情。现代计算机都拥有多个核,但是大部分编程语言都没有有效的工具让程序可以轻易利用这些资源。编程时需要写大量的线程同步代码来利用多个核,很容易导致错误。
Go语言正是在多核和网络化的时代背景下诞生的原生支持并发的编程语言。Go语言从底层原生支持并发,无须第三方库,开发人员可以很轻松地在编写程序时决定怎么使用 CPU 资源。
Go语言的并发是基于 goroutine 的,goroutine 类似于线程,但并非线程。可以将 goroutine 理解为一种虚拟线程。Go语言运行时会参与调度 goroutine,并将 goroutine 理地分配到每个 CPU 中,限度地使用 CPU 性能。
多个 goroutine 中,Go语言使用通道(channel)进行通信,通道是一种内置的数据结构,可以让用户在不同的 goroutine 之间同步发送具有类型的消息。这让编程模型更倾向于在 goroutine 之间发送消息,而不是让多个 goroutine 争夺同一个数据的使用权。
程序可以将需要并发的环节设计为生产者模式和消费者的模式,将数据放入通道。通道另外一端的代码将这些数据进行并发计算并返回结果,如下图所示。

提示:Go语言通过通道可以实现多个 goroutine 之间内存共享。
【实例】生产者每秒生成一个字符串,并通过通道传给消费者,生产者使用两个 goroutine 并发运行,消费者在 main() 函数的 goroutine 中进行处理。
package main
import (
"fmt"
"math/rand"
"time"
)
// 数据生产者
func producer(header string, channel chan<- string) {
// 无限循环, 不停地生产数据
for {
// 将随机数和字符串格式化为字符串发送给通道
channel <- fmt.Sprintf("%s: %v", header, rand.Int31())
// 等待1秒
time.Sleep(time.Second)
}
}
// 数据消费者
func customer(channel <-chan string) {
// 不停地获取数据
for {
// 从通道中取出数据, 此处会阻塞直到信道中返回数据
message := <-channel
// 打印数据
fmt.Println(message)
}
}
func main() {
// 创建一个字符串类型的通道
channel := make(chan string)
// 创建producer()函数的并发goroutine
go producer("cat", channel)
go producer("dog", channel)
// 数据消费函数
customer(channel)
}
运行结果:
dog: 2019727887
cat: 1298498081
dog: 939984059
cat: 1427131847
cat: 911902081
dog: 1474941318
dog: 140954425
cat: 336122540
cat: 208240456
dog: 646203300
对代码的分析:
第 03 行,导入格式化(fmt)、随机数(math/rand)、时间(time)包参与编译。
第 10 行,生产数据的函数,传入一个标记类型的字符串及一个只能写入的通道。
第 13 行,for{} 构成一个无限循环。
第 15 行,使用 rand.Int31() 生成一个随机数,使用 fmt.Sprintf() 函数将 header 和随机数格式化为字符串。
第 18 行,使用 time.Sleep() 函数暂停 1 秒再执行这个函数。如果在 goroutine 中执行时,暂停不会影响其他 goroutine 的执行。
第 23 行,消费数据的函数,传入一个只能写入的通道。
第 26 行,构造一个不断消费消息的循环。
第 28 行,从通道中取出数据。
第 31 行,将取出的数据进行打印。
第 35 行,程序的入口函数,总是在程序开始时执行。
第 37 行,实例化一个字符串类型的通道。
第 39 行和第 40 行,并发执行一个生产者函数,两行分别创建了这个函数搭配不同参数的两个 goroutine。
第 42 行,执行消费者函数通过通道进行数据消费。
整段代码中,没有线程创建,没有线程池也没有加锁,仅仅通过关键字 go 实现 goroutine,和通道实现数据交换。
- 随机文章
- 直播 中国 马尔代夫战争(中马战斗:现场直播更新)
- 亚洲强队马尔代夫(马尔代夫成为亚洲足球强队)
- 中国岛屿马尔代夫(中国援建的“梦之岛”在马尔代夫建成)
- 中国 马尔代夫 历史比分(中国与马尔代夫足球历史交锋结果回顾)
- 马尔代夫荧光酒店(马尔代夫独特荧光酒店,美不胜收!)
- 泰国 马来 马尔代夫(东南亚三地旅游指南:泰国、马来西亚、马尔代夫)
- 北京马尔代夫新闻(北京公司计划开设马尔代夫主题度假村)
- 壁纸马尔代夫沙滩(享受马尔代夫度假时光:美丽沙滩壁纸)
- 太原娄烦马尔代夫(太原娄烦游客可直飞马尔代夫度假了!)
- 乐宜马尔代夫图文(浅谈乐宜马尔代夫:天堂般的旅行胜地)
- 小野解说马尔代夫(小野带你游马尔代夫,感受海岛之美!)
- 成都马尔代夫地址(成都“马尔代夫”去哪儿?答案在这里)
- 广东夫妇马尔代夫(广东夫妇在马尔代夫迎来浪漫蜜月之旅)
- 安庆马尔代夫风景(安徽有座马尔代夫,水清沙白美不胜收)
- 海上秋千马尔代夫(马尔代夫海上秋千,极致浪漫惊艳全球)
- 局座评价马尔代夫(局座点赞马尔代夫:天堂般的度假胜地)
- 泰国过境马尔代夫(泰国旅客可经马尔代夫中转前往第三国)
- 温州马尔代夫别墅(温州奢华马尔代夫别墅:度假不用出国)
- 渝中半岛马尔代夫(渝中半岛打造仿佛马尔代夫的度假胜地)
- 入境 马尔代夫(领略马尔代夫美景,放松身心享受悠闲假期)
- 安庆马尔代夫在哪(安庆哪里有类似马尔代夫的旅游胜地?)
- 迪拜马尔代夫位置(迪拜皇家度假村坐落于美丽的马尔代夫)
- 马尔代夫不用滤镜(马尔代夫的真实面貌,不需要加滤镜!)
- 马尔代夫为何有钱(马尔代夫奢华背后的财源到底是什么?)
- 马尔代夫亲子优惠(马尔代夫亲子游优惠活动,快来享受吧)
- 购买马尔代夫别墅(马尔代夫豪华别墅售卖,尽享清凉海风)
- 长春马尔代夫报价(长春至马尔代夫旅游报价,尽在这里!)
- 深圳南山马尔代夫(深圳南山将推出马尔代夫风情主题公园)
- 震撼马尔代夫视频(令人惊艳!马尔代夫美景视频震撼呈现)
- 马尔代夫到新西兰(从马尔代夫到新西兰:探索南半球天堂)
