zoukankan      html  css  js  c++  java
  • Go基础系列:指定goroutine的执行顺序

    Go channel系列

    当关闭一个channel时,会使得这个channel变得可读。通过这个特性,可以实现一个goroutine执行顺序的技巧。

    如果一个goroutine A依赖于另一个goroutine B,在goroutine A中首先通过读goroutine B来阻塞自己,直到goroutine B关闭自身之后,goroutine A才会继续运行。这样,goroutine B就先于goroutine A运行。

    下面是一个指定goroutine执行顺序的示例,它保证的顺序是A()-->B()-->C()

    package main
    
    import (
    	"fmt"
    	"time"
    )
    
    // A首先被a阻塞,A()结束后关闭b,使b可读
    func A(a, b chan struct{}) {
    	<-a
    	fmt.Println("A()!")
    	time.Sleep(time.Second)
    	close(b)
    }
    
    // B首先被a阻塞,B()结束后关闭b,使b可读
    func B(a, b chan struct{}) {
    	<-a
    	fmt.Println("B()!")
    	close(b)
    }
    
    // C首先被a阻塞
    func C(a chan struct{}) {
    	<-a
    	fmt.Println("C()!")
    }
    
    func main() {
    	x := make(chan struct{})
    	y := make(chan struct{})
    	z := make(chan struct{})
    
    	go C(z)
    	go A(x, y)
    	go C(z)
    	go B(y, z)
    	go C(z)
    	
    	// 关闭x,让x可读
    	close(x)
    	time.Sleep(3 * time.Second)
    }
    

    上面的示例中:A goroutine被x阻塞,B goroutine被y阻塞,C goroutine被z阻塞。C依赖的z由B关闭,B依赖的y由A关闭。

    如此一来,当main goroutine中的x被关闭后,A()从阻塞中释放,继续执行,关闭y,然后B从阻塞中释放,继续执行,关闭z,C得以释放。由于z被关闭后,z仍然可读,所以多次执行C(z)不会出问题。

    A()和B()不能多次执行,因为close()不能操作已被关闭的channel。

    注意,上面的channel都是struct{}类型的,整个过程中,x、y、z这3个通道都没有传递数据,而是直接关闭来释放通道,让某些阻塞的goroutine继续执行下去。显然,这里的x、y、z的作用都是"信号通道",用来传递消息。

  • 相关阅读:
    Java SE(2)
    Java SE(1)
    第二次作业
    Markdown 进阶
    关于主题
    Markdown入门指南
    网络游戏架构与微服务架构简单对比
    微服务框架的存储架构
    轻量级微服务框架的通信架构
    页面静态化
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/9994652.html
Copyright © 2011-2022 走看看