Go goroutine
并发和并行
并发
并发表示的是单核运行多个线程(通过CPU轮询实现的,比较损耗CPU,CPU切换的过程)
并行
并行表示的是多核上面运行多线程
goroutine
//协程是轻量级的线程
//共享的堆空间
//独立的栈空间
//在运行某个程序时,如何知道是否存在资源竞争问题。 方法很简单,在编译该程序时,增加一个参数 -race 即可
互斥锁
var lock sync.Mutex // 这里的这个就是申明一个Mutex的变量lock
lock.Lock() // 这个表示锁上
... // 需要锁的操作
lock.Unlock() // 这个表示的是解锁
channel
channel 的操作符
<- // C语言返指针的符号
通过 close()内置函数可以关闭channel的写入
channel 的定义方式
var channel_ chan typeX // 表示的是申明一个类型为typeX的chan引用
channel(引用数据类型) 的特性
作用:用来进行不同协程之间的通信
channel的本质是一个队列FIFO
使用channel的FIFO的特性导致了本身的线程安全
有着指定的长度,存满之后不能再存,已经取完了,再取的话就会报deadlock的错误
channel 的使用
var channel_ chan string // 定义一个string类型的chan名字叫做channel_
channel_ = make(string, 15)
// len() ,cap()
// 简单使用channel
func main() {
var channel_ chan int
channel_ = make(chan int, 10)
channel_ <- 1
channel_ <- 2
channel_ <- 3
channel_ <- 4
channel_ <- 5
for true {
fmt.Println(<-channel_) //当我们的channel已经取完数据的时候: fatal error: all goroutines are asleep - deadlock!
}
}
channel的遍历 for range
当我们进行遍历的时候使用了for range
1. closed 正常遍历,没问题,遍历的过程中其实就是将里面的数据取出来,并不是类似win32的msg的seek
2. open 报错deadlock,出现死锁,因为我们此时的for range不能确定channel的长度,取的时候超出了len
思考
主线程在等待所有 goroutine 全部完成的时间很难确定,我们应该怎么确定主线程完成的时间