Go基础系列:指定goroutine的执行顺序

栏目: Go · 发布时间: 7年前

内容简介:当关闭一个channel时,会使得这个channel变得可读。通过这个特性,可以实现一个goroutine执行顺序的技巧。如果一个goroutine A依赖于另一个goroutine B,在goroutine A中首先通过读goroutine B来阻塞自己,直到goroutine B关闭自身之后,goroutine A才会继续运行。这样,goroutine B就先于goroutine A运行。下面是一个指定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的作用都是"信号通道",用来传递消息。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大视觉创意宝典

大视觉创意宝典

2008-8 / 28.00元

《大视觉创意宝典:网页设计》主要内容:将优秀的网页分为设计、卡通、教育、金融、通讯、企业、房地产、娱乐等十四个章节,并详尽解析其页面布局、配色参考、设计特色及细节元素。丛书编写以设计基础的角度出发,具备速查、参照、案头工具书等功能。一起来看看 《大视觉创意宝典》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具