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的作用都是"信号通道",用来传递消息。

Go基础系列:指定goroutine的执行顺序的更多相关文章

  1. go语言基础之多个defer执行顺序

    1. 多个defer执行顺序 如果一个函数中有多个defer语句,它们会以LIFO(后进先出)的顺序执行.哪怕函数或某个延迟调用发生错误,这些调用依旧会被执.示例: package main //必须 ...

  2. Springboot:单元测试@FixMethodOrder注解指定测试方法的执行顺序

    我们在写JUnit测试用例时,有时候需要按照定义顺序执行我们的单元测试方法,比如如在测试数据库相关的用例时候要按照测试插入.查询.删除的顺序测试.如果不按照这个顺序测试可能会出现问题,比如删除方法在前 ...

  3. JAVA基础2——类初始化相关执行顺序

    类初始化相关执行顺序 几个概念说明 代码块的含义与作用 static静态代码块: 一般用于初始化类中的静态变量.比如:给静态的数组或者list变量赋初值.使用static静态代码块进行初始化与直接在定 ...

  4. testng基础知识:注解的执行顺序

    1. 单类,无继承父子关系 code: public class basicTest { @BeforeSuite(alwaysRun = true) public void beforeSuite_ ...

  5. - > 贪心基础入门讲解五——任务执行顺序

    分析: 本题可以抽象成,从一个整数开始,每次减去a,再加上b (a,b都是正数),要求每次操作都不产生负数. 针对本题a[i] = R[i], b[i] = R[i] – O[i],注意O[i] &l ...

  6. Java 基础:继承中的执行顺序

    1.单独的父类测试 Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分, 它们的执行顺序相对来说比较简单,用程序也很容易验证. 比如新建一个 ...

  7. WPF 基础 - 点击事件的执行顺序及 Button 点击事件的特殊性

    1. 点击事件的执行顺序 PreviewMouseLeftButtonDown PreviewMouseDown MouseLeftButtonDown MouseDown PreviewMouseL ...

  8. Java基础-继承-子类与父类执行顺序

    代码 public class Test { public static void main(String[] args) { new Circle(); } } class Draw { publi ...

  9. Java多线程系列四——控制线程执行顺序

    假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...

随机推荐

  1. UC浏览器input文本框输入文字回车键自动提交

    这是测试今天在jira给我提出的一个bug 下面是贴的代码 屏蔽或者禁止回车键 <!DOCTYPE html> <html> <head> <meta cha ...

  2. table增删改查操作--jq

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. centos 安装部署zabbix

    Zabbix_server初始安装部署 各模块要安装的模块 Server:server+nginx+mysql+php Agentd:agentd Proxy:proxy+mysql 1.准备环境: ...

  4. Borg, Omega, and Kubernetes读后笔记

    前言 最近又读了一遍 Borg, Omega, and Kubernetes 这篇文章,觉得这个文章写得很好,让我对架构设计有了进一步的认识,所以想写一篇读后笔记. 原文地址,还有篇中文翻译的,这个中 ...

  5. now

  6. phantomjs的安装和使用链接

    1.先下载phantomjs并解压2.将phantomjs的bin目录配置到环境变量中3.测试phantomjs,cmd下输入phantomjs进入 (按 Ctrl + c 组 合键退出和 phant ...

  7. 【转载】ARCHIVE_LAG_TARGET参数的作用(定时切换redo)

    (一)  设置archive_lag_target参数1.      一旦设置了archive_lag_target初始化参数,数据库将会周期性的检查实例的当前重做日志.如果遇到下列情况,实例将会切换 ...

  8. 使用jenkins自部署Coding项目

    下载安装jenkins 下载地址:https://jenkins.io/download/ 安装后通过主机的8080端口进行程序设置,插件安装默认的就好 Jenkins项目目录:C:\Program ...

  9. C/C++ 多线程机制

    一.C/C++多线程操作说明 C/C++多线程基本操作如下: 1. 线程的建立结束 2. 线程的互斥和同步 3. 使用信号量控制线程 4. 线程的基本属性配置 在C/C++代码编写时,使用多线程机制, ...

  10. Docker学习笔记-CentOS7镜像

    前言: 环境:centos7.5 64 位 正文: 第一步:下载centos7镜像 docker pull centos 第二步:建立centos7的容器 sudo docker run --priv ...