我的编程空间,编程开发者的网络收藏夹
学习永远不晚

分析Go语言中CSP并发模型与Goroutine的基本使用

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

分析Go语言中CSP并发模型与Goroutine的基本使用

一、并发实现模型

1.1、多进程

在之前的文章当中我们曾经介绍过,进程是操作系统资源分配的最小单元。所以多进程是在操作系统层面的并发模型,因为所有的进程都是有操作系统的内核管理的。所以每个进程之间是独立的,每一个进程都会有自己单独的内存空间以及上下文信息,一个进程挂了不会影响其他进程的运行。这个也是多进程最大的优点,但是它的缺点也很明显。

最大的缺点就是开销很大,创建、销毁进程的开销是最高的,远远高于创建、销毁线程。并且由于进程之间互相独立,导致进程之间通信也是一个比较棘手的问题,进程之间共享内存也非常不方便。因为这些弊端使得在大多数场景当中使用多进程都不是一个很好的做法。

1.2、多线程

多线程是目前最流行的并发场景的解决方案,由于线程更加轻量级,创建和销毁的成本都很低。并且线程之间通信以及共享内存非常方便,和多进程相比开销要小得多。

但是多线程也有缺点,一个缺点也是开销。虽然线程的开销要比进程小得多,但是如果创建和销毁频繁的话仍然是不小的负担。针对这个问题诞生了线程池这种设计。创建一大批线程放入线程池当中,需要用的时候拿出来使用,用完了再放回,回收和领用代替了创建和销毁两个操作,大大提升了性能。另外一个问题是资源的共享,由于线程之间资源共享更加频繁,所以在一些场景当中我们需要加上锁等设计,避免并发带来的数据紊乱。以及需要避免死锁等问题。

1.3、协程

也叫做轻量级线程,本质上仍然是线程。相比于多线程和多进程来说,协程要小众得多,相信很多同学可能都没有听说过。和多线程最大的区别在于,协程的调度不是基于操作系统的而是基于程序的。

也就是说协程更像是程序里的函数,但是在执行的过程当中可以随时挂起、随时继续。

我们举个例子,比如这里有两个函数:


def A():
    print '1'
    print '2'
    print '3'

def B():
    print 'x'
    print 'y'
    print 'z'

如果我们在一个线程内执行A和B这两个函数,要么先执行A再执行B要么先执行B再执行A。输出的结果是确定的,但如果我们用写成来执行A和B,有可能A函数执行了一半刚输出了一条语句的时候就转而去执行B,B输出了一条又再回到A继续执行。不管执行的过程当中发生了几次中断和继续,在操作系统当中执行的线程都没有发生变化。也就是说这是程序级的调度。

那么和多线程相比,我们创建、销毁线程的开销就完全没有了,整个过程变得非常灵活。但是缺点是由于是程序级别的调度,所以需要编程语言自身的支持,如果语言本身不支持,就很难使用了。目前原生就支持协程的语言并不多,显然golang就是其中一个。

二、共享内存与CSP

我们常见的多线程模型一般是通过共享内存实现的,但是共享内存就会有很多问题。比如资源抢占的问题、一致性问题等等。为了解决这些问题,我们需要引入多线程锁、原子操作等等限制来保证程序执行结果的正确性。

除了共享内存模型之外,还有一个经典模型就是CSP模型。CSP模型其实并不新,发表已经好几十年了。CSP的英文全称是Communicating Sequential Processes,翻译过来的意思是通信顺序进程。CSP描述了并发系统中的互动模式,是一种面向并发的语言的源头。

Golang只使用了CSP当中关于Process/Channel的部分。简单来说Process映射Goroutine,Channel映射Channel。Goroutine即Golang当中的协程,Goroutine之间没有任何耦合,可以完全并发执行。Channel用于给Goroutine传递消息,保持数据同步。虽然Goroutine之间没有耦合,但是它们与Channel依然存在耦合。

整个Goroutine和Channel的结构有些类似于生产消费者模式,多个线程之间通过队列共享数据,从而保持线程之间独立。这里不过多深入,我们大概有一个印象即可。

三、Goroutine

Goroutine即golang当中的协程,这也是golang这门语言的核心精髓所在。正是因为Goroutine,所以golang才叫做golang,所以人们才选择golang。

相比于Java、Python等多线程的复杂的使用体验而言,golang当中的Goroutine的使用非常简单,简单到爆表。只需要一个关键字就够了,那就是go。所以你们应该明白为什么golang叫做Go语言不叫别的名字了吧?

比如我们有一个函数:


func Add(x, y int) int{
    z := x + y
    fmt.Println(z)
}

我们希望启动一个goroutine去执行它, 应该怎么办?很简单,只需要一行代码:


go Add(3, 4)

我们还可以用go关键字来使用goroutine来执行一个匿名函数:


go func(x, y int) {
    fmt.Println(x + y)
}(3, 4)

需要注意的是,当我们使用go关键字的时候,是不能获取返回值的。也就是说z := go Add(3, 4)是违法的。乍看起来似乎不合理,但是道理其实是很简单的。如果我们希望一个变量承接一个函数的返回值,说明这里的逻辑是串行的,那么我们使用goroutine的意义是什么?所以这里看似不合理,其实是设计者下了心思的。

以上就是分析Go语言中CSP并发模型与Goroutine的基本使用的详细内容,更多关于Go CSP并发模型 Goroutine的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

分析Go语言中CSP并发模型与Goroutine的基本使用

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go并发中goroutine模型与调度策略的示例分析

这篇文章给大家分享的是有关Go并发中goroutine模型与调度策略的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。单进程操作系统早期的单进程操作系统,可以理解为只有一个时间轴,CPU顺序执行每一个进程/
2023-06-25

Go语言中并发goroutine底层原理的示例分析

小编给大家分享一下Go语言中并发goroutine底层原理的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、基本概念①并发、并行区分1.概念并发:同一时间段内一个对象执行多个任务,充分利用时间并行:同一时刻,多个
2023-06-29

Go语言在大型项目开发中的适用性分析

Go语言在大型项目开发中的适用性分析随着互联网的快速发展,大型项目的开发变得日益复杂和多样化。开发人员在选择适合项目的编程语言时,需要考虑到语言的性能、可维护性、并发处理能力等因素。Go语言作为一种新兴的编程语言,备受开发者关注。本文将从
Go语言在大型项目开发中的适用性分析
2024-03-11

Go语言中chan通道的基本概念与使用方法

Go语言中chan通道的基本概念与使用方法Go语言作为一门并发编程语言,chan通道(channel)是其提供的一种重要的并发原语,用于在不同的goroutine之间进行通信和同步,实现数据传递和共享。chan通道是Go语言在语言级别提供
Go语言中chan通道的基本概念与使用方法
2024-03-12

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录