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

前端之家收集整理的这篇文章主要介绍了关于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("------------ 子进程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

猜你在找的Go相关文章