Go 并发实战--协程浅析 二

前言

继续上一篇的内容,我们介绍了go协程的实现中的几个核心的对象,也说了他们之间是如何合作工作的。


image.png

下面来看一些go协程的使用:

    go func() {
    fmt.Println("hello goroutine")
    }()

这样就完成了一个最简单的demo,相较而言go协程的使用同Java中线程的使用要简单太多了,至少少写了十几行有没有,也更加清晰了。

并发编程模型

就并发来说,通常分为Actor模型CSP(communicating sequential processes)模型多线程共享内存并发这么几种
多线程共享内存:
并发是大多数语言中的实现,比如说Java、C++、python等。这种方式基本上是最原始的并发编程的形式,我们需要通过锁来协同各个线程,保证并发的安全性。在这个基础上语言提供了&我们也实现了不少的并发工具和线程安全的数据结构,比如说ConcurrentHashMap、CountDownLatch、ReentrantLock等,这种编程模式对于程序员要求较高,需要非常清楚所使用API的各个细节及线程&内存实现,平心而论学习成本&门槛较高。
Actor模型:
由于多线程共享内存的编程模式,编程复杂度较高,并且容易出问题,调试起来更加的费劲,所以产生了像是Actor、CSP这些并发模型。
actor模型是处理并行计算的概念模型,它定义了系统部件行为和交互的一些规则,Actor模型内部的状态由它自己维护即它内部数据只能由它自己修改(通过消息传递来进行状态修改),所以使用Actors模型进行并发编程可以很好地避免这些问题,Actor由状态(state)、行为(Behavior)和邮箱(mailBox)三部分组成。实现比较经典的有Erlang,Java中也有对应的实现。
actor有这么几个好处:
1、事件模型驱动--Actor之间的通信是异步的
2、强隔离性--Actor中的方法不能由外部直接调用,所有的一切都通过消息传递进行的,从而避免了Actor之间的数据共享。
3、位置透明--无论Actor地址是在本地还是在远程机上对于代码来说都是一样的。
4、轻量性--Actor是非常轻量的计算单元,单个Actor仅占400多字节,只需少量内存就能达到高并发。
缺点:
CSP 模型:
CSP的核心理念是通过消息传递的尝试交互而不是共享内存,关注点更是仅关心消息的传递方式,而不是关心发送方和接收方。Actor也是通过消息来进行通信的,但是csp和actor的差异在于CSP进程通常是同步的(即任务被推送进Channel就立即执行,如果任务执行的线程正忙,则发送者就暂时无法推送新任务),Actor进程通常是异步的(消息传递给Actor后并不一定马上执行)。Actor 更加关注的是一个数据和行为封闭。
go支持共享内存这种比较原始的方式,也支持CSP模型,go的官方建议是强力建议使用消息传递也就是CSP的模式完成并发的构建,原话是这么说的:
Do not communicate by sharing memory; instead, share memory by communicating.
“不要以共享内存的方式来通信,相反,要通过通信来共享内存。”
go具有天然的并发性,为了保证在这个优势的基础上构建更加安全稳定的应用,go提出了这些建议。
我们在使用go写成的时候也应该尽可能的遵循这些建议,关于管道的使用可以看channel那篇文章,后面也会有相应的实战。
具体来说是这样的,下面来看一个很经典的生产者消费者的例子。

package main

import "fmt"

func main() {
    var channel = make(chan int, 3) // 用于消息通信的管道
    var c2 = make(chan int) // 防止main提前退出的通道
    // 同时开启两个go协程创建生产者消费者,能大致模拟同步进行
    go func() { // 开一个协程用来启动生产者
        for i:=0; i<100 ; i++ {
            go produce(channel, i)
        }
    }()
    go func() { // 开一个协程用来启动消费者
        for i:=0; i<100 ; i++ {
            go consumer(channel)
        }
    }()
    
    <-c2 // 防止主线程直接结束
}
func produce(channel chan int, data int) {
    channel <- data
}
func consumer(channel chan int) {
    fmt.Println(<- channel)
}

解释一下上述的代码,producer通过channel向生产者发送产品,而consumer从channel来取产品,producer&consumer并没通过一个共享内存直接交互,而是通过这种发消息的方式来进行协同的,包括阻塞等待等。
当然了,我们也可以用共享内存这种方式来完成并发编程,go也提供了对应的API:

    sync.Mutex.Lock()
    if i >2 {
       i = i + 1
     } else {
       i = i + 2
     }
    sync.Mutex.Unlock()

像上述代码,就通过sync.Mutex的锁操作,完成了共享变量i的一个存在竞态条件的操作。
剩下的go协程相关的就从后面并发编程的几个经典场景来理解吧,本篇暂时就先讲这么多。

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

推荐阅读更多精彩内容

  • Go 并发编程 选择 Go 编程的原因可能是看中它简单且强大,那么你其实可以选择C语言;除此之外,我看中 Go 的...
    PRE_ZHY阅读 886评论 1 6
  • 最近我们钻石小区大门口安装了一套汽车号牌识别系统,也就是说把汽车号牌输入系统里,只要是你的汽车出入小区,电子屏幕上...
    陆学峰阅读 1,636评论 6 10
  • 何处缕幽香,缘是栀子绕。 忆却儿时烂漫岗,朵朵相窈窕。 楼外响轻雷,闲雨听年少。 花落花开几度回? 故梦尘中老。
    淡月轩阅读 490评论 5 7
  • 1、我怎么如此幸运:凌晨醒来打开QQ空间豁然发现,自己之前从曾经写了那么多的文章,有一大大半是关于思维导图应用方...
    大漠先生工作室阅读 191评论 0 3
  • node基本概念 什么是node? node源于js的流行,因而出现性能极强的V8。Node是JavaScript...
    醉饮满天星阅读 1,021评论 0 1