Golang channel 笔记
初学GO的并行写法,如有错误还请指正。
先上总结:
- 主线程(main)与主线程中启动的其他线程存在一种包含关系,当主线程执行完毕后,其他线程也会结束
- channel变量实现了类似java中的锁机制
主线程结束后,其他线程也会自动结束
func main(){
a:=make(chan int)
go f(a)
time.Sleep(time.Duration(2)*time.Millisecond)
fmt.Println("main thread running")
a<-2
fmt.Println("main thread finished")
// time.Sleep(time.Duration(20)*time.Millisecond)
}
func f (b chan int){
fmt.Println("haha")
fmt.Println(<-b)
}
输出:
haha
main thread running
main thread finished
2
OR
haha
main thread running
main thread finished
输出存在两种情况,第一种情况是当main线程给a chan赋值时,f线程被激活运行,在main打印完“finished”之后还未结束,f线程有机会 输出chan的值
第二种情况:main线程在打印结束后线程运行结束,虽然这时f线程也获得了值并即将打印,但是在main线程结束后,f线程也自动结束,这一部分的系统调用(Print)还未执行就一并结束了。
证明:在main打印完finished之后加一段sleep,就可以保证f线程一定输出2
chan变量自动实现了锁机制
package main
import "fmt"
func main(){
a:=make(chan int)
a<-2 // input a value when nobody is receiving ========> main thread is blocked
// go func(b chan int){
// fmt.Println(<-b)
// }(a)
go f(a)
}
func f (b chan int){
fmt.Println("haha")
fmt.Println(<-b)
}
/**
* results: all threads are blocked
* 实际上,f这个thread压根都没有运行,因为main thread在a赋值的时候已经block了,然后不会启用f,导致死锁
**/
如果在给chan 赋值的时候,除了主线程之外还有其他线程已经在运行,就算他们恰好因为这个chan而阻塞就不会引发死锁。