go语言学习笔记—进阶—并发编程:轻量级线程goroutine——并发与并行

Locutus Locutus     2023-01-19     187

关键词:

并发编程

并发指在同一时间内可以执行多个任务。并发编程包含多线程编程、多进程编程、分布式程序等。

  • go语言的并发是指多线程并发,通过goroutine完成
  • goroutine类似线程,可以根据需要创建多个goroutine并发工作
  • goroutine是由go语言的编译器运行时(runtime)调度完成,而线程是由操作系统调度完成
  • 多个goroutine之间通过channel通道进行通信。goroutine和channel是go语言实现CSP(Communicating Sequential Process)并发模式的基础

并发与并行

  • 概念

并发:在不同时间点,把任务交给处理器处理。在同一时间点,任务并不会同时运行。

并行:把每一个任务分配给单个逻辑处理器独立完成。在同一个时间点,任务一定是同时运行。

并发与并行的区别:在同一个时间点,任务是否同时执行。

  • 例子

打电话与吃饭。在吃饭时,电话来了,需要停止吃饭去接电话,电话接完后回来继续吃饭。这个过程是并发执行。在吃饭时,电话来了,边吃饭边接电话。这个过程是并行执行。

在GOMAXPROCS数量与任务数相等时(>=),go程序可以做到并行执行。但一般情况下,go程序都是并发执行。


goroutine

线程池机制:在编写socket网络程序时,我们需要一个线程池,它为每个socket的收发包分配一个线程。在传统逻辑中,开发者需要维护线程数和CPU核数的对应关系,以保证每个任务及时分配到CPU上执行。面对实时的任务分配和并发线程处理需求,线程池就不好用了。

goroutine机制:开发者可以分配足够多的任务,编译器运行时(runtime)自动帮助开发者把任务分配到CPU上,让这些任务尽量并发运行。

go程序从main包的main()函数开始,在go程序启动时,编译器运行时(runtime)自动为main()函数创建一个默认goroutine。

go语言学习笔记—进阶—并发编程:调整并发的运行性能(gomaxprocs)(代码片段)

go语言的运行时(runtime)实现了一个小型任务调度器,它类似于操作系统的线程调度,可以高效地把CPU资源分配给每一个任务。通过runtime.GOMAXPROCS()函数,可以指定线程池中线程与CPU核心数量的对应关系,如下:... 查看详情

对于go语言的进阶与依赖管理|青训营笔记(代码片段)

...个进程中的多个线程之间可以并发执行。协程:用户态,轻量级线程,栈MB级别。线程:内核态,线程跑多个协程,栈KB级别。1.2.1快速打印(协程)go语言开启协程十分简单,只需要在函数的前面写上go关键字即可。funchello(iint)printl... 查看详情

go语言学习笔记—进阶—并发编程:go语言的协程goroutine,与普通程序的协程coroutine

拿Python程序的coroutine与Go程序的goroutine做比较,两者都可以把函数或语句运行在独立的环境,但还是有不同点:goroutine可能并行执行,但coroutine始终顺序执行狭义地说,goroutine可能发生在多线程环境下。goroutine... 查看详情

go并发编程

...ocess),进程内的线程(thread),以及进程内的协程(coroutine,也叫轻量级线程).与传统的线程和进程比,协程的最大优势在于其"轻量级",可以轻松创建上百万而不导致系统资源耗尽,而线程和进程通常最多不能超过一万个,这也是协程叫轻量... 查看详情

go语言并发编程(代码片段)

...与传统的系统级线程和进程相比,协程的大优势在于其“轻量级”,可以轻松创建上百万个而不会导致系统资源衰竭,而线程和进程通常多也不能超过1万个。这也是协程也叫轻量级线程的原因。golang原生支持并发编程轻量级线... 查看详情

go语言学习笔记—进阶—并发编程:为函数创建goroutine(代码片段)

使用go关键字为一个函数创建一个goroutine。函数与goroutine是一对多的关系,即可以为一个函数创建多个goroutine,一个goroutine必定只对应一个函数。为普通函数创建goroutine格式为一个go函数创建goroutine,写法如下:go... 查看详情

go语言学习笔记—进阶—并发编程:互斥锁(sync.mutex)——保证同时只有一个goroutine可以访问共享资源(代码片段)

互斥锁(英语:Mutualexclusion,缩写Mutex)是一种在多线程编程中,防止两条线程同时对同一共享资源(比如全局变量)进行读写的机制。互斥锁通过把代码切片成一个个的临界区域(criticalsection࿰... 查看详情

go语言并发编程

轻量级线程(goroutine)在编写socket网络程序时,需要提前准备一个线程池为每一个socket的收发包分配一个线程。开发人员需要在线程数量和CPU数量间建立一个对应关系,以保证每个任务能及时地被分配到CPU上进行处理,同时避免... 查看详情

go语言入门第五节go语言的并发编程

...一)1.Go语言的携程机制线程和携程的区别(携程是更加轻量级的线程)JDK5之后一个线程的默认栈道大小是5M,而携程栈的大小是2KJava中线程和系统线程的对应关系是1:1, 查看详情

go语言学习笔记—进阶—并发编程:通道(channel)——使用channel收发数据(代码片段)

创建channel之后,我们可以使用channel进行数据收发操作。使用channel发送(填充)数据使用特殊的操作符<-,把数据通过channel发送。格式通道变量<-值通道变量是上文通过make创建的通道实例;值可以是变量... 查看详情

go语言学习笔记—进阶—并发编程:通道(channel)——在多个goroutine之间通信的管道(代码片段)

单纯地并发执行函数是无意义的,函数之间需要交换数据才能体现并发执行的意义。虽然可以使用“共享内存”的方式交换数据,但共享内存在不同goroutine间易发生竞态问题。为了保证数据交换的正确性,必须使用互... 查看详情

go语言学习笔记—进阶—并发编程:通道(channel)——各种各样的通道(代码片段)

单向通道在声明通道时,我们可以设置只发送或只接收。这种被约束操作方向的通道称为单向通道。声明单向通道只发送:chan<-,只接收:<-chanvar通道实例chan<-元素类型//只发送数据var通道实例<-chan元素... 查看详情

go笔记(十五):并发编程(代码片段)

...过go关键字来开启goroutine(协程)即可。  goroutine(协程)是轻量级线程,goroutine(协程)的调度是由Golang运行时进行管理的。goroutine语法格式(创建协程):go函数名(参数列表)示例代码如下:packagemainimport("fmt""time")funcrest(msgstring)fori:=0;i... 查看详情

go语言学习笔记—进阶—并发编程(11):同步sync,等待组(sync.waitgroup)——保证在并发环境中完成指定数量的任务(代码片段)

除了使用通道channel和互斥锁sync.Mutex进行两个并发程序间的同步,我们还可以使用等待组(sync.WaitGroup)进行多个任务之间的同步。方法名功能(wg*WaitGroup)Add(deltaint)等待组的计数器+1(wg*WaitGroup)Done()等待组的计数器-1(... 查看详情

1.5go微服务实战(go语言基础)---并发编程

...ine之间是共享内存的。5.1 协程 协程是Go语言特有的一种轻量级线程,实际上,所有的Go语言都是通过goroutine运行的。 5.1.1 核心概念 进程:是指具有一定功能的程序关于某数据集合上的一次 查看详情

2.1go微服务实战(go语言进阶)---并发编程进阶

第8章 并发编程进阶8.1 竞态与并发模式 8.1.1 数据竞态 8.1.2 并发原理8.2 sync包 8.2.1 sync.Mutex互斥锁 8.2.2 sync.RWMutex多读写锁 8.2.3 sync.Once 8.2.4 sync.Cond 8.2.5 sync.Pool 8.2.6 sync.Map8.3 context包 8.3.1 应用场景 8.3.2 定义 8.3.3... 查看详情

09.go语言并发(代码片段)

Go语言并发并发指在同一时间内可以执行多个任务。并发编程含义比较广泛,包含多线程编程、多进程编程及分布式程序等。本章讲解的并发含义属于多线程编程。Go语言通过编译器运行时(runtime),从语言上支持了并发的特性... 查看详情

go语言学习笔记—进阶—并发编程(10):读写互斥锁(sync.rwmutex)——在读比写多的环境下,比互斥锁更高效(代码片段)

在读多写少的场景中,可以优先使用读写互斥锁,sync包中的RWMutex提供了读写互斥锁的封装。var(countint//某个逻辑中使用的变量,如包级别变量、结构体成员字段变量countGuardsync.RWMutex//变量名+Guard,以表示这个... 查看详情