0
点赞
收藏
分享

微信扫一扫

go语言学习之并发并行【字节跳动青训营】



文章目录

  • ​​一,并发编程​​
  • ​​1.1,并发和并行的区别​​
  • ​​1.2,Goroutine​​
  • ​​1.3,channel​​
  • ​​1.4,并发安全Lock​​
  • ​​1.5,WaitGroup​​

一,并发编程

1.1,并发和并行的区别

并发:

go语言学习之并发并行【字节跳动青训营】_开发语言

并发,就是通过一种算法将 CPU 资源合理地分配给多个任务,当一个任务执行 I/O 操作时,CPU 可以转而执行其它的任务,等到 I/O 操作完成以后,或者新的任务遇到 I/O 操作时,CPU 再回到原来的任务继续执行。

通过将 CPU 的使用权在恰当的时机分配给不同的任务,使得多个任务在视觉上看起来是一起执行的。CPU 的执行速度极快,多任务切换的时间也极短,用户根本感受不到,所以并发执行看起来才跟真的一样。

总结:

其实并发就是单核cpu不断的切换任务,给我们的感觉像是多个任务同时进行的。

并行:

go语言学习之并发并行【字节跳动青训营】_i++_02

多核 CPU 的每个核心都可以独立地执行一个任务,而且多个核心之间不会相互干扰。在不同核心上执行的多个任务,是真正地同时运行,这种状态就叫做并行。

一图来区别它们。

go语言学习之并发并行【字节跳动青训营】_golang_03

1.2,Goroutine

go中使用Goroutine来实现并发concurrently。Go应用程序可以并发运行数千个Goroutines。

func hello(i int) {
println("hello world : " + fmt.Sprint(i))
}

func main() {
for i := 0; i < 5; i++ {
go func(j int) {

hello(j)
}(i)
}
time.Sleep(time.Second)
}

如上代码开了五个任务并发执行,输出来看一下。

go语言学习之并发并行【字节跳动青训营】_学习_04

1.3,channel

Go 语言中的通道(channel)是一种特殊的类型。通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。

go语言学习之并发并行【字节跳动青训营】_开发语言_05

go语言学习之并发并行【字节跳动青训营】_i++_06

例子:

package main

func main() {
src := make(chan int)
dest := make(chan int, 3)
go func() {
defer close(src)
for i := 0; i < 10; i++ {
src <- i
}
}()
go func() {
defer close(dest)
for i := range src {
dest <- i * i
}
}()
for i := range dest {
println(i)
}
}

上述代码解释:

A子协程发生0~9数字到无缓冲通道。

B子协程将传入的数字计算为平方到有缓冲通道。

主协程输出结果如下:

go语言学习之并发并行【字节跳动青训营】_学习_07

1.4,并发安全Lock

线程安全是指,函数或者某个函数库在多线程的模式被调用时,能够正确处理多个线程之间共享变量,使得程序可以正常运行。

线程调用时线程之间会随时发生切换会发生不可预料的结果,出现线程不安全。

Lock可以在“关键的位置”提供串行特性,保证数据安全与独立

1.5,WaitGroup

Go语言中除了可以使用通道(channel)和互斥锁进行两个并发程序间的同步外,还可以使用等待组进行多个任务的同步,等待组可以保证在并发环境中完成指定数量的任务

WaitGroup 值在内部维护着一个计数,此计数的初始默认值为零。

go语言学习之并发并行【字节跳动青训营】_开发语言_08

func hello(i int) {
println("hello world : " + fmt.Sprint(i))
}

func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(j int) {
defer wg.Done()
hello(j)
}(i)
}
wg.Wait()
}

输出来看一下。

go语言学习之并发并行【字节跳动青训营】_学习_09



举报

相关推荐

0 条评论