Go语言中的多线程 | 青训营笔记

341 阅读2分钟

并发: 多线程程序在一个核的cpu上运行,通过时间片的分配来达到多线程的效果或者多线程程序在多个核的cpu上运行。

并行: 并行则就是广义上的并行

Go可以充分发挥多核优势,高效运行

线程: 是属于内核态的,直接通过cpu来控制,量级比较的重,线程中可以有多个协程 栈MB级

协程: 用户态的,轻量级线程,栈KB级

通过语句go来添加一个协程

协程之间的通信: 提倡通过通信共享内存而不是通过共享内存而实现通信

通过通信共享内存: 协程之间通过通道交互发送数据来达到共享通道这块资源

通过共享内存实现通信: 协程之间通过互斥的访问临界区资源获取信息来达到通信的效果。需要互斥的访问临界区资源导致了资源的利用率降低。 通道的类型

定义方式:make(chan 元素类型,[缓冲大小])

  • 无缓冲通道 make(chan int)

  • 有缓冲通道 make(chan int,2)

package main
import()
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)
	}
}

线程安全问题: 通过加锁来达到互斥访问实现线程的安全

package main
​
import (
    "sync"
    "time"
)
var(
    x  int64
    lock sync.Mutex
)
func main(){
    x=0
    for i := 0; i < 5; i++ {
        go addWithoutLock()
    }
    time.Sleep(time.Second)
    println("WithoutLock:",x)
    x=0
    for i := 0; i < 5; i++ {
        go addWithLock()
        
    }
    time.Sleep(time.Second)
    println("WithLock:",x)
}
​
func addWithLock() {
    for i := 0; i < 2000; i++ {
        lock.Lock()
        x+=1
        lock.Unlock()
    }
}
​
func addWithoutLock() {
    for i := 0; i < 2000; i++ {
        
        x+=1
    
    }
}

WaitGRoup:

WaitGroup 实现并发等待 WaitGroup 类实现的功能是:等待一系列协程并发地执行完毕。如果不等待所有协程执行完毕,可能会导致一些线程安全问题。sync.WaitGroup 包含 3 个方法:

作用方法
Add(delta int)主协程调用该方法,设置 delta 为需要等待的协程数量
Done()每个子协程运行起来,当每个子协程执行结束后,调用 Done() 表示子协程运行结束
Wait()当所有协程执行完毕后,代码块可使用 Wait() ,当 delta ==0时,才执行后续代码 例