Golang CSP并发机制及使用模型

 更新时间:2022年05月25日 16:16:32   作者:falm  
这篇文章主要为大家介绍了Golang CSP并发机制及使用模型,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

今天介绍一下 go语言的并发机制以及它所使用的CSP并发模型

CSP并发模型

CSP模型是上个世纪七十年代提出的,用于描述两个独立的并发实体通过共享的通讯 channel(管道)进行通信的并发模型。 CSP中channel是第一类对象,它不关注发送消息的实体,而关注与发送消息时使用的channel。

Golang CSP

Golang 就是借用CSP模型的一些概念为之实现并发进行理论支持,其实从实际上出发,go语言并没有,完全实现了CSP模型的所有理论,仅仅是借用了 process和channel这两个概念。process是在go语言上的表现就是 goroutine 是实际并发执行的实体,每个实体之间是通过channel通讯来实现数据共享。

Channel

Golang中使用 CSP中 channel 这个概念。channel 是被单独创建并且可以在进程之间传递,它的通信模式类似于 boss-worker 模式的,一个实体通过将消息发送到channel 中,然后又监听这个 channel 的实体处理,两个实体之间是匿名的,这个就实现实体中间的解耦,其中 channel 是同步的一个消息被发送到 channel 中,最终是一定要被另外的实体消费掉的,在实现原理上其实是一个阻塞的消息队列。

Goroutine

Goroutine 是实际并发执行的实体,它底层是使用协程(coroutine)实现并发,coroutine是一种运行在用户态的用户线程,类似于 greenthread,go底层选择使用coroutine的出发点是因为,它具有以下特点:

  • 用户空间 避免了内核态和用户态的切换导致的成本
  • 可以由语言和框架层进行调度
  • 更小的栈空间允许创建大量的实例

可以看到第二条 用户空间线程的调度不是由操作系统来完成的,像在java 1.3中使用的greenthread的是由JVM统一调度的(后java已经改为内核线程),还有在ruby中的fiber(半协程) 是需要在重新中自己进行调度的,而goroutine是在golang层面提供了调度器,并且对网络IO库进行了封装,屏蔽了复杂的细节,对外提供统一的语法关键字支持,简化了并发程序编写的成本。

Goroutine 调度器

上节已经说了,golang使用goroutine做为最小的执行单位,但是这个执行单位还是在用户空间,实际上最后被处理器执行的还是内核中的线程,用户线程和内核线程的调度方法有:

N:1 多个用户线程对应一个内核线程

1:1 一个用户线程对应一个内核线程

M:N 用户线程和内核线程是多对多的对应关系

golang 通过为goroutine提供语言层面的调度器,来实现了高效率的M:N线程对应关系

调度示意

图中

  • M:是内核线程
  • P : 是调度协调,用于协调M和G的执行,内核线程只有拿到了 P才能对goroutine继续调度执行,一般都是通过限定P的个数来控制golang的并发度
  • G : 是待执行的goroutine,包含这个goroutine的栈空间
  • Gn : 灰色背景的Gn 是已经挂起的goroutine,它们被添加到了执行队列中,然后需要等待网络IO的goroutine,当P通过 epoll查询到特定的fd的时候,会重新调度起对应的,正在挂起的goroutine。

Golang为了调度的公平性,在调度器加入了steal working 算法 ,在一个P自己的执行队列,处理完之后,它会先到全局的执行队列中偷G进行处理,如果没有的话,再会到其他P的执行队列中抢G来进行处理。

总结

Golang实现了 CSP 并发模型做为并发基础,底层使用goroutine做为并发实体,goroutine非常轻量级可以创建几十万个实体。实体间通过 channel 继续匿名消息传递使之解耦,在语言层面实现了自动调度,这样屏蔽了很多内部细节,对外提供简单的语法关键字,大大简化了并发编程的思维转换和管理线程的复杂性。

以上就是Golang CSP并发机制及使用模型的详细内容,更多关于Golang CSP并发模型的资料请关注脚本之家其它相关文章!

相关文章

  • 使用client go实现自定义控制器的方法

    使用client go实现自定义控制器的方法

    本文我们来使用client-go实现一个自定义控制器,通过判断service的Annotations属性是否包含ingress/http,如果包含则创建ingress,如果不包含则不创建,对client go自定义控制器相关知识感兴趣的朋友一起看看吧
    2022-05-05
  • Golang中goroutine和channel使用介绍深入分析

    Golang中goroutine和channel使用介绍深入分析

    一次只做一件事情并不是完成任务最快的方法,一些大的任务可以拆解成若干个小任务,goroutine可以让程序同时处理几个不同的任务,goroutine使用channel来协调它们的工作,channel允许goroutine互相发送数据并同步,这样一个goroutine就不会领先于另一个goroutine
    2023-01-01
  • Go映射的使用

    Go映射的使用

    Go提供了另一个重要的数据类型,称为map,它将唯一键映射到值,本文主要介绍了Go映射的使用,包括声明映射、初始化映射、操作映射等,感兴趣的可以了解一下
    2023-11-11
  • Qt6.5 grpc组件使用 + golang grpc server示例详解

    Qt6.5 grpc组件使用 + golang grpc server

    这篇文章主要介绍了Qt6.5 grpc组件使用+golang grpc server示例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • go语言中Timer和Ticker两种计时器的使用

    go语言中Timer和Ticker两种计时器的使用

    go语言中有Timer和Ticker这样的两种计时器,两种计时器分别实现了不同的计时功能,本文主要介绍了go语言中Timer和Ticker两种计时器的使用,感兴趣的可以了解一下
    2024-08-08
  • 在Golang中使用C语言代码实例

    在Golang中使用C语言代码实例

    这篇文章主要介绍了在Golang中使用C语言代码实例,本文先是给出了一个Hello World例子、Golang 引用 C例子,并总结了一些要注意的地方,需要的朋友可以参考下
    2014-10-10
  • Go源码分析之预分配slice内存

    Go源码分析之预分配slice内存

    这篇文章主要从Go语言源码带大家分析一下预分配slice内存的相关知识,文中的示例代码简洁易懂,对我们深入了解go有一定的帮助,需要的可以学习一下
    2023-08-08
  • Golang实现支付宝沙箱支付的方法步骤

    Golang实现支付宝沙箱支付的方法步骤

    本文主要介绍了Golang实现支付宝沙箱支付的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Go Java 算法之字符串解码示例详解

    Go Java 算法之字符串解码示例详解

    这篇文章主要为大家介绍了Go Java 算法之字符串解码示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Go语言库系列之dotsql详解

    Go语言库系列之dotsql详解

    这篇文章主要介绍了Go语言库系列之dotsql的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04

最新评论