关于golang的协程并行的控制与示例程序

首先明确一个观点并行 并发区别:

并行是指程序的运行状态,要有两个线程正在执行才能算是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("------------ channel 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("------------ channel  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 函数
------------ channel 2--------------
1471577916141068800
相当于fork一个子进程在进行
------------ channel 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 进行同步锁,但是这个跟协程并行似乎关系不大,有兴趣的也可以了解下

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章