首先明确一个观点并行 并发区别:
并行是指程序的运行状态,要有两个线程正在执行才能算是Parallelism;并发指程序的逻辑结构,Concurrency则只要有两个以上线程还在执行过程中即可。简单地说,Parallelism要在多核或者多处理器情况下才能做到,而Concurrency则不需要。golang 利用 go func() 的方式,可以进行多个函数的并行。
我们写C 的时候,假如用到多进程,我们通常都会用信号,管理等来进程进程间的通信, 那么golang是怎么实现这个的呢?? 直接看码说话吧
package main import ( "fmt" "time" ) func main() { timeout := make(chan bool,1) go func() { fmt.Println("------------ 子进程1--------------") t1 := time.Now().UnixNano() fmt.Println(t1) fmt.Println("这个一定会执行") time.Sleep(3 * time.Second) // timeout <- true timeout <- true }() fmt.Println("首先逻辑还是响应 main 函数") go func() { fmt.Println("------------ 子进程2--------------") t2 := time.Now().UnixNano() fmt.Println(t2) fmt.Println("相当于fork一个子进程在进行") }() ch := make(chan int) select { case <-ch: case <-timeout: fmt.Println("------------ 回到main函数 --------------") fmt.Println("task is timeout!") } fmt.Println("main 函数本身的输出") }
我们执行代码看一看结果
首先逻辑还是响应 main 函数 ------------ 子进程2-------------- 1471577916141068800 相当于fork一个子进程在进行 ------------ 子进程1-------------- 1471577916142068800 这个一定会执行 ------------ 回到main函数 -------------- task is timeout! main 函数本身的输出
分别从 纳秒的时间戳可以看出, 两个 go func() 几乎是同时执行的, 这种是golang并行处理的写法, goroutine是Go语言运行库的功能,不是操作系统提供的功能,goroutine不是用线程实现的。, golang同样提供了一种监视手段去监视每个并行处理逻辑的返回, select就是这种手段
按照目前golang的机制,假如调用select的话,循环监控,假如我们注释掉 timeout <- true 这句, 看看会有什么变化, 我们再执行 go run xx.go 的时候, 会提示fatal error: all goroutines are asleep - deadlock!, 这是可以理解为我们的select 监控的多个并行状态都没有回调响应,所以程序一直在等待,造成死锁导致了错误。
其实golang里面也可以用 sync的 waitgroup进行同步锁,但是这个跟协程并行似乎关系不大,有兴趣的也可以了解下
原文链接:https://www.f2er.com/go/189448.html