最经典的处理方式:

在启动goroutine的时候,传递一个额外的chan型参数,用来接收退出信号,代码如下

func worker(name string, stopchan chan struct{}) {
for {
select {
case <-stopchan:
fmt.Println("receive a stop signal, ", name)
return
default:
fmt.Println("I am worker ", name)
time.Sleep( * time.Second)
}
} }

在main函数中应该如何发送stop信号呢?

func main() {
stopCh := make(chan struct{})
go worker("a", stopCh) time.Sleep( * time.Second)
stopCh <- struct{}{}
time.Sleep( * time.Second)
}

输出:

I am worker  a
I am worker a
receive a stop signal, a Process finished with exit code

ok,从输出可以看出name为a的这个woker在收到信号之后退出了,过了2s后主函数退出

当我们又2个goroutine的时候情况如何呢?

func main() {
stopCh := make(chan struct{})
go worker("a", stopCh)
go worker("b", stopCh) time.Sleep( * time.Second)
stopCh <- struct{}{}
time.Sleep( * time.Second)
}

输出:

I am worker  a
I am worker b
I am worker b
I am worker a
receive a stop signal, a
I am worker b
I am worker b
I am worker b

也就是说a退出了,b没有退出,因为stopCh <- struct{}{}只发送一个信号,被a接收了,b不受影响

如果想让2个goroutine同时退出,需要这样写:

close(stopCh)

再看下输出:

I am worker  a
I am worker b
I am worker a
receive a stop signal, b
receive a stop signal, a Process finished with exit code

已经全部退出了

												

golang如何使用channel控制goroutine退出的更多相关文章

  1. Golang控制goroutine的启动与关闭

    最近在用golang做项目的时候,使用到了goroutine.在golang中启动协程非常方便,只需要加一个go关键字: go myfunc(){ //do something }() 但是对于一些长 ...

  2. golang(8):channel读写 & goroutine 通信

    goroutine 1.进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独 ...

  3. golang 部分理解:关于channel 和 goroutine 例子

    部分理解:关于channel 和 goroutine 例子package main import "strconv" import "fmt" func mai ...

  4. go中控制goroutine数量

    控制goroutine数量 前言 控制goroutine的数量 通过channel+sync 使用semaphore 线程池 几个开源的线程池的设计 fasthttp中的协程池实现 Start Sto ...

  5. 如何优雅地等待所有的goroutine退出

    转自:https://www.cnblogs.com/cobbliu/p/4461866.html goroutine和channel是Go语言非常棒的特色,它们提供了一种非常轻便易用的并发能力.但是 ...

  6. 如何优雅的控制goroutine的数量

    1,为什么要控制goroutine的数量? goroutine固然好,但是数量太多了,往往会带来很多麻烦,比如耗尽系统资源导致程序崩溃,或者CPU使用率过高导致系统忙不过来.比如: ; i < ...

  7. golang的缓冲channel简单使用

    目录 golang的缓冲channel简单使用 阻塞型 非阻塞 golang的缓冲channel简单使用 我们常用的是无缓冲channel : make(chan type) 其实make() 创建c ...

  8. 理解golang中的channel

    channel是goroutine之间的通信机制.可以类比线程间的通信,线程间的通信有多种方式,比如线程上下文.共享内存.IPC通信.socket实现不同机器间的通信. channel用起来很简单,绑 ...

  9. golang 无缓冲channel

    golang 无缓冲channel package main import "fmt" func main() { // 1S =1000ms //1ms = 1000us //1 ...

随机推荐

  1. PAT-L3-球队“食物链”-dfs-状压-set

    题目分析: 1. 一场双循环赛制的篮球赛,注意双循环,双循环! 2. 共有n只球队,两两之间有胜有负有平局: 3. 输入: 举例: 第一行:W:代表球队1打赢过这只队伍 L:代表球队2没打赢过这只队伍 ...

  2. java中equals相同,hashcode一定相同ma

    一.jdk中equals和hashcode的定义和源码进行分析 1.java.lang.Object中对equals()方法的定义 java.lang.Object中对hashCode()方法的定义 ...

  3. JVM活学活用——优化springboot

    介绍 在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方便微服务部署. 2. 方便项目启动,不需要下载Tomcat或者 ...

  4. Java基础学习笔记二十 IO流

    转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者OutputStre ...

  5. 【Spring系列】Spring mvc整合redis(非集群)

    一.在pom.xml中增加redis需要的jar包 <!--spring redis相关jar包--> <dependency> <groupId>redis.cl ...

  6. Leetcode 12——Integer to Roman

    12.Integer to Roman Given an integer, convert it to a roman numeral. Input is guaranteed to be withi ...

  7. C语言二维数组作业

    一.PTA实验作业 题目1:7-3 出生年 1. 本题PTA提交列表 2. 设计思路 1.声明一个函数different()用来计算一个年份的不同数字个数 2.定义y(y是来计算符合要求的年份的量), ...

  8. Software Engineering-HW2

    title: Software Engineering-HW2 date: 2017-09-21 10:35:47 tags: HW --- 题目描述 从<构建之法>第一章的 " ...

  9. 详谈C++虚函数表那回事(多重继承关系)

    上一篇说了一般继承,也就是单继承的虚函数表,接下来说说多重继承的虚函数表: 1.无虚函数覆盖的多重继承: 代码: #pragma once //无覆盖,多重继承 class Base1 { publi ...

  10. windows系统下安装 node.js (node.js安装及环境配置)

    node.js简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. Node. ...