Go教程

go语言并发模型浅谈

本文主要是介绍go语言并发模型浅谈,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

    今天给大家说一说go语言并发模型,希望加深同学们对其理解,具体如下:

    Go 语言中实现了两种并发模型,一种是依赖于共享内存实现的线程-锁并发模型,另一种则是CSP并发模型。

    大多数编程语言(比如 C++、Java、Python 等)的并发逻辑都是基于操作系统的线程。并发执行单元(线程)之间的通信利用的就是操作系统提供的线程或进程间通信的原语,如共享内存、信号、管道、消息队列、套接字等。在这些通信原语中,使用最广泛的就是共享内存。 而 Go 语言从设计之初,就将解决上面传统并发模型问题作为目标,并在新并发模型设计中借鉴注明的 CSP并发模型。

    前者(线程与锁并发模型)类似于对底层硬件运行过程的形式化,程序的正确运行很大程度依赖于开发人员的能力和技巧,程序在出错时不易排查,写起代码来比较复杂,特别是在大型复杂的业务场景中,主要是 Go sync 包中的互斥锁、读写锁、条件变量、原子操作等同步原语。后者(CSP模型)目的在于简化并发程序的编写,让并发程序的编写顺序像编写顺序程序一样简单,是 Go 的主流并发模型。

CSP 理论

    CSP 并发模型最初由 Tony Hoare 于 1977 年的论文中被提出,它倡导使用通信的手段来共享内存。

    Do not communicate by sharing memory; instead, share memory by communicating.

    不要通过共享内存来通信,而要通过通信来实现内存共享。

    这句话也是 Go 的并发哲学,它依赖 CSP 模型,基于 channel 实现。

CSP 模型中存在两个关键的概念:

    并发实体,通常可以理解为执行线程,它们相互独立,且并发执行;

    通道,并发实体之间使用通道发送信息。

    与共享内存的线程与锁并发模型不同,CSP 中的并发实体是独立的,它们之间没有共享的内存空间。并发实体之间的数据交换通过通道实现,无论在通道中放数据还是从通道中取数据,都会导致并发实体的阻塞,直到通道中的数据被取出或者通道中被放入新的数据,并发实体通过这种方式实现同步。

    CSP 类似于我们常用的同步队列,它关注的是消息传输的方式,即通道,消息的具体发送实体和具体接收实体并不关注。发送和接收信息的并发实体可能不知道对方具体是谁,它们之间是互相解耦的。通道与并发实体也不是紧耦合的,通道可以独立地进行创建和放取,并在不同的并发实体中传递使用。

    CSP 通道的特性给并发编程提供了极大的灵活性,通道作为独立的对象,可以被任意创建、读取、放入数据,并在不同的并发实体中被使用。但是它也极易导致死锁,如果一个并发实体在读取一个永远没有数据放入的通道或者把数据放入一个永远不会被读取的通道中,那么它将被永远阻塞。

常见的线程模型

    常见的有用户级线程模型、内核级线程模型、两级线程模型

GMP 模型(Goroutine调度器模型)

    在操作系统提供的内核线程之上,Go 搭建了一个特有的两级线程模型。goroutine 机制实现了 M : N 的线程模型,goroutine 机制是协程(goroutine)的一种实现,Golang 内置的调度器,可以让多核 CPU 中每个 CPU 执行一个协程。

    以上便是关于go语言并发模型浅谈的全部内容,更多内容干货可关注慕课网~

这篇关于go语言并发模型浅谈的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!