Go并发编程(上)

并发编程

Go语言在语言层面上就支持了并行,虽然一般来说,程序会被编写为顺序执行的,因为这样程序写起来很简单,逻辑也很简单,而且还很容易维护,但其实在某些情况下,并行执行多个任务会带来更大的优势。

Go语言中里的并发指的是能让某个函数独立于其他函数运行的能力,当一个函数创建为协程goroutine时,Go语言会将其视为一个独立的工作单元,这个单元会被调度到可用调度到可用的逻辑处理器上执行。

并发与并行

在了解并发编程之前,我们需要先明白什么是操作系统的线程'thread'和进程'process':

当运行一个程序的时候,操作系统会为这个应用程序启动一个进程,而一个线程是一个执行空间,在进程当中可以包括有多个线程,最初始的线程被称为主线程


操作系统是在物理处理器上调度线程来运行的,而Go语言在运行时会在逻辑处理器上调度goroutine来运行。
而且,goroutine是非常强大的,举个例子:
正在运行的goroutine需要执行一个阻塞的系统调用,比如打开一个文件,当这类发生调用的时候,线程和goroutine会从逻辑处理器上分离,该线程会继续阻塞,等待系统调用的返回。一旦被阻塞的系统调用执行完成并返回,对应的goroutine会放回到本地运行队列,而之前的线程会保存好,以便之后可以继续使用。


但并发concurrency和并行parallelism又是完全不同的两个概念,并行是让不同的代码片段同时在不同的物理处理器上执行。

并行的关键是同时做很多事情,而并发是指同时管理很多事情

接下来就一起领略一下Go语言并发编程的魅力所在吧!

制定使用核心数

Go语言默认会调用CPU核心数,这些功能都是自动调整的,但也提供了相应的标准库---flags,如下

var numCores = flag.Int("n", 2, "CPU核心数")

写个简单的程序:

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println("Start")
    go longWait()
    go shortWait()
    fmt.Println("挂起MAIN()")
    time.Sleep(10 * time.Second)
    fmt.Println("End")
}

func longWait() {
    fmt.Println("LongWait() Starting...")
    time.Sleep(5 * time.Second)
    fmt.Println("LongWait() Ending...")
}

func shortWait() {
    fmt.Println("ShortWait() Starting...")
    time.Sleep(2 * time.Second)
    fmt.Println("ShortWait() Ending...")
}
/** The result is:
Start
挂起MAIN()
LongWait() Starting...
ShortWait() Starting...
ShortWait() Ending...
LongWait() Ending...
End
 */

整个函数的执行过程很简单,就是一个简单的并行运行,然后每一个函数都在运行的开始和结束阶段输出了消息,为了模拟它们的运算时间消耗,使用time.Sleep()函数进行模拟。而且如果我们使用计时函数进行观察的话,我们还可以发现,整个程序的运行时间就是main()当中的10s,这都归功于go这一个关键词,它可以让两个函数并发的执行,我们可以尝试着把go去掉,那么我们可以发现运行的结果的顺序与时间也是与上面的完全不同的:

Start
LongWait() Starting...
LongWait() Ending...
ShortWait() Starting...
ShortWait() Ending...
挂起MAIN()
End
The last time is:  17.0004881s

这样,我们就对并发编程有了一个初步的认识,下一次我们将会介绍一下协程又是如何实现的。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354

推荐阅读更多精彩内容

  • 介绍 上一篇文章我对操作系统级别的调度进行了讲解,这对理解 Go 语言的调度器是很重要的。这篇文章,我将解释下 G...
    达菲格阅读 8,002评论 1 30
  • [toc] 原文:Scheduling In Go : Part II - Go Scheduler 前言 这是本...
    豆腐匠阅读 1,030评论 0 8
  • 理解并发和并行并发:同时管理多件事情。并行:同时做多件事情。表示同时发生了多件事情,通过时间片切换,哪怕只有单一的...
    Chuck_Hu阅读 6,042评论 7 44
  • GO并发使用goroutine运行程序,检测并修正状态,利用通道共享数据。通常程序会被编写为一个顺序执行并完成一个...
    小线亮亮阅读 552评论 0 1
  • 概述 简而言之,所谓并发编程是指在一台处理器上“同时”处理多个任务。 随着硬件的发展,并发程序变得越来越重要。We...
    泡泡龙吐泡泡阅读 7,910评论 1 12